konnektoren_core/events/
event_bus.rs

1use super::{
2    EventType,
3    event::{Event, EventTrait},
4};
5use std::collections::HashMap;
6use std::sync::{Arc, Mutex};
7
8type EventHandler = Arc<dyn Fn(Event) + Send + Sync>;
9
10#[derive(Default, Clone)]
11pub struct EventBus {
12    pub listeners: Arc<Mutex<HashMap<EventType, Vec<EventHandler>>>>,
13}
14
15impl EventBus {
16    pub fn new() -> Self {
17        Self::default()
18    }
19
20    pub fn subscribe<F>(&self, event_type: EventType, callback: F)
21    where
22        F: Fn(Event) + Send + Sync + 'static,
23    {
24        let mut listeners = self.listeners.lock().unwrap();
25        listeners
26            .entry(event_type)
27            .or_default()
28            .push(Arc::new(callback));
29    }
30
31    pub fn publish(&self, event: Event) {
32        let listeners = self.listeners.lock().unwrap();
33        if let Some(handlers) = listeners.get(&event.get_type()) {
34            for handler in handlers {
35                handler(event.clone());
36            }
37        }
38    }
39}
40
41#[cfg(test)]
42mod tests {
43    use super::super::{GameEvent, event::Event};
44    use super::*;
45    use std::sync::Arc;
46    use std::sync::atomic::{AtomicUsize, Ordering};
47
48    #[test]
49    fn test_event_bus() {
50        let event_bus = EventBus::new();
51        let counter = Arc::new(AtomicUsize::new(0));
52        let counter_clone = counter.clone();
53        event_bus.subscribe(EventType::Game, move |event| {
54            if let Event::Game(GameEvent::Started) = event {
55                counter_clone.fetch_add(1, Ordering::SeqCst);
56            }
57        });
58
59        event_bus.publish(Event::Game(GameEvent::Started));
60        assert_eq!(counter.load(Ordering::SeqCst), 1);
61    }
62}