diff options
| author | luwenpeng <[email protected]> | 2023-08-17 15:16:12 +0800 |
|---|---|---|
| committer | luwenpeng <[email protected]> | 2023-08-17 18:50:24 +0800 |
| commit | 185629f06799443a0364506d2be9057744796ab8 (patch) | |
| tree | 5a9c255037107015946eaece5f06e01389d60318 | |
| parent | 53e184805feabca2724841dcf45f356d427ea6e6 (diff) | |
[feature] Add event manager base trait object
| -rw-r--r-- | src/event/event.rs | 132 | ||||
| -rw-r--r-- | src/event/mod.rs | 1 | ||||
| -rw-r--r-- | src/lib.rs | 1 |
3 files changed, 134 insertions, 0 deletions
diff --git a/src/event/event.rs b/src/event/event.rs new file mode 100644 index 0000000..de360ac --- /dev/null +++ b/src/event/event.rs @@ -0,0 +1,132 @@ +use crate::packet::packet::Packet; +use std::cell::RefCell; +use std::collections::HashMap; +use std::collections::VecDeque; + +trait EventCallback { + fn handle(&mut self, index: usize, packet: &Packet); +} + +struct EventManager { + event_map: HashMap<String, usize>, // event name -> event index + ready_event: VecDeque<usize>, // ready event index + cared_event: HashMap<usize, RefCell<Vec<Box<dyn EventCallback>>>>, // event index -> event callback +} + +impl EventManager { + pub fn new() -> EventManager { + EventManager { + event_map: HashMap::new(), + ready_event: VecDeque::new(), + cared_event: HashMap::new(), + } + } + + pub fn index(&mut self, event: &String) -> usize { + if let Some(index) = self.event_map.get(event) { + *index + } else { + let index = self.event_map.len(); + self.event_map.insert(event.to_string(), index); + index + } + } + + pub fn registe(&mut self, index: usize, handle: Box<dyn EventCallback>) { + if let Some(vec) = self.cared_event.get(&index) { + let mut vec = vec.borrow_mut(); + vec.push(handle); + } else { + let mut vec = vec![]; + vec.push(handle); + self.cared_event.insert(index, RefCell::new(vec)); + } + } + + pub fn trigger(&mut self, index: usize) { + self.ready_event.push_back(index); + } + + pub fn dispatch(&mut self, packet: &Packet) { + loop { + if let Some(index) = self.ready_event.pop_front() { + println!("Dispatch event {:?}", index); + if let Some(vec) = self.cared_event.get(&index) { + let mut vec = vec.borrow_mut(); + for callback in vec.iter_mut() { + callback.handle(index, packet); + } + } + } else { + break; + } + } + } +} + +/****************************************************************************** + * TEST + ******************************************************************************/ + +#[cfg(test)] +mod tests { + use super::EventCallback; + use super::EventManager; + use crate::packet::packet::Packet; + use std::cell::RefCell; + use std::rc::Rc; + + #[derive(Debug, Clone)] + struct Pulgin { + plugin_id: u32, + plugin_ctx: Rc<RefCell<String>>, + } + impl Pulgin { + pub fn new(plugin_id: u32, plugin_ctx: Rc<RefCell<String>>) -> Pulgin { + Pulgin { + plugin_id, + plugin_ctx, + } + } + } + impl EventCallback for Pulgin { + fn handle(&mut self, index: usize, packet: &Packet) { + self.plugin_ctx.borrow_mut().push_str(" World"); + println!("Pulgin handle event {:?}, {:?}, {:?}", index, self, packet); + } + } + + #[test] + fn test_event_manager() { + // create plugin + let mut plugin_cb = Pulgin::new(1, Rc::new(RefCell::new(String::from("Hello")))); + + // create event manager + let mut mgr: EventManager = EventManager::new(); + + // get event index + let tcp_opening_event = mgr.index(&String::from("TCP_OPENING")); + let tcp_active_event = mgr.index(&String::from("TCP_ACTIVE")); + let tcp_closing_event = mgr.index(&String::from("TCP_CLOSING")); + let tcp_closed_event = mgr.index(&String::from("TCP_CLOSED")); + + // registe event + mgr.registe(tcp_opening_event, Box::new(plugin_cb.clone())); + mgr.registe(tcp_active_event, Box::new(plugin_cb.clone())); + mgr.registe(tcp_closing_event, Box::new(plugin_cb.clone())); + mgr.registe(tcp_closed_event, Box::new(plugin_cb.clone())); + + // trigger event + mgr.trigger(tcp_opening_event); + mgr.trigger(tcp_active_event); + mgr.trigger(tcp_closing_event); + mgr.trigger(tcp_closed_event); + + // dispatch event + let bytes = [0x48, 0x73]; + let mut packet = Packet::new(&bytes, bytes.len() as u32); + mgr.dispatch(&packet); + + assert_eq!(1, 0); + } +} diff --git a/src/event/mod.rs b/src/event/mod.rs new file mode 100644 index 0000000..53f1126 --- /dev/null +++ b/src/event/mod.rs @@ -0,0 +1 @@ +pub mod event; @@ -1,2 +1,3 @@ pub mod packet; pub mod protocol; +pub mod event;
\ No newline at end of file |
