engine/ecs/src/events.rs

89 lines
2.4 KiB
Rust
Raw Normal View History

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(())
}
}