use std::any::Any;
use super::handler::EventHandler;
use crate::ecs::world::UnsafeWorldCell;
use super::queue::{EventQueue, ErasedEventQueue};
pub struct EventChannel<E> {
handlers: Vec<Box<dyn EventHandler<E>>>,
}
impl<E> EventChannel<E> {
pub fn new() -> Self {
let handlers = vec![];
Self { handlers }
}
pub fn new_box() -> Box<Self> {
let this = Self::new();
Box::new(this)
}
pub fn register<H>(&mut self, handler: H)
where
H: EventHandler<E> + 'static,
{
let handler = Box::new(handler);
self.handlers.push(handler);
}
pub fn trigger(&self, event: &E, cell: &UnsafeWorldCell) {
self.handlers
.iter()
.for_each(|h| h.trigger(event, cell))
}
}
pub trait ErasedEventChannel {
fn as_any_mut(&mut self) -> &mut dyn Any;
fn trigger_all(&self, queue: &mut dyn ErasedEventQueue, cell: &UnsafeWorldCell);
}
impl<E> ErasedEventChannel for EventChannel<E>
where
E: 'static,
{
fn as_any_mut(&mut self) -> &mut dyn Any {
self
}
fn trigger_all(&self, queue: &mut dyn ErasedEventQueue, cell: &UnsafeWorldCell) {
queue
.as_any_mut()
.downcast_mut::<EventQueue<E>>()
.map(|queue| queue.drain())
.map(|events| {
events.for_each(|e| self.trigger(&e, cell));
});
}
}