From 624e6dd450944e67d84ad7afda54ae2abd277aba Mon Sep 17 00:00:00 2001 From: HampusM Date: Thu, 23 Jul 2026 17:38:51 +0200 Subject: refactor(engine-ecs): remove distinction between query terms with & without a field --- engine-ecs/src/query/flexible.rs | 24 ++++---- engine-ecs/src/query/term.rs | 121 +++++++++++++++++++++++++-------------- 2 files changed, 90 insertions(+), 55 deletions(-) (limited to 'engine-ecs/src/query') diff --git a/engine-ecs/src/query/flexible.rs b/engine-ecs/src/query/flexible.rs index 66d62c6..fd1e30e 100644 --- a/engine-ecs/src/query/flexible.rs +++ b/engine-ecs/src/query/flexible.rs @@ -19,7 +19,7 @@ impl<'world, const MAX_TERM_CNT: usize> Query<'world, MAX_TERM_CNT> { /// Iterates over the entities matching this query. #[must_use] - pub fn iter(&self) -> Iter<'_> + pub fn iter(&self) -> Iter<'_, 'world> { Iter { iter: self @@ -52,10 +52,10 @@ impl<'world, const MAX_TERM_CNT: usize> Query<'world, MAX_TERM_CNT> } } -impl<'query, const MAX_TERM_CNT: usize> IntoIterator for &'query Query<'_, MAX_TERM_CNT> +impl<'query, 'world, const MAX_TERM_CNT: usize> IntoIterator for &'query Query<'world, MAX_TERM_CNT> { - type IntoIter = Iter<'query>; - type Item = EntityHandle<'query>; + type IntoIter = Iter<'query, 'world>; + type Item = EntityHandle<'world>; fn into_iter(self) -> Self::IntoIter { @@ -63,15 +63,15 @@ impl<'query, const MAX_TERM_CNT: usize> IntoIterator for &'query Query<'_, MAX_T } } -pub struct Iter<'query> +pub struct Iter<'query, 'world> { - iter: QueryEntityIter<'query>, - world: &'query World, + iter: QueryEntityIter<'query, 'world>, + world: &'world World, } -impl<'query> Iterator for Iter<'query> +impl<'query, 'world> Iterator for Iter<'query, 'world> { - type Item = EntityHandle<'query>; + type Item = EntityHandle<'world>; fn next(&mut self) -> Option { @@ -85,8 +85,8 @@ type ComponentIterMapFnOutput<'a> = Zip, EntityIter<'a>>; type ComponentIterMapFn = for<'a> fn(&'a Archetype) -> ComponentIterMapFnOutput<'a>; -type QueryEntityIter<'query> = FlatMap< - ArchetypeRefIter<'query, 'query>, - ComponentIterMapFnOutput<'query>, +type QueryEntityIter<'query, 'world> = FlatMap< + ArchetypeRefIter<'world, 'query>, + ComponentIterMapFnOutput<'world>, ComponentIterMapFn, >; diff --git a/engine-ecs/src/query/term.rs b/engine-ecs/src/query/term.rs index 7c4503a..04bca1d 100644 --- a/engine-ecs/src/query/term.rs +++ b/engine-ecs/src/query/term.rs @@ -1,17 +1,19 @@ use std::any::type_name; use std::marker::PhantomData; +use crate::World; use crate::component::{ Component, Handle as ComponentHandle, HandleMut as ComponentHandleMut, }; +use crate::entity::Handle as EntityHandle; use crate::query::{ - TermWithField, - TermWithoutField, + Term, TermsBuilder, TermsBuilderInterface, }; +use crate::tuple::Tuple; use crate::uid::With as WithUid; pub struct With @@ -21,16 +23,27 @@ where _pd: PhantomData, } -impl TermWithoutField for With +impl<'world, WithUidT> Term<'world> for With where WithUidT: WithUid, { + type AddField = Fields; + fn apply_to_terms_builder( terms_builder: &mut TermsBuilder, ) { terms_builder.present([WithUidT::uid()]); } + + fn add_field( + _entity_handle: &EntityHandle<'world>, + _world: &'world World, + fields: Fields, + ) -> Self::AddField + { + fields + } } pub struct Without @@ -40,21 +53,33 @@ where _pd: PhantomData, } -impl TermWithoutField for Without +impl<'world, WithUidT> Term<'world> for Without where WithUidT: WithUid, { + type AddField = Fields; + fn apply_to_terms_builder( terms_builder: &mut TermsBuilder, ) { terms_builder.absent([WithUidT::uid()]); } + + fn add_field( + _entity_handle: &EntityHandle<'world>, + _world: &'world World, + fields: Fields, + ) -> Self::AddField + { + fields + } } -impl TermWithField for Option<&ComponentT> +impl<'world, ComponentT: Component> Term<'world> for Option<&ComponentT> { - type Field<'a> = Option>; + type AddField = + Fields::WithElementAtEnd>>; fn apply_to_terms_builder( _terms_builder: &mut TermsBuilder, @@ -62,30 +87,36 @@ impl TermWithField for Option<&ComponentT> { } - fn get_field<'world>( - entity_handle: &crate::entity::Handle<'world>, - _world: &'world crate::World, - ) -> Self::Field<'world> + fn add_field( + entity_handle: &EntityHandle<'world>, + _world: &'world World, + fields: Fields, + ) -> Self::AddField { - Some( - ComponentHandle::<'world, ComponentT>::from_entity_component_ref( - &entity_handle - .get_matching_components(ComponentT::id()) - .next()?, - ) - .unwrap_or_else(|err| { - panic!( - "Creating handle to component {} failed: {err}", - type_name::() - ); - }), - ) + let component = (|| { + let comp_ref = &entity_handle + .get_matching_components(ComponentT::id()) + .next()?; + + match ComponentHandle::::from_entity_component_ref(comp_ref) { + Ok(component) => Some(component), + Err(err) => { + panic!( + "Creating handle to component {} failed: {err}", + type_name::() + ); + } + } + })(); + + fields.with_elem(component) } } -impl TermWithField for Option<&mut ComponentT> +impl<'world, ComponentT: Component> Term<'world> for Option<&mut ComponentT> { - type Field<'a> = Option>; + type AddField = + Fields::WithElementAtEnd>>; fn apply_to_terms_builder( _terms_builder: &mut TermsBuilder, @@ -93,24 +124,28 @@ impl TermWithField for Option<&mut ComponentT> { } - fn get_field<'world>( - entity_handle: &crate::entity::Handle<'world>, - world: &'world crate::World, - ) -> Self::Field<'world> + fn add_field( + entity_handle: &EntityHandle<'world>, + world: &'world World, + fields: Fields, + ) -> Self::AddField { - Some( - ComponentHandleMut::<'world, ComponentT>::from_entity_component_ref( - &entity_handle - .get_matching_components(ComponentT::id()) - .next()?, - world, - ) - .unwrap_or_else(|err| { - panic!( - "Creating handle to component {} failed: {err}", - type_name::() - ); - }), - ) + let component = (|| { + let comp_ref = &entity_handle + .get_matching_components(ComponentT::id()) + .next()?; + + match ComponentHandleMut::::from_entity_component_ref(comp_ref, world) { + Ok(component) => Some(component), + Err(err) => { + panic!( + "Creating mut handle to component {} failed: {err}", + type_name::() + ); + } + } + })(); + + fields.with_elem(component) } } -- cgit v1.2.3-18-g5258