use std::{collections::{HashMap, VecDeque}, any::{TypeId, Any}, cell::RefCell}; use crate::{castable_any::CastableAny, plugin::Plugin}; pub trait Event: Clone + Send + Sync + 'static {} impl Event for T {} pub type Events = VecDeque; pub struct EventQueue { events: HashMap>>, event_write_queue: HashMap>> } impl Default for EventQueue { fn default() -> Self { Self::new() } } impl EventQueue { pub fn new() -> Self { Self { event_write_queue: HashMap::new(), events: HashMap::new(), } } /// Trigger an event pub fn trigger_event(&mut self, event: E) where E: Event { // the compiler wants me to explicit right here for some reason let default = || RefCell::new(Box::>::default() as Box); // Get, or create, a list of events of this type let type_id = event.type_id(); let mut events = self.event_write_queue.entry(type_id) .or_insert_with(default) .borrow_mut(); // downcast resource as an events storage let e: &mut Events = events.as_mut().as_any_mut().downcast_mut().unwrap(); e.push_back(event); } // Clear events, this should happen at the start of every tick since events are cloned // before being given to the reader. pub fn update_events(&mut self) { self.events.clear(); // get all keys of events let keys: Vec = self.event_write_queue.keys().copied().collect(); // remove all elements from self.event_write_queue and insert them to events for k in keys.into_iter() { let v = self.event_write_queue.remove(&k).unwrap(); self.events.insert(k, v); } } pub fn read_events(&self) -> Option> where E: Event { if let Some(event ) = self.events.get(&TypeId::of::()) { let eref = event.borrow(); Some(eref.as_ref().as_any().downcast_ref::>().unwrap().clone()) } else { None } } } #[derive(Default)] pub struct EventsPlugin; impl Plugin for EventsPlugin { fn setup(&self, game: &mut crate::game::Game) { game.world_mut().add_resource(EventQueue::new()); } }