Skip to main content

karbon_framework/event/
mod.rs

1use std::any::{Any, TypeId};
2use std::collections::HashMap;
3use std::future::Future;
4use std::pin::Pin;
5use std::sync::Arc;
6use tokio::sync::RwLock;
7
8/// Trait for events. Implement this on your event structs.
9///
10/// ```ignore
11/// struct UserCreated { pub user_id: i64, pub email: String }
12/// impl Event for UserCreated {}
13/// ```
14pub trait Event: Send + Sync + 'static {}
15
16type BoxHandler = Arc<dyn Fn(&dyn Any) -> Pin<Box<dyn Future<Output = ()> + Send>> + Send + Sync>;
17
18/// Simple async event bus (pub/sub).
19///
20/// ```ignore
21/// let bus = EventBus::new();
22///
23/// bus.on::<UserCreated>(|event| async move {
24///     println!("User created: {}", event.email);
25/// }).await;
26///
27/// bus.emit(UserCreated { user_id: 1, email: "foo@bar.com".into() }).await;
28/// ```
29#[derive(Clone)]
30pub struct EventBus {
31    handlers: Arc<RwLock<HashMap<TypeId, Vec<BoxHandler>>>>,
32}
33
34impl EventBus {
35    pub fn new() -> Self {
36        Self {
37            handlers: Arc::new(RwLock::new(HashMap::new())),
38        }
39    }
40
41    /// Register a handler for an event type
42    pub async fn on<E, F, Fut>(&self, handler: F)
43    where
44        E: Event,
45        F: Fn(Arc<E>) -> Fut + Send + Sync + 'static,
46        Fut: Future<Output = ()> + Send + 'static,
47    {
48        let handler = Arc::new(handler);
49        let handler: BoxHandler = Arc::new(move |event: &dyn Any| -> Pin<Box<dyn Future<Output = ()> + Send>> {
50            if let Some(e) = event.downcast_ref::<Arc<E>>() {
51                let e = e.clone();
52                let h = handler.clone();
53                Box::pin(async move { h(e).await })
54            } else {
55                Box::pin(async {})
56            }
57        });
58
59        let mut handlers = self.handlers.write().await;
60        handlers.entry(TypeId::of::<E>()).or_default().push(handler);
61    }
62
63    /// Emit an event, calling all registered handlers concurrently
64    pub async fn emit<E: Event>(&self, event: E) {
65        let event = Arc::new(event);
66        let handlers = self.handlers.read().await;
67        if let Some(list) = handlers.get(&TypeId::of::<E>()) {
68            let futures: Vec<_> = list
69                .iter()
70                .map(|h| h(&event as &dyn Any))
71                .collect();
72            futures::future::join_all(futures).await;
73        }
74    }
75}
76
77impl Default for EventBus {
78    fn default() -> Self {
79        Self::new()
80    }
81}