use std::{ any::{Any, TypeId}, collections::HashMap, sync::{Arc, Mutex}, }; use crate::{event, state::StateManager}; event!(Close); pub trait Event { fn as_any(&self) -> &dyn Any; } pub struct EventManager { handlers: Mutex, &dyn Event)>>>>>, states: Mutex>>, } impl EventManager { pub fn new() -> Arc { Arc::new(EventManager { handlers: Mutex::new(HashMap::new()), states: Mutex::new(None), }) } pub fn on, &E) + 'static>( self: &Arc, mut f: F, ) { let states = self.states.lock().unwrap().clone(); self.handlers .lock() .unwrap() .entry(TypeId::of::()) .or_insert_with(Vec::new) .push(Arc::new(Mutex::new( move |e: &Arc, evt: &dyn Event| { if let Some(concrete) = evt.as_any().downcast_ref::() { f(&e, concrete); if let Some(states) = &states { states.clone().flush(); } } }, ))); } pub fn dispatch(self: &Arc, evt: E) { let handlers = { self.handlers.lock().unwrap().get(&evt.type_id()).cloned() }; if let Some(handlers) = handlers { for h in handlers { let mut ha = h.lock().unwrap(); (ha)(self, &evt); } } } pub fn close(self: &Arc) { self.dispatch(Close); std::process::exit(0); } pub fn set_state_manager(self: &Arc, states: Arc) { *self.states.lock().unwrap() = Some(states); } }