engine/ecs/src/events.rs

95 lines
2.5 KiB
Rust
Raw Normal View History

2024-08-23 11:22:09 +00:00
use std::{
any::{Any, TypeId},
collections::HashMap,
mem,
ops::DerefMut,
};
2025-02-26 07:39:19 +00:00
pub struct Events<C> {
2024-08-23 11:22:09 +00:00
events: HashMap<
TypeId,
(
Vec<Box<dyn Any + Send + Sync>>,
2025-02-26 07:39:19 +00:00
Vec<Box<dyn Fn(&mut C, &dyn Any) -> anyhow::Result<()> + Send + Sync>>,
2024-08-23 11:22:09 +00:00
),
>,
}
2025-02-26 07:39:19 +00:00
impl<C> Default for Events<C> {
fn default() -> Self {
Self {
events: HashMap::new(),
}
}
}
impl<C> Events<C> {
2024-08-23 11:22:09 +00:00
pub(crate) fn clone_from_register(&self) -> Self {
Self {
events: self
.events
.keys()
.map(|type_id| (*type_id, (Vec::new(), Vec::new())))
.collect(),
}
}
pub(crate) fn move_events(&mut self, other: &mut Self) {
for (type_id, (payloads, _)) in other.events.iter_mut() {
if !payloads.is_empty() {
let mut tmp = Vec::new();
mem::swap(payloads, &mut tmp);
self.events.get_mut(type_id).unwrap().0.extend(tmp);
}
}
}
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 07:39:19 +00:00
F: Fn(&mut C, &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 07:39:19 +00:00
Some((_, listener)) => listener.push(Box::new(move |c, payload| {
2024-08-23 11:22:09 +00:00
let typed_payload: &T = payload.downcast_ref().unwrap();
2025-02-26 07:39:19 +00:00
f(c, 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 07:39:19 +00:00
pub(crate) fn fire_events(&mut self, c: &mut C) -> 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 07:39:19 +00:00
(listener)(c, payload.deref_mut())?;
2024-08-23 11:22:09 +00:00
}
}
payloads.clear();
}
Ok(())
}
}