diff options
Diffstat (limited to 'ecs/src/lib.rs')
-rw-r--r-- | ecs/src/lib.rs | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/ecs/src/lib.rs b/ecs/src/lib.rs index 01e0cde..334fe69 100644 --- a/ecs/src/lib.rs +++ b/ecs/src/lib.rs @@ -17,6 +17,7 @@ use crate::component::{ Sequence as ComponentSequence, }; use crate::entity::CREATE_STATIC_ENTITIES; +use crate::event::component::Kind as ComponentEventKind; use crate::extension::{Collector as ExtensionCollector, Extension}; use crate::lock::{Lock, WriteGuard}; use crate::phase::{Phase, START as START_PHASE}; @@ -331,6 +332,9 @@ impl World self.emit_event_by_id(comp_added_event_id); } } + Action::Despawn(entity_uid) => { + self.despawn_entity(entity_uid, &mut has_swapped_active_queue); + } Action::AddComponents( entity_uid, components, @@ -382,6 +386,52 @@ impl World } } + fn despawn_entity(&self, entity_uid: Uid, has_swapped_active_queue: &mut bool) + { + let mut component_storage_lock = self.lock_component_storage_rw(); + + let Some(archetype) = component_storage_lock.get_entity_archetype(entity_uid) + else { + #[cfg(feature = "debug")] + tracing::error!("No archetype for entity {entity_uid:?} was found"); + + return; + }; + + let entity = archetype + .get_entity(entity_uid) + .expect("Entity archetype was found but the entity is not in the archetype"); + + let component_removed_event_uids = entity + .components() + .iter() + .map(|component| { + component + .component + .read_nonblock() + .unwrap_or_else(|_| { + panic!( + "Failed to acquire read-only {} component lock", + component.name + ) + }) + .get_event_uid(ComponentEventKind::Removed) + }) + .collect::<Vec<_>>(); + + component_storage_lock.remove_entity(entity_uid); + + drop(component_storage_lock); + + if !*has_swapped_active_queue { + self.swap_event_queue(has_swapped_active_queue); + } + + for comp_removed_event_id in component_removed_event_uids { + self.emit_event_by_id(comp_removed_event_id); + } + } + fn emit_event_by_id(&self, event_id: Uid) { for (system,) in self |