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.rs122
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(),
);