63 lines
2.0 KiB
Rust
63 lines
2.0 KiB
Rust
|
use std::{collections::{HashMap, VecDeque}, any::{TypeId, Any}, cell::{RefCell, Ref, RefMut}};
|
||
|
|
||
|
use super::{CastableAny, Events, Event};
|
||
|
|
||
|
pub struct EventQueue {
|
||
|
events: HashMap<TypeId, RefCell<Box<dyn CastableAny>>>,
|
||
|
event_write_queue: HashMap<TypeId, RefCell<Box<dyn CastableAny>>>
|
||
|
}
|
||
|
|
||
|
impl EventQueue {
|
||
|
pub fn new() -> Self {
|
||
|
Self {
|
||
|
event_write_queue: HashMap::new(),
|
||
|
events: HashMap::new(),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// Trigger an event
|
||
|
pub fn trigger_event<E>(&mut self, event: E)
|
||
|
where
|
||
|
E: Event
|
||
|
{
|
||
|
// the compiler wants me to explicit right here for some reason
|
||
|
let default = || RefCell::new(Box::new(Events::<E>::new()) as Box<dyn CastableAny>);
|
||
|
|
||
|
// 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<E> = 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<TypeId> = self.event_write_queue.keys().map(|k| k.clone()).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<E>(&self) -> Option<Events<E>>
|
||
|
where
|
||
|
E: Event
|
||
|
{
|
||
|
if let Some(event ) = self.events.get(&TypeId::of::<E>()) {
|
||
|
let eref = event.borrow();
|
||
|
Some(eref.as_ref().as_any().downcast_ref::<Events<E>>().unwrap().clone())
|
||
|
} else {
|
||
|
None
|
||
|
}
|
||
|
}
|
||
|
}
|