summaryrefslogtreecommitdiff
path: root/ecs/src/query.rs
diff options
context:
space:
mode:
Diffstat (limited to 'ecs/src/query.rs')
-rw-r--r--ecs/src/query.rs70
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,
{