summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorluwenpeng <[email protected]>2023-08-17 15:16:12 +0800
committerluwenpeng <[email protected]>2023-08-17 18:50:24 +0800
commit185629f06799443a0364506d2be9057744796ab8 (patch)
tree5a9c255037107015946eaece5f06e01389d60318
parent53e184805feabca2724841dcf45f356d427ea6e6 (diff)
[feature] Add event manager base trait object
-rw-r--r--src/event/event.rs132
-rw-r--r--src/event/mod.rs1
-rw-r--r--src/lib.rs1
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;
diff --git a/src/lib.rs b/src/lib.rs
index c9cf115..d44174d 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,2 +1,3 @@
pub mod packet;
pub mod protocol;
+pub mod event; \ No newline at end of file