2024-08-23 11:22:09 +00:00
|
|
|
use std::{
|
|
|
|
any::{Any, TypeId},
|
|
|
|
collections::HashMap,
|
|
|
|
ops::DerefMut,
|
2025-02-26 11:22:32 +00:00
|
|
|
sync::Arc,
|
2024-08-23 11:22:09 +00:00
|
|
|
};
|
|
|
|
|
2025-02-26 11:22:32 +00:00
|
|
|
use crate::World;
|
|
|
|
|
|
|
|
pub struct Events {
|
2024-08-23 11:22:09 +00:00
|
|
|
events: HashMap<
|
2025-02-26 11:22:32 +00:00
|
|
|
TypeId, // TypeId of Payload
|
2024-08-23 11:22:09 +00:00
|
|
|
(
|
2025-02-26 11:22:32 +00:00
|
|
|
Vec<Box<dyn Any + Send + Sync>>, // Payload
|
|
|
|
Vec<Arc<dyn Fn(&mut World, &dyn Any) -> anyhow::Result<()> + Send + Sync>>, // Listener on Payload
|
2024-08-23 11:22:09 +00:00
|
|
|
),
|
|
|
|
>,
|
|
|
|
}
|
|
|
|
|
2025-02-26 11:22:32 +00:00
|
|
|
impl Default for Events {
|
2025-02-26 07:39:19 +00:00
|
|
|
fn default() -> Self {
|
|
|
|
Self {
|
|
|
|
events: HashMap::new(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-02-26 11:22:32 +00:00
|
|
|
impl Events {
|
|
|
|
pub(crate) fn take_events(&mut self) -> Self {
|
2024-08-23 11:22:09 +00:00
|
|
|
Self {
|
|
|
|
events: self
|
|
|
|
.events
|
2025-02-26 11:22:32 +00:00
|
|
|
.iter_mut()
|
|
|
|
.filter_map(|(type_id, (payload, listener))| {
|
|
|
|
(!payload.is_empty())
|
|
|
|
.then(|| (*type_id, (std::mem::take(payload), listener.clone())))
|
|
|
|
})
|
2024-08-23 11:22:09 +00:00
|
|
|
.collect(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn clear(&mut self) {
|
|
|
|
for (payloads, listener) in self.events.values_mut() {
|
|
|
|
payloads.clear();
|
|
|
|
listener.clear();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn register_event<T: Any + Send + Sync>(&mut self) {
|
|
|
|
self.events
|
|
|
|
.insert(TypeId::of::<T>(), (Vec::new(), Vec::new()));
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn add_reader<T: Any + Send + Sync, F>(&mut self, f: F)
|
|
|
|
where
|
2025-02-26 11:22:32 +00:00
|
|
|
F: Fn(&mut World, &T) -> anyhow::Result<()> + Send + Sync + 'static,
|
2024-08-23 11:22:09 +00:00
|
|
|
{
|
|
|
|
match self.events.get_mut(&TypeId::of::<T>()) {
|
2025-02-26 11:22:32 +00:00
|
|
|
Some((_, listener)) => listener.push(Arc::new(move |world, payload| {
|
2024-08-23 11:22:09 +00:00
|
|
|
let typed_payload: &T = payload.downcast_ref().unwrap();
|
|
|
|
|
2025-02-26 11:22:32 +00:00
|
|
|
f(world, typed_payload)
|
2024-08-23 11:22:09 +00:00
|
|
|
})),
|
|
|
|
None => panic!("register event type first!"),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn write_event<T: Any + Send + Sync>(&mut self, payload: T) {
|
|
|
|
match self.events.get_mut(&TypeId::of::<T>()) {
|
|
|
|
Some((payloads, _)) => payloads.push(Box::new(payload)),
|
|
|
|
None => panic!("register event type first!"),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-02-26 11:22:32 +00:00
|
|
|
pub(crate) fn fire_events(&mut self, world: &mut World) -> anyhow::Result<()> {
|
2024-08-23 11:22:09 +00:00
|
|
|
for (payloads, listeners) in self.events.values_mut() {
|
|
|
|
for payload in payloads.iter_mut() {
|
|
|
|
for listener in listeners.iter_mut() {
|
2025-02-26 11:22:32 +00:00
|
|
|
(listener)(world, payload.deref_mut())?;
|
2024-08-23 11:22:09 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
payloads.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|