summaryrefslogtreecommitdiff
path: root/ecs/src/lib.rs
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2025-08-15 13:38:27 +0200
committerHampusM <hampus@hampusmat.com>2025-08-22 17:18:54 +0200
commite229b104593d3afede47cc07e9917a42d6d13e60 (patch)
tree25cd15befc8bf3e5864158aa791895c6d5bea751 /ecs/src/lib.rs
parentc8d3b211b8328452c9d15955004030430a99d1fc (diff)
refactor(ecs): store local components as system entity components
Diffstat (limited to 'ecs/src/lib.rs')
-rw-r--r--ecs/src/lib.rs94
1 files changed, 68 insertions, 26 deletions
diff --git a/ecs/src/lib.rs b/ecs/src/lib.rs
index fa31460..2b4302a 100644
--- a/ecs/src/lib.rs
+++ b/ecs/src/lib.rs
@@ -18,7 +18,7 @@ use crate::component::{
Parts as ComponentParts,
Sequence as ComponentSequence,
};
-use crate::entity::Declaration as EntityDeclaration;
+use crate::entity::{Declaration as EntityDeclaration, Handle as EntityHandle};
use crate::event::component::{
Added as ComponentAddedEvent,
Removed as ComponentRemovedEvent,
@@ -30,15 +30,15 @@ use crate::phase::{Phase, START as START_PHASE};
use crate::query::flexible::Query as FlexibleQuery;
use crate::query::term::Without;
use crate::query::{
- Iter as QueryIter,
TermWithFieldTuple as QueryTermWithFieldTuple,
TermWithoutFieldTuple as QueryTermWithoutFieldTuple,
Terms as QueryTerms,
TermsBuilderInterface,
+ MAX_TERM_CNT as QUERY_MAX_TERM_CNT,
};
use crate::sole::Sole;
use crate::stats::Stats;
-use crate::system::{System, SystemComponent};
+use crate::system::{Callbacks, Metadata as SystemMetadata, System, SystemComponent};
use crate::uid::{Kind as UidKind, Uid};
pub mod actions;
@@ -126,6 +126,19 @@ impl World
}
}
+ pub fn add_component(&mut self, entity_id: Uid, component_parts: ComponentParts)
+ {
+ let added_component_ids = Self::add_entity_components(
+ entity_id,
+ [component_parts],
+ &mut self.data.component_storage,
+ );
+
+ for comp_id in added_component_ids {
+ self.emit_event_by_id::<ComponentAddedEvent>(comp_id);
+ }
+ }
+
pub fn create_declared_entity(&mut self, entity_decl: &EntityDeclaration)
{
entity_decl.create(self);
@@ -148,10 +161,14 @@ impl World
system: impl System<'this, SystemImpl>,
)
{
- self.create_entity((
- SystemComponent { system: system.into_type_erased() },
+ let (type_erased_system, mut system_callbacks) = system.finish();
+
+ let system_ent_id = self.create_entity((
+ SystemComponent { system: type_erased_system },
Pair::new::<DependsOn>(phase_euid),
));
+
+ system_callbacks.on_created(self, SystemMetadata { ent_id: system_ent_id });
}
pub fn register_observer_system<'this, SystemImpl>(
@@ -160,10 +177,12 @@ impl World
event: Pair<Uid, Uid>,
)
{
- self.create_entity((
- SystemComponent { system: system.into_type_erased() },
- event,
- ));
+ let (type_erased_system, mut system_callbacks) = system.finish();
+
+ let system_ent_id =
+ self.create_entity((SystemComponent { system: type_erased_system }, event));
+
+ system_callbacks.on_created(self, SystemMetadata { ent_id: system_ent_id });
}
/// Adds a extensions.
@@ -190,6 +209,20 @@ impl World
FlexibleQuery::new(self, terms)
}
+ pub fn get_entity(&self, entity_id: Uid) -> Option<EntityHandle<'_>>
+ {
+ let archetype = self
+ .data
+ .component_storage
+ .get_entity_archetype(entity_id)?;
+
+ let entity = archetype
+ .get_entity_by_id(entity_id)
+ .expect("Should exist since archetype was found by entity id");
+
+ Some(EntityHandle::new(archetype, entity))
+ }
+
/// Performs a single tick.
/// # Panics
/// Will panic if mutable internal lock cannot be acquired.
@@ -289,21 +322,23 @@ impl World
fn query_and_run_systems(&self, phase_euid: Uid)
{
- let system_query = self.flexible_query(
- QueryTerms::<2>::builder()
- .with_required([
- SystemComponent::id(),
- Pair::new::<DependsOn>(phase_euid).id(),
- ])
- .build(),
+ let system_query = Query::<(&SystemComponent,)>::from_flexible_query(
+ self.flexible_query(
+ QueryTerms::<QUERY_MAX_TERM_CNT>::builder()
+ .with_required([
+ SystemComponent::id(),
+ Pair::new::<DependsOn>(phase_euid).id(),
+ ])
+ .build(),
+ ),
);
- for (system_component,) in
- QueryIter::<(&SystemComponent,), _>::new(self, system_query.iter())
- {
+ for (system_ent_id, (system_component,)) in system_query.iter_with_euids() {
// SAFETY: The world lives long enough
unsafe {
- system_component.system.run(self);
+ system_component
+ .system
+ .run(self, SystemMetadata { ent_id: system_ent_id });
}
}
}
@@ -499,15 +534,22 @@ impl World
return;
}
- let query = self.flexible_query(
- QueryTerms::<2>::builder()
- .with_required([SystemComponent::id(), Pair::new::<Event>(target).id()])
- .build(),
+ let query = Query::<(&SystemComponent,)>::from_flexible_query(
+ self.flexible_query(
+ QueryTerms::<QUERY_MAX_TERM_CNT>::builder()
+ .with_required([
+ SystemComponent::id(),
+ Pair::new::<Event>(target).id(),
+ ])
+ .build(),
+ ),
);
- for (system,) in QueryIter::<(&SystemComponent,), _>::new(self, query.iter()) {
+ for (system_ent_id, (system,)) in query.iter_with_euids() {
unsafe {
- system.system.run(self);
+ system
+ .system
+ .run(self, SystemMetadata { ent_id: system_ent_id });
}
}
}