diff options
Diffstat (limited to 'ecs/src/query.rs')
| -rw-r--r-- | ecs/src/query.rs | 80 |
1 files changed, 35 insertions, 45 deletions
diff --git a/ecs/src/query.rs b/ecs/src/query.rs index ccb7add..5f13579 100644 --- a/ecs/src/query.rs +++ b/ecs/src/query.rs @@ -10,7 +10,7 @@ use crate::component::{ }; use crate::entity::Handle as EntityHandle; use crate::query::flexible::{Iter as FlexibleQueryIter, Query as FlexibleQuery}; -use crate::system::{Param as SystemParam, System}; +use crate::system::{Metadata as SystemMetadata, Param as SystemParam}; use crate::uid::{Kind as UidKind, Uid, With as WithUid}; use crate::util::array_vec::ArrayVec; use crate::util::Array; @@ -19,15 +19,16 @@ use crate::World; pub mod flexible; pub mod term; +// A term tuple type can have a maximum of 17 elements +pub const MAX_TERM_CNT: usize = 17; + #[derive(Debug)] pub struct Query<'world, FieldTerms, FieldlessTerms = ()> where FieldTerms: TermWithFieldTuple, FieldlessTerms: TermWithoutFieldTuple, { - world: &'world World, - // A term tuple type can have a maximum of 17 elements - inner: FlexibleQuery<'world, 17>, + inner: FlexibleQuery<'world, MAX_TERM_CNT>, _pd: PhantomData<(FieldTerms, FieldlessTerms)>, } @@ -46,8 +47,8 @@ where tracing::trace!("Searching for {}", std::any::type_name::<FieldTerms>()); Iter { - world: self.world, - iter: self.inner.iter(), + world: self.inner.world(), + inner: self.inner.iter(), comps_pd: PhantomData, } } @@ -62,7 +63,7 @@ where tracing::trace!("Searching for {}", std::any::type_name::<FieldTerms>()); ComponentAndEuidIter { - world: self.world, + world: self.inner.world(), iter: self.inner.iter(), comps_pd: PhantomData, } @@ -84,8 +85,8 @@ where tracing::trace!("Searching for {}", std::any::type_name::<FieldTerms>()); Iter { - world: self.world, - iter: func(self.inner.iter()), + world: self.inner.world(), + inner: func(self.inner.iter()), comps_pd: PhantomData, } } @@ -97,6 +98,25 @@ where Some(self.inner.iter().nth(entity_index)?.uid()) } + /// Returns a new `Query` created from a [`FlexibleQuery`]. + /// + /// # Important notes + /// The terms in `FieldTerms` and `FieldlessTerms` must be compatible with the terms + /// in the given [`FlexibleQuery`], otherwise any method call or iterating might + /// panic. + #[must_use] + pub fn from_flexible_query( + flexible_query: FlexibleQuery<'world, MAX_TERM_CNT>, + ) -> Self + { + // TODO: Check compatability of terms + + Self { + inner: flexible_query, + _pd: PhantomData, + } + } + pub(crate) fn new(world: &'world World) -> Self { let mut terms_builder = Terms::builder(); @@ -105,7 +125,6 @@ where FieldlessTerms::apply_terms_to_builder(&mut terms_builder); Self { - world, inner: world.flexible_query(terms_builder.build()), _pd: PhantomData, } @@ -135,17 +154,7 @@ where { type Input = (); - fn initialize<SystemImpl>( - _system: &mut impl System<'world, SystemImpl>, - _input: Self::Input, - ) - { - } - - fn new<SystemImpl>( - _system: &'world impl System<'world, SystemImpl>, - world: &'world World, - ) -> Self + fn new(world: &'world World, _system_metadata: &SystemMetadata) -> Self { Self::new(world) } @@ -360,7 +369,7 @@ impl<ComponentT: Component> TermWithField for &ComponentT ); }; - Self::Field::from_entity_component_ref(component).unwrap_or_else(|err| { + Self::Field::from_entity_component_ref(&component).unwrap_or_else(|err| { panic!( "Creating handle to component {} failed: {err}", type_name::<ComponentT>() @@ -382,7 +391,7 @@ impl<ComponentT: Component> TermWithField for &mut ComponentT fn get_field<'world>( entity_handle: &EntityHandle<'world>, - _world: &'world World, + world: &'world World, ) -> Self::Field<'world> { assert_eq!(ComponentT::id().kind(), UidKind::Component); @@ -401,7 +410,7 @@ impl<ComponentT: Component> TermWithField for &mut ComponentT ); }; - Self::Field::from_entity_component_ref(component).unwrap_or_else(|err| { + Self::Field::from_entity_component_ref(&component, world).unwrap_or_else(|err| { panic!( "Creating handle to component {} failed: {err}", type_name::<ComponentT>() @@ -437,29 +446,10 @@ where EntityHandleIter: Iterator<Item = EntityHandle<'query>>, { world: &'world World, - iter: EntityHandleIter, + inner: EntityHandleIter, comps_pd: PhantomData<FieldTerms>, } -impl<'query, 'world, FieldTerms, EntityHandleIter> - Iter<'query, 'world, FieldTerms, EntityHandleIter> -where - FieldTerms: TermWithFieldTuple, - EntityHandleIter: Iterator<Item = EntityHandle<'query>>, - 'world: 'query, -{ - /// Creates a new iterator from the given entity handle iterator. - /// - /// # Important - /// All of the yielded entities of the entity handle iterator should match the - /// terms `Terms`. The [`Self::next`] function will panic if it encounters a - /// entity that does not match the terms `Terms`. - pub fn new(world: &'world World, iter: EntityHandleIter) -> Self - { - Self { world, iter, comps_pd: PhantomData } - } -} - impl<'query, 'world, FieldTerms, EntityHandleIter> Iterator for Iter<'query, 'world, FieldTerms, EntityHandleIter> where @@ -471,7 +461,7 @@ where fn next(&mut self) -> Option<Self::Item> { - let entity_handle = self.iter.next()?; + let entity_handle = self.inner.next()?; Some(FieldTerms::get_fields(&entity_handle, self.world)) } |
