use bevy_platform::collections::HashMap;
use crate::{
archetype::ArchetypeFlags, component::ComponentId, entity::EntityHashMap, event::EventKey,
observer::ObserverRunner,
};
#[derive(Default, Debug)]
pub struct Observers {
add: CachedObservers,
insert: CachedObservers,
replace: CachedObservers,
remove: CachedObservers,
despawn: CachedObservers,
cache: HashMap<EventKey, CachedObservers>,
}
impl Observers {
pub(crate) fn get_observers_mut(&mut self, event_key: EventKey) -> &mut CachedObservers {
use crate::lifecycle::*;
match event_key {
ADD => &mut self.add,
INSERT => &mut self.insert,
REPLACE => &mut self.replace,
REMOVE => &mut self.remove,
DESPAWN => &mut self.despawn,
_ => self.cache.entry(event_key).or_default(),
}
}
pub fn try_get_observers(&self, event_key: EventKey) -> Option<&CachedObservers> {
use crate::lifecycle::*;
match event_key {
ADD => Some(&self.add),
INSERT => Some(&self.insert),
REPLACE => Some(&self.replace),
REMOVE => Some(&self.remove),
DESPAWN => Some(&self.despawn),
_ => self.cache.get(&event_key),
}
}
pub(crate) fn is_archetype_cached(event_key: EventKey) -> Option<ArchetypeFlags> {
use crate::lifecycle::*;
match event_key {
ADD => Some(ArchetypeFlags::ON_ADD_OBSERVER),
INSERT => Some(ArchetypeFlags::ON_INSERT_OBSERVER),
REPLACE => Some(ArchetypeFlags::ON_REPLACE_OBSERVER),
REMOVE => Some(ArchetypeFlags::ON_REMOVE_OBSERVER),
DESPAWN => Some(ArchetypeFlags::ON_DESPAWN_OBSERVER),
_ => None,
}
}
pub(crate) fn update_archetype_flags(
&self,
component_id: ComponentId,
flags: &mut ArchetypeFlags,
) {
if self.add.component_observers.contains_key(&component_id) {
flags.insert(ArchetypeFlags::ON_ADD_OBSERVER);
}
if self.insert.component_observers.contains_key(&component_id) {
flags.insert(ArchetypeFlags::ON_INSERT_OBSERVER);
}
if self.replace.component_observers.contains_key(&component_id) {
flags.insert(ArchetypeFlags::ON_REPLACE_OBSERVER);
}
if self.remove.component_observers.contains_key(&component_id) {
flags.insert(ArchetypeFlags::ON_REMOVE_OBSERVER);
}
if self.despawn.component_observers.contains_key(&component_id) {
flags.insert(ArchetypeFlags::ON_DESPAWN_OBSERVER);
}
}
}
#[derive(Default, Debug)]
pub struct CachedObservers {
pub(super) global_observers: ObserverMap,
pub(super) component_observers: HashMap<ComponentId, CachedComponentObservers>,
pub(super) entity_observers: EntityHashMap<ObserverMap>,
}
impl CachedObservers {
pub fn global_observers(&self) -> &ObserverMap {
&self.global_observers
}
pub fn component_observers(&self) -> &HashMap<ComponentId, CachedComponentObservers> {
&self.component_observers
}
pub fn entity_observers(&self) -> &EntityHashMap<ObserverMap> {
&self.entity_observers
}
}
pub type ObserverMap = EntityHashMap<ObserverRunner>;
#[derive(Default, Debug)]
pub struct CachedComponentObservers {
pub(super) global_observers: ObserverMap,
pub(super) entity_component_observers: EntityHashMap<ObserverMap>,
}
impl CachedComponentObservers {
pub fn global_observers(&self) -> &ObserverMap {
&self.global_observers
}
pub fn entity_component_observers(&self) -> &EntityHashMap<ObserverMap> {
&self.entity_component_observers
}
}