diff options
Diffstat (limited to 'ecs/src/lib.rs')
-rw-r--r-- | ecs/src/lib.rs | 122 |
1 files changed, 69 insertions, 53 deletions
diff --git a/ecs/src/lib.rs b/ecs/src/lib.rs index 3b89dac..dd43e0b 100644 --- a/ecs/src/lib.rs +++ b/ecs/src/lib.rs @@ -18,6 +18,10 @@ use crate::component::{ Sequence as ComponentSequence, }; use crate::entity::CREATE_STATIC_ENTITIES; +use crate::event::component::{ + Added as ComponentAddedEvent, + Removed as ComponentRemovedEvent, +}; use crate::extension::{Collector as ExtensionCollector, Extension}; use crate::lock::{Lock, WriteGuard}; use crate::pair::{ChildOf, DependsOn, Pair}; @@ -111,6 +115,8 @@ impl World { debug_assert_eq!(entity_uid.kind(), UidKind::Entity); + let added_component_ids; + { let mut component_storage_lock = self.lock_component_storage_rw(); @@ -119,18 +125,16 @@ impl World return; }; - Self::add_entity_components( + added_component_ids = Self::add_entity_components( entity_uid, components.into_parts_array(), &mut component_storage_lock, ); } - // TODO: Emit component added events here - - // for added_event_id in Comps::added_event_ids() { - // self.emit_event_by_id(added_event_id); - // } + for comp_id in added_component_ids { + self.emit_event_by_id::<ComponentAddedEvent>(comp_id); + } } /// Adds a globally shared singleton value. @@ -156,14 +160,13 @@ impl World )); } - pub fn register_observer_system<'this, SystemImpl, Event>( + pub fn register_observer_system<'this, SystemImpl>( &'this mut self, system: impl System<'this, SystemImpl>, - event: Event, - ) where - Event: Component, + event: Pair<Uid, Uid>, + ) { - self.create_entity::<(SystemComponent, Event)>(( + self.create_entity(( SystemComponent { system: system.into_type_erased() }, event, )); @@ -377,6 +380,8 @@ impl World for action in active_action_queue.drain(..) { match action { Action::Spawn(components) => { + let added_component_ids; + { let mut component_storage_lock = self.lock_component_storage_rw(); @@ -389,7 +394,7 @@ impl World continue; }; - Self::add_entity_components( + added_component_ids = Self::add_entity_components( new_entity_uid, components, &mut component_storage_lock, @@ -400,20 +405,20 @@ impl World self.swap_event_queue(&mut has_swapped_active_queue); } - // TODO: Emit component added events here - - // for comp_added_event_id in component_added_event_ids.ids { - // self.emit_event_by_id(comp_added_event_id); - // } + for comp_id in added_component_ids { + self.emit_event_by_id::<ComponentAddedEvent>(comp_id); + } } Action::Despawn(entity_uid) => { self.despawn_entity(entity_uid, &mut has_swapped_active_queue); } Action::AddComponents(entity_uid, components) => { + let added_component_ids; + { let mut component_storage_lock = self.lock_component_storage_rw(); - Self::add_entity_components( + added_component_ids = Self::add_entity_components( entity_uid, components, &mut component_storage_lock, @@ -424,20 +429,17 @@ impl World self.swap_event_queue(&mut has_swapped_active_queue); } - // TODO: Emit component added events here - - // TODO: Fix that events are emitted for components that haven't been - // added because a error occurred (for example, the entity already has - // the component) - // for comp_added_event_id in component_added_event_ids.ids { - // self.emit_event_by_id(comp_added_event_id); - // } + for comp_id in added_component_ids { + self.emit_event_by_id::<ComponentAddedEvent>(comp_id); + } } Action::RemoveComponents(entity_uid, component_ids) => { + let removed_component_ids; + { let mut component_storage_lock = self.lock_component_storage_rw(); - Self::remove_entity_components( + removed_component_ids = Self::remove_entity_components( entity_uid, component_ids, &mut component_storage_lock, @@ -448,14 +450,9 @@ impl World self.swap_event_queue(&mut has_swapped_active_queue); } - // TODO: Emit component removed events here - - // TODO: Fix that events are emitted for components that haven't been - // removed because a error occurred (for example, the entity does not - // have the component) - // for comp_removed_event_id in component_removed_event_ids.ids { - // self.emit_event_by_id(comp_removed_event_id); - // } + for comp_id in removed_component_ids { + self.emit_event_by_id::<ComponentRemovedEvent>(comp_id); + } } Action::Stop => { self.stop.store(true, Ordering::Relaxed); @@ -469,7 +466,7 @@ impl World { let mut component_storage_lock = self.lock_component_storage_rw(); - let _removed_entity = match component_storage_lock.remove_entity(entity_uid) { + let removed_entity = match component_storage_lock.remove_entity(entity_uid) { Ok(components) => components, Err(err) => { tracing::error!("Failed to despawn entity: {err}"); @@ -483,54 +480,73 @@ impl World self.swap_event_queue(has_swapped_active_queue); } - // TODO: Emit component removed events here - - // for comp_removed_event_id in component_removed_event_uids { - // self.emit_event_by_id(comp_removed_event_id); - // } + for removed_ent_comp in removed_entity.components() { + self.emit_event_by_id::<ComponentRemovedEvent>(removed_ent_comp.id()); + } } fn add_entity_components( entity_uid: Uid, components: impl IntoIterator<Item = ComponentParts>, component_storage: &mut ComponentStorage, - ) + ) -> Vec<Uid> { - for component_parts in components { + let component_iter = components.into_iter(); + + let mut added_component_ids = + Vec::<Uid>::with_capacity(component_iter.size_hint().0); + + for component_parts in component_iter { + let comp_id = component_parts.id(); + if let Err(err) = component_storage.add_entity_component( entity_uid, - ( - component_parts.id(), - component_parts.name(), - component_parts.into_data(), - ), + (comp_id, component_parts.name(), component_parts.into_data()), ) { tracing::error!("Failed to add component to entity: {err}"); + continue; } + + added_component_ids.push(comp_id); } + + added_component_ids } fn remove_entity_components( entity_uid: Uid, component_ids: impl IntoIterator<Item = Uid>, component_storage: &mut ComponentStorage, - ) + ) -> Vec<Uid> { - for component_id in component_ids { + let component_id_iter = component_ids.into_iter(); + + let mut removed_component_ids = + Vec::<Uid>::with_capacity(component_id_iter.size_hint().0); + + for component_id in component_id_iter { if let Err(err) = component_storage.remove_entity_component(entity_uid, component_id) { tracing::error!("Failed to remove component to entity: {err}"); + continue; } + + removed_component_ids.push(component_id); } + + removed_component_ids } - #[allow(dead_code)] - fn emit_event_by_id(&self, event_id: Uid) + fn emit_event_by_id<Event: Component>(&self, target: Uid) { + if target.kind() == UidKind::Pair { + return; + } + let query = self.flexible_query( QueryTerms::<2>::builder() - .with_required([SystemComponent::id(), event_id]) + .with_required([SystemComponent::id(), Pair::new::<Event>(target).id()]) .build(), ); |