2023-09-10 04:38:54 +00:00
|
|
|
use std::{collections::{HashMap, VecDeque}, any::{TypeId, Any}, cell::RefCell};
|
2023-09-01 01:34:58 +00:00
|
|
|
|
2023-09-17 16:08:08 +00:00
|
|
|
use crate::{castable_any::CastableAny, plugin::Plugin};
|
2023-09-08 04:13:46 +00:00
|
|
|
|
|
|
|
pub trait Event: Clone + Send + Sync + 'static {}
|
|
|
|
impl<T: Clone + Send + Sync + 'static> Event for T {}
|
|
|
|
|
|
|
|
pub type Events<T> = VecDeque<T>;
|
2023-09-01 01:34:58 +00:00
|
|
|
|
|
|
|
pub struct EventQueue {
|
|
|
|
events: HashMap<TypeId, RefCell<Box<dyn CastableAny>>>,
|
|
|
|
event_write_queue: HashMap<TypeId, RefCell<Box<dyn CastableAny>>>
|
|
|
|
}
|
|
|
|
|
2023-10-23 01:49:31 +00:00
|
|
|
impl Default for EventQueue {
|
|
|
|
fn default() -> Self {
|
|
|
|
Self::new()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-01 01:34:58 +00:00
|
|
|
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
|
2023-10-23 01:49:31 +00:00
|
|
|
let default = || RefCell::new(Box::<Events::<E>>::default() as Box<dyn CastableAny>);
|
2023-09-01 01:34:58 +00:00
|
|
|
|
|
|
|
// 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
|
2023-10-23 01:49:31 +00:00
|
|
|
let keys: Vec<TypeId> = self.event_write_queue.keys().copied().collect();
|
2023-09-01 01:34:58 +00:00
|
|
|
|
|
|
|
// 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
|
|
|
|
}
|
|
|
|
}
|
2023-09-17 16:08:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Default)]
|
|
|
|
pub struct EventsPlugin;
|
|
|
|
|
|
|
|
impl Plugin for EventsPlugin {
|
|
|
|
fn setup(&self, game: &mut crate::game::Game) {
|
2023-12-26 19:12:53 +00:00
|
|
|
game.world().add_resource(EventQueue::new());
|
2023-09-17 16:08:08 +00:00
|
|
|
}
|
2023-09-01 01:34:58 +00:00
|
|
|
}
|