diff --git a/Cargo.toml b/Cargo.toml index 016714a..5522d73 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,4 +10,5 @@ edition = "2018" rmp = "0.8.9" rmp-serde = "0.14.4" serde = {version = "1.0.117", features = ["serde_derive"]} -byteorder = "1.3.4" \ No newline at end of file +byteorder = "1.3.4" +parking_lot = "0.11.0" \ No newline at end of file diff --git a/src/event_handler/mod.rs b/src/event_handler/mod.rs new file mode 100644 index 0000000..f792efd --- /dev/null +++ b/src/event_handler/mod.rs @@ -0,0 +1,49 @@ +use crate::event::Event; +use serde::de::DeserializeOwned; +use serde::Serialize; +use std::collections::HashMap; + +#[cfg(test)] +mod tests; + +/// A handler for events +pub struct EventHandler { + event_handlers: HashMap)>>>, +} + +impl EventHandler +where + T: Serialize + DeserializeOwned, +{ + /// Creates a new vented event_handler + pub fn new() -> Self { + Self { + event_handlers: HashMap::new(), + } + } + + /// Adds a handler for the given event + pub fn on(&mut self, event_name: &str, handler: F) + where + F: Fn(&Event), + { + match self.event_handlers.get_mut(event_name) { + Some(handlers) => handlers.push(Box::new(handler)), + None => { + self.event_handlers + .insert(event_name.to_string(), vec![Box::new(handler)]); + } + } + } + + /// Handles a single event + pub fn handle_event(&mut self, event: Event) -> bool { + if let Some(handlers) = self.event_handlers.get(&event.name) { + handlers.iter().for_each(|handler| handler(&event)); + + true + } else { + false + } + } +} diff --git a/src/event_handler/tests.rs b/src/event_handler/tests.rs new file mode 100644 index 0000000..e0b4822 --- /dev/null +++ b/src/event_handler/tests.rs @@ -0,0 +1,28 @@ +use crate::event::Event; +use crate::event_handler::EventHandler; +use std::sync::atomic::{AtomicUsize, Ordering}; +use std::sync::Arc; + +#[test] +fn it_handles_events() { + let mut handler = EventHandler::new(); + let call_count = Arc::new(AtomicUsize::new(0)); + { + let call_count = Arc::clone(&call_count); + handler.on("test", move |_event| { + call_count.fetch_add(1, Ordering::Relaxed); + }); + } + { + let call_count = Arc::clone(&call_count); + handler.on("test2", move |_event| { + call_count.fetch_add(1, Ordering::Relaxed); + }) + } + + handler.handle_event(Event::new("test".to_string())); + handler.handle_event(Event::new("test".to_string())); + handler.handle_event(Event::new("test2".to_string())); + + assert_eq!(call_count.load(Ordering::Relaxed), 3) +} diff --git a/src/lib.rs b/src/lib.rs index aa81c77..ff3d44d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,2 +1,3 @@ pub mod event; -pub mod result; \ No newline at end of file +pub mod event_handler; +pub mod result;