diff options
Diffstat (limited to 'ecs/src/query.rs')
-rw-r--r-- | ecs/src/query.rs | 70 |
1 files changed, 54 insertions, 16 deletions
diff --git a/ecs/src/query.rs b/ecs/src/query.rs index 7542f0d..1d27b7a 100644 --- a/ecs/src/query.rs +++ b/ecs/src/query.rs @@ -7,7 +7,7 @@ use crate::component::{Component, HandleFromEntityComponentRef, Ref as 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::uid::Uid; +use crate::uid::{Kind as UidKind, Uid, With as WithUid}; use crate::util::array_vec::ArrayVec; use crate::util::Array; use crate::World; @@ -111,7 +111,7 @@ where impl<'query, 'world, FieldTerms, FieldlessTerms> IntoIterator for &'query Query<'world, FieldTerms, FieldlessTerms> where - FieldTerms: TermWithFieldTuple + 'world, + FieldTerms: TermWithFieldTuple, FieldlessTerms: TermWithoutFieldTuple, { type IntoIter = Iter<'query, 'world, FieldTerms, FlexibleQueryIter<'query>>; @@ -171,11 +171,13 @@ pub struct TermsBuilder<const MAX_TERM_CNT: usize> pub trait TermsBuilderInterface { - fn with<ComponentT: Component>(self) -> Self; + fn with<WithUidT: WithUid>(self) -> Self; - fn without<ComponentT: Component>(self) -> Self; + fn without<WithUidT: WithUid>(self) -> Self; fn with_required(self, ids: impl Array<Uid>) -> Self; + + fn without_ids(self, ids: impl Array<Uid>) -> Self; } macro_rules! impl_terms_builder { @@ -196,25 +198,25 @@ macro_rules! impl_terms_builder { impl_terms_builder! { #[allow(unused_mut)] - fn with<ComponentT: Component>(mut self) -> Self + fn with<WithUidT: WithUid>(mut self) -> Self { let insert_index = self.required_components - .partition_point(|id| *id <= ComponentT::id()); + .partition_point(|id| *id <= WithUidT::uid()); self.required_components - .insert(insert_index, ComponentT::id()); + .insert(insert_index, WithUidT::uid()); self } #[allow(unused_mut)] - fn without<ComponentT: Component>(mut self) -> Self + fn without<WithUidT: WithUid>(mut self) -> Self { let insert_index = self.excluded_components - .partition_point(|id| *id <= ComponentT::id()); + .partition_point(|id| *id <= WithUidT::uid()); self.excluded_components - .insert(insert_index, ComponentT::id()); + .insert(insert_index, WithUidT::uid()); self } @@ -250,6 +252,38 @@ impl_terms_builder! { self } + + #[allow(unused_mut)] + fn without_ids(mut self, mut ids: impl Array<Uid>) -> Self + { + if !ids.as_ref().is_sorted() { + ids.as_mut().sort(); + } + + if self.excluded_components.len() == 0 { + self.excluded_components.extend(ids); + return self; + } + + let mut id_iter = ids.into_iter(); + + while let Some(id) = id_iter.next() { + let insert_index = self.excluded_components + .partition_point(|other_id| *other_id <= id); + + if insert_index == self.excluded_components.len() { + self.excluded_components.extend([id].into_iter().chain(id_iter)); + + return self; + } + + self.excluded_components + .insert(insert_index, id); + + } + + self + } } impl<const MAX_TERM_CNT: usize> TermsBuilder<MAX_TERM_CNT> @@ -303,8 +337,12 @@ impl<ComponentRefT: ComponentRef> TermWithField for ComponentRefT world: &'world World, ) -> Self::Field<'world> { + assert_eq!(ComponentRefT::Component::id().kind(), UidKind::Component); + Self::Field::from_entity_component_ref( - entity_handle.get_component(ComponentRefT::Component::id()), + entity_handle + .get_matching_components(ComponentRefT::Component::id()) + .next(), world, ) .unwrap_or_else(|err| { @@ -339,7 +377,7 @@ pub trait TermWithFieldTuple pub struct Iter<'query, 'world, FieldTerms, EntityHandleIter> where - FieldTerms: TermWithFieldTuple + 'world, + FieldTerms: TermWithFieldTuple, EntityHandleIter: Iterator<Item = EntityHandle<'query>>, { world: &'world World, @@ -350,7 +388,7 @@ where impl<'query, 'world, FieldTerms, EntityHandleIter> Iter<'query, 'world, FieldTerms, EntityHandleIter> where - FieldTerms: TermWithFieldTuple + 'world, + FieldTerms: TermWithFieldTuple, EntityHandleIter: Iterator<Item = EntityHandle<'query>>, 'world: 'query, { @@ -369,7 +407,7 @@ where impl<'query, 'world, FieldTerms, EntityHandleIter> Iterator for Iter<'query, 'world, FieldTerms, EntityHandleIter> where - FieldTerms: TermWithFieldTuple + 'world, + FieldTerms: TermWithFieldTuple, EntityHandleIter: Iterator<Item = EntityHandle<'query>>, 'world: 'query, { @@ -385,7 +423,7 @@ where pub struct ComponentAndEuidIter<'query, 'world, FieldTerms, EntityHandleIter> where - FieldTerms: TermWithFieldTuple + 'world, + FieldTerms: TermWithFieldTuple, EntityHandleIter: Iterator<Item = EntityHandle<'query>>, { world: &'world World, @@ -396,7 +434,7 @@ where impl<'query, 'world, FieldTerms, EntityHandleIter> Iterator for ComponentAndEuidIter<'query, 'world, FieldTerms, EntityHandleIter> where - FieldTerms: TermWithFieldTuple + 'world, + FieldTerms: TermWithFieldTuple, EntityHandleIter: Iterator<Item = EntityHandle<'query>>, 'world: 'query, { |