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.rs68
1 files changed, 39 insertions, 29 deletions
diff --git a/ecs/src/lib.rs b/ecs/src/lib.rs
index 7a2178e..32ade13 100644
--- a/ecs/src/lib.rs
+++ b/ecs/src/lib.rs
@@ -2,6 +2,7 @@
use std::any::{Any, TypeId, type_name};
use std::fmt::Debug;
+use std::hint::cold_path;
use std::mem::ManuallyDrop;
use std::rc::Rc;
use std::sync::Arc;
@@ -23,8 +24,9 @@ use crate::event::component::Added;
use crate::event::{Emitted as EmittedEvent, NewEvents, Submitter as EventSubmitter};
use crate::extension::{Collector as ExtensionCollector, Extension};
use crate::lock::Lock;
-use crate::pair::{ChildOf, DependsOn, Pair};
+use crate::pair::{ChildOf, Pair, Wildcard};
use crate::phase::{
+ HasSystem as PhaseHasSystem,
POST_UPDATE as POST_UPDATE_PHASE,
PRE_UPDATE as PRE_UPDATE_PHASE,
Phase,
@@ -171,15 +173,18 @@ impl World
{
let (type_erased_system, mut system_callbacks) = system.finish();
- let system_ent_id = self.create_entity((
- SystemComponent { system: type_erased_system },
- Pair::builder()
- .relation::<DependsOn>()
- .target_id(phase_euid)
- .build(),
- ));
+ let system_ent_id =
+ self.create_entity((SystemComponent { system: type_erased_system },));
system_callbacks.on_created(self, SystemMetadata { ent_id: system_ent_id });
+
+ self.create_entity_with_uid(
+ phase_euid,
+ (Pair::builder()
+ .relation::<PhaseHasSystem>()
+ .target_id(system_ent_id)
+ .build(),),
+ );
}
/// Adds a extensions.
@@ -246,7 +251,11 @@ impl World
.compare_exchange(false, true, Ordering::Relaxed, Ordering::Relaxed)
.is_ok()
{
- self.query_and_run_systems(*START_PHASE);
+ let Some(start_phase_entity) = self.get_entity(*START_PHASE) else {
+ unreachable!();
+ };
+
+ self.run_phase_systems(&start_phase_entity);
}
self.perform_phases();
@@ -346,29 +355,26 @@ impl World
);
}
- fn query_and_run_systems(&self, phase_euid: Uid)
+ fn run_phase_systems(&self, phase_entity: &EntityHandle<'_>)
{
- let system_query = Query::<(&SystemComponent,)>::from_flexible_query(
- self.flexible_query(
- QueryTerms::<QUERY_MAX_TERM_CNT>::builder()
- .with_required([
- SystemComponent::id(),
- Pair::builder()
- .relation::<DependsOn>()
- .target_id(phase_euid)
- .build()
- .id(),
- ])
- .build(),
- ),
- );
+ // The phase's systems are retrieved this way so that the order they are
+ // run is the same order as they were registered, even if they have local
+ // components.
+ for system_entity in phase_entity
+ .get_wildcard_pair_matches::<PhaseHasSystem, Wildcard>()
+ .into_iter()
+ .filter_map(|phase_has_system| phase_has_system.get_target_ent())
+ {
+ let Some(system) = system_entity.get::<SystemComponent>() else {
+ cold_path();
+ continue;
+ };
- for (system_ent_id, (system_component,)) in system_query.iter_with_euids() {
// SAFETY: The world lives long enough
unsafe {
- system_component
+ system
.system
- .run(self, SystemMetadata { ent_id: system_ent_id });
+ .run(self, SystemMetadata { ent_id: system_entity.uid() });
}
}
}
@@ -389,14 +395,18 @@ impl World
);
for child_phase_entity in &phase_query {
- self.query_and_run_systems(child_phase_entity.uid());
+ self.run_phase_systems(&child_phase_entity);
self.perform_child_phases(child_phase_entity.uid());
}
}
fn perform_single_phase(&self, phase_entity_id: Uid)
{
- self.query_and_run_systems(phase_entity_id);
+ let Some(phase_entity) = self.get_entity(phase_entity_id) else {
+ unreachable!();
+ };
+
+ self.run_phase_systems(&phase_entity);
self.perform_child_phases(phase_entity_id);
}