use std::any::Any;
use std::cmp::Reverse;
use super::priority::PostOrder;
pub(crate) trait ErasedHandler: Send + Sync {
fn call(&self, event: &mut dyn Any);
}
pub(crate) struct TypedHandler<E: 'static> {
handler: Box<dyn Fn(&mut E) + Send + Sync>,
}
impl<E: 'static> TypedHandler<E> {
pub(crate) fn new(handler: impl Fn(&mut E) + Send + Sync + 'static) -> Self {
Self {
handler: Box::new(handler),
}
}
}
impl<E: 'static> ErasedHandler for TypedHandler<E> {
fn call(&self, event: &mut dyn Any) {
let event = event
.downcast_mut::<E>()
.expect("EventManager dispatched wrong event type to handler");
(self.handler)(event);
}
}
pub(crate) struct HandlerRegistration {
pub(crate) priority: PostOrder,
pub(crate) handler: Box<dyn ErasedHandler>,
}
pub(crate) fn sort_handlers(handlers: &mut [HandlerRegistration]) {
handlers.sort_by_key(|h| Reverse(h.priority));
}
pub(crate) trait ErasedObserver: Send + Sync {
fn call(&self, event: &dyn Any);
}
pub(crate) struct TypedObserver<E: 'static> {
observer: Box<dyn Fn(&E) + Send + Sync>,
}
impl<E: 'static> TypedObserver<E> {
pub(crate) fn new(observer: impl Fn(&E) + Send + Sync + 'static) -> Self {
Self {
observer: Box::new(observer),
}
}
}
impl<E: 'static> ErasedObserver for TypedObserver<E> {
fn call(&self, event: &dyn Any) {
let event = event
.downcast_ref::<E>()
.expect("EventManager dispatched wrong event type to observer");
(self.observer)(event);
}
}
pub(crate) struct ObserverRegistration {
pub(crate) observer: Box<dyn ErasedObserver>,
}
#[derive(Default)]
pub(crate) struct EventPipeline {
pub(crate) pre_observers: Vec<ObserverRegistration>,
pub(crate) handlers: Vec<HandlerRegistration>,
pub(crate) post_observers: Vec<ObserverRegistration>,
}