Crates.io | rs-event-emitter |
lib.rs | rs-event-emitter |
version | 3.0.3 |
source | src |
created_at | 2023-07-12 07:36:22.280957 |
updated_at | 2024-09-26 14:18:30.739389 |
description | simulate promise implementation for rust |
homepage | |
repository | https://github.com/Shcarp/rs-event-emitter.git |
max_upload_size | |
id | 914353 |
size | 51,831 |
A thread-safe, flexible event emitter implementation in Rust.
Add this to your Cargo.toml
:
[dependencies]
event_emitter = "3.0.0"
Here's a more comprehensive example demonstrating various features of the EventEmitter
and AsyncEventEmitter
:
EventEmitter
The main struct for managing events.
use event_emitter::{EventEmitter, emit};
use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Duration;
fn main() {
// Create a new EventEmitter
let emitter = EventEmitter::new();
// Start the event listener in a separate thread
let listener = emitter.start_listening();
// Create a shared state to demonstrate thread-safe updates
let shared_state = Arc::new(Mutex::new(Vec::new()));
// Handler for a simple greeting event
emitter.on("greet", |(name,): (String,)| {
println!("Hello, {}!", name);
});
// Handler for an event with multiple arguments
{
let state = Arc::clone(&shared_state);
emitter.on("user_action", move |(user, action, value): (String, String, i32)| {
println!("User {} performed action: {} with value: {}", user, action, value);
let mut data = state.lock().unwrap();
data.push((user, action, value));
});
}
// Handler for a more complex event
{
let state = Arc::clone(&shared_state);
emitter.on("process_data", move |(data, callback): (Vec<i32>, Box<dyn Fn(i32) + Send + 'static>)| {
let sum: i32 = data.iter().sum();
callback(sum);
let mut shared_data = state.lock().unwrap();
shared_data.push(("System".to_string(), "process_data".to_string(), sum));
});
}
// Emit events
emit!(emitter, "greet", "Alice".to_string());
emit!(emitter, "user_action", "Bob".to_string(), "click".to_string(), 5);
let callback = Box::new(|result: i32| {
println!("Processing result: {}", result);
});
emit!(emitter, "process_data", vec![1, 2, 3, 4, 5], callback);
// Demonstrate emitting events from another thread
let emitter_clone = emitter.clone();
thread::spawn(move || {
thread::sleep(Duration::from_millis(100));
emit!(emitter_clone, "greet", "Thread".to_string());
});
// Wait a bit for all events to be processed
thread::sleep(Duration::from_millis(200));
// Print the final state
let final_state = shared_state.lock().unwrap();
println!("Final state: {:?}", *final_state);
// Stop the event listener
emitter.stop_listening();
listener.join().unwrap();
}
This example demonstrates:
Creating and starting an EventEmitter
Registering handlers for different event types
Handling events with multiple arguments
Using shared state across event handlers
Emitting events with the emit!
macro
Passing callbacks as event arguments
Cloning and using the EventEmitter
in different threads
new()
: Create a new EventEmitter
.
with_thread_pool_size(thread_pool_size: usize)
: Create a new EventEmitter
with a specified capacity.
on<F, Args>(&self, event: &str, handler: F) -> HandlerId
: Register an event handler.
off(&self, event: &str, handler_id: HandlerId)
: Remove all handlers for an event.
emit(&self, event: &str, args: Vec<Param>)
: Emit an event.
start_listening(&self) -> JoinHandle<()>
: Start the event processing loop.
stop_listening(&self)
: Stop the event processing loop.
clone(&self) -> Self
: Create a clone of the EventEmitter
.
AsyncEventEmitter
rs-event-emitter = { version = "2.0.2", features = ["async"] }
// or use tokio runtime
rs-event-emitter = { version = "2.0.2", features = ["async", "tokio_runtime"] }
#[tokio::main]
async fn use_tokio_runtime() {
// use tokio runtime
let rt = Arc::new(TokioRuntime::new());
let emitter = AsyncEventEmitter::new(rt);
let counter = Arc::new(AtomicI32::new(0));
let counter_clone = counter.clone();
emitter
.on("test_event", move |_args: ()| {
let counter = counter_clone.clone();
Box::pin(async move {
counter.fetch_add(1, Ordering::SeqCst);
})
})
.await;
emitter.emit("test_event", vec![]).await;
// emitter.emit("test_event", vec![]).await;
async_emit!(emitter, "test_event").await;
assert_eq!(counter.load(Ordering::SeqCst), 2);
println!("done");
}
// or use custom runtime
use rs_event_emitter::runtime::*;
struct CustomRuntime;
impl Runtime for CustomRuntime {
...
}
fn use_custom_runtime() {
// use custom runtime
let rt = Arc::new(CustomRuntime::new());
let emitter = AsyncEventEmitter::new(rt);
}
This example demonstrates:
AsyncEventEmitter
async_emit!
macronew(rt: Arc<R>)
: Create a new AsyncEventEmitter
with the given async runtime.async on<F, Args>(&self, event: &str, handler: F) -> HandlerId
: Register an asynchronous event handler.async off(&self, event: &str, handler_id: HandlerId)
: Remove a specific handler for an event.async emit(&self, event: &str, args: Vec<Param>)
: Emit an event asynchronously.clone(&self) -> Self
: Create a clone of the AsyncEventEmitter
.Note: All methods on AsyncEventEmitter
are asynchronous and return Future
s that need to be awaited.
emit!
for convenient event emission with typed arguments.cargo test
.emit!
: A convenient macro for emitting events with typed arguments.async_emit!
: A convenient macro for emitting events with typed arguments.The library includes a comprehensive test suite. Run the tests using:
cargo test
This project is licensed under [LICENSE NAME]. See the LICENSE file for details.
Contributions are welcome! Please feel free to submit a Pull Request.