summaryrefslogtreecommitdiff
path: root/ecs/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'ecs/src/lib.rs')
-rw-r--r--ecs/src/lib.rs141
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([