summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2024-08-15 19:04:03 +0200
committerHampusM <hampus@hampusmat.com>2024-08-15 19:04:03 +0200
commit30f7ab671486c95287fb8d1c791aabef7007987c (patch)
treef66e6558ed1917968bc7d3efb36eb64473f5d8d0
parent48a415c63b7b98c5947e1517370eb8323b7b2a33 (diff)
feat(ecs): add component removed event
-rw-r--r--ecs/src/event/component.rs48
-rw-r--r--ecs/src/lib.rs25
2 files changed, 71 insertions, 2 deletions
diff --git a/ecs/src/event/component.rs b/ecs/src/event/component.rs
index 306d43f..4628cb1 100644
--- a/ecs/src/event/component.rs
+++ b/ecs/src/event/component.rs
@@ -54,11 +54,59 @@ where
}
}
+/// Event emitted when a `ComponentT` component is removed from a entity.
+pub struct Removed<ComponentT>
+where
+ ComponentT: Component,
+{
+ _pd: PhantomData<ComponentT>,
+}
+
+impl<ComponentT> Debug for Removed<ComponentT>
+where
+ ComponentT: Component,
+{
+ fn fmt(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result
+ {
+ formatter
+ .debug_struct("Removed")
+ .field("_pd", &self._pd)
+ .finish()
+ }
+}
+
+impl<ComponentT> Default for Removed<ComponentT>
+where
+ ComponentT: Component,
+{
+ fn default() -> Self
+ {
+ Self { _pd: PhantomData }
+ }
+}
+
+impl<ComponentT> Event for Removed<ComponentT>
+where
+ ComponentT: Component,
+{
+ fn id() -> Id
+ where
+ Self: Sized,
+ {
+ Id::new::<Removed<ComponentForId>, _>(Some(ComponentId::of::<ComponentT>()))
+ }
+}
+
pub fn create_added_id(component_id: ComponentId) -> Id
{
Id::new::<Added<ComponentForId>, _>(Some(component_id))
}
+pub fn create_removed_id(component_id: ComponentId) -> Id
+{
+ Id::new::<Removed<ComponentForId>, _>(Some(component_id))
+}
+
pub struct ComponentToAddedEvent;
impl<ComponentT: Component, Accumulator>
diff --git a/ecs/src/lib.rs b/ecs/src/lib.rs
index ed2ccef..39b6bf3 100644
--- a/ecs/src/lib.rs
+++ b/ecs/src/lib.rs
@@ -14,6 +14,7 @@ use crate::component::{Component, Id as ComponentId, Sequence as ComponentSequen
use crate::entity::Uid as EntityUid;
use crate::event::component::{
create_added_id as create_component_added_event_id,
+ create_removed_id as create_component_removed_event_id,
ComponentToAddedEvent,
};
use crate::event::start::Start as StartEvent;
@@ -238,7 +239,7 @@ impl World
));
}
}
- Action::RemoveComponents(entity_uid, component_ids) => {
+ Action::RemoveComponents(entity_uid, components_metadata) => {
let mut component_storage_lock =
self.data.component_storage.write_nonblock().expect(
"Failed to acquire read-write component storage lock",
@@ -246,10 +247,30 @@ impl World
component_storage_lock.remove_components_from_entity(
entity_uid,
- component_ids
+ components_metadata
.iter()
.map(|component_metadata| component_metadata.id),
);
+
+ drop(component_storage_lock);
+
+ if !has_swapped_active_queue {
+ let mut active_queue =
+ self.data.action_queue.active_queue.borrow_mut();
+
+ *active_queue = match *active_queue {
+ ActiveActionQueue::A => ActiveActionQueue::B,
+ ActiveActionQueue::B => ActiveActionQueue::A,
+ };
+
+ has_swapped_active_queue = true;
+ }
+
+ for component_metadata in components_metadata {
+ self.emit_event_by_id(create_component_removed_event_id(
+ component_metadata.id,
+ ));
+ }
}
Action::Stop => {
self.stop.store(true, Ordering::Relaxed);