use std::any::{Any, TypeId};
use std::collections::HashMap;
#[derive(Default)]
pub struct RuntimeEventBus {
map: HashMap<TypeId, Vec<Box<dyn Any + Send + 'static>>>,
}
impl RuntimeEventBus {
pub fn new() -> Self {
Self {
map: HashMap::new(),
}
}
pub fn emit<T: Send + 'static>(&mut self, event: T) {
self.map
.entry(TypeId::of::<T>())
.or_default()
.push(Box::new(event));
}
pub fn read<T: Send + 'static>(&self) -> impl Iterator<Item = &T> + '_ {
self.map
.get(&TypeId::of::<T>())
.into_iter()
.flat_map(|v| v.iter().filter_map(|b| b.downcast_ref::<T>()))
}
pub fn drain<T: Send + 'static>(&mut self) -> Vec<T> {
self.map
.remove(&TypeId::of::<T>())
.unwrap_or_default()
.into_iter()
.filter_map(|b| b.downcast::<T>().ok().map(|b| *b))
.collect()
}
pub fn has<T: Send + 'static>(&self) -> bool {
self.map
.get(&TypeId::of::<T>())
.map_or(false, |v| !v.is_empty())
}
pub fn count<T: Send + 'static>(&self) -> usize {
self.map.get(&TypeId::of::<T>()).map_or(0, |v| v.len())
}
pub fn is_empty(&self) -> bool {
self.map.values().all(|v| v.is_empty())
}
}