mod bus;
mod contract;
mod subscription;
use std::{future::Future, sync::Arc};
pub(crate) use bus::EventBus;
pub use contract::{AsyncEventHandler, Event, EventFuture, EventKey, InvalidEventKey};
pub use subscription::EventSubscription;
pub async fn emit<T>(key: EventKey<T>, payload: T) -> usize
where
T: Clone + Send + Sync + 'static,
{
crate::application::current_application("emit").emit_keyed(&key, payload)
}
pub fn listen<T>(key: EventKey<T>, listener: impl Fn(T) + Send + Sync + 'static)
where
T: Clone + Send + Sync + 'static,
{
listen_with(key, (), listener);
}
pub fn listen_with<T, D>(key: EventKey<T>, deps: D, listener: impl Fn(T) + Send + Sync + 'static)
where
T: Clone + Send + Sync + 'static,
D: Clone + PartialEq + 'static,
{
let application = crate::core::use_context::<crate::application::ApplicationContext>();
let effect_deps = (key.clone(), deps);
crate::core::stage_current_listener(effect_deps, move || {
let subscription = application.subscribe_keyed(key, listener);
move || drop(subscription)
});
}
pub fn listen_async<T, F, Fut>(key: EventKey<T>, listener: F)
where
T: Clone + Send + Sync + 'static,
F: Fn(T) -> Fut + Send + Sync + 'static,
Fut: Future<Output = ()> + Send + 'static,
{
listen_async_with(key, (), listener);
}
pub fn listen_async_with<T, D, F, Fut>(key: EventKey<T>, deps: D, listener: F)
where
T: Clone + Send + Sync + 'static,
D: Clone + PartialEq + 'static,
F: Fn(T) -> Fut + Send + Sync + 'static,
Fut: Future<Output = ()> + Send + 'static,
{
let application = crate::core::use_context::<crate::application::ApplicationContext>();
let effect_deps = (key.clone(), deps);
let listener = Arc::new(listener);
crate::core::stage_current_listener(effect_deps, move || {
let task_application = application.clone();
let subscription = application.subscribe_keyed(key, move |payload| {
let _ = task_application.spawn(listener(payload));
});
move || drop(subscription)
});
}
#[path = "events_test.rs"]
#[cfg(test)]
mod tests;