diff options
Diffstat (limited to 'ecs/src/lib.rs')
-rw-r--r-- | ecs/src/lib.rs | 141 |
1 files changed, 91 insertions, 50 deletions
diff --git a/ecs/src/lib.rs b/ecs/src/lib.rs index 72b5cf9..dc31daf 100644 --- a/ecs/src/lib.rs +++ b/ecs/src/lib.rs @@ -52,8 +52,6 @@ pub mod util; #[doc(hidden)] pub mod private; -mod archetype; - pub use ecs_macros::{Component, Sole}; pub use crate::query::Query; @@ -109,18 +107,20 @@ impl World { debug_assert_eq!(entity_uid.kind(), UidKind::Entity); - #[allow(unused_variables)] - if let Err(err) = self - .data - .component_storage - .write_nonblock() - .expect("Failed to acquire read-write component storage lock") - .push_entity(entity_uid, components.into_array().into()) { - tracing::error!("Failed to create entity: {err}"); + let mut component_storage_lock = self.lock_component_storage_rw(); - return; - }; + if let Err(err) = component_storage_lock.create_entity(entity_uid) { + tracing::warn!("Failed to create entity: {err}"); + return; + }; + + Self::add_entity_components( + entity_uid, + components.into_array(), + &mut component_storage_lock, + ); + } for added_event_id in Comps::added_event_ids() { self.emit_event_by_id(added_event_id); @@ -316,19 +316,25 @@ impl World for action in active_action_queue.drain(..) { match action { Action::Spawn(components, component_added_event_ids) => { - let mut component_storage_lock = self.lock_component_storage_rw(); - - #[allow(unused_variables)] - if let Err(err) = component_storage_lock - .push_entity(Uid::new_unique(UidKind::Entity), components) { - tracing::error!("Failed to create entity: {err}"); - - continue; + let mut component_storage_lock = self.lock_component_storage_rw(); + + let new_entity_uid = Uid::new_unique(UidKind::Entity); + + if let Err(err) = + component_storage_lock.create_entity(new_entity_uid) + { + tracing::warn!("Failed to create entity: {err}"); + continue; + }; + + Self::add_entity_components( + new_entity_uid, + components, + &mut component_storage_lock, + ); } - drop(component_storage_lock); - if !has_swapped_active_queue { self.swap_event_queue(&mut has_swapped_active_queue); } @@ -345,17 +351,23 @@ impl World components, component_added_event_ids, ) => { - let mut component_storage_lock = self.lock_component_storage_rw(); - - component_storage_lock - .add_components_to_entity(entity_uid, components); + { + let mut component_storage_lock = self.lock_component_storage_rw(); - drop(component_storage_lock); + Self::add_entity_components( + entity_uid, + components, + &mut component_storage_lock, + ); + } if !has_swapped_active_queue { self.swap_event_queue(&mut has_swapped_active_queue); } + // 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); } @@ -365,21 +377,25 @@ impl World components_metadata, component_removed_event_ids, ) => { - let mut component_storage_lock = self.lock_component_storage_rw(); - - component_storage_lock.remove_components_from_entity( - entity_uid, - components_metadata - .iter() - .map(|component_metadata| component_metadata.id), - ); - - drop(component_storage_lock); + { + let mut component_storage_lock = self.lock_component_storage_rw(); + + Self::remove_entity_components( + entity_uid, + components_metadata + .iter() + .map(|comp_metadata| comp_metadata.id), + &mut component_storage_lock, + ); + } if !has_swapped_active_queue { self.swap_event_queue(&mut has_swapped_active_queue); } + // 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); } @@ -391,23 +407,20 @@ impl World } } + #[tracing::instrument(skip_all)] 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 { - tracing::error!("No archetype for entity {entity_uid:?} was found"); - - return; + let components = match component_storage_lock.remove_entity(entity_uid) { + Ok(components) => components, + Err(err) => { + tracing::error!("Failed to despawn entity: {err}"); + 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() + let component_removed_event_uids = components .iter() .map(|component| { component @@ -423,8 +436,6 @@ impl World }) .collect::<Vec<_>>(); - component_storage_lock.remove_entity(entity_uid); - drop(component_storage_lock); if !*has_swapped_active_queue { @@ -436,6 +447,36 @@ impl World } } + fn add_entity_components( + entity_uid: Uid, + components: impl IntoIterator<Item = Box<dyn Component>>, + component_storage: &mut ComponentStorage, + ) + { + for component in components.into_iter() { + if let Err(err) = + component_storage.add_entity_component(entity_uid, component) + { + tracing::error!("Failed to add component to entity: {err}"); + } + } + } + + fn remove_entity_components( + entity_uid: Uid, + component_ids: impl IntoIterator<Item = Uid>, + component_storage: &mut ComponentStorage, + ) + { + for component_id in component_ids.into_iter() { + if let Err(err) = + component_storage.remove_entity_component(entity_uid, component_id) + { + tracing::error!("Failed to remove component to entity: {err}"); + } + } + } + fn emit_event_by_id(&self, event_id: Uid) { let query = self.flexible_query([ |