diff options
Diffstat (limited to 'ecs/src/lib.rs')
| -rw-r--r-- | ecs/src/lib.rs | 68 |
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); } |
