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.rs126
1 files changed, 79 insertions, 47 deletions
diff --git a/ecs/src/query.rs b/ecs/src/query.rs
index d7d2d1c..b29db3d 100644
--- a/ecs/src/query.rs
+++ b/ecs/src/query.rs
@@ -1,5 +1,4 @@
use std::any::type_name;
-use std::borrow::Cow;
use std::marker::PhantomData;
use seq_macro::seq;
@@ -9,7 +8,8 @@ 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::util::VecExt;
+use crate::util::array_vec::ArrayVec;
+use crate::util::Array;
use crate::World;
pub mod flexible;
@@ -22,7 +22,8 @@ where
FieldlessTerms: TermWithoutFieldTuple,
{
world: &'world World,
- inner: FlexibleQuery<'world, 'static>,
+ // A term tuple type can have a maximum of 17 elements
+ inner: FlexibleQuery<'world, 17>,
_pd: PhantomData<(FieldTerms, FieldlessTerms)>,
}
@@ -147,43 +148,47 @@ where
}
#[derive(Debug)]
-pub struct Terms<'a>
+pub struct Terms<const MAX_TERM_CNT: usize>
{
- required_components: Cow<'a, [Uid]>,
- excluded_components: Cow<'a, [Uid]>,
+ required_components: ArrayVec<Uid, MAX_TERM_CNT>,
+ excluded_components: ArrayVec<Uid, MAX_TERM_CNT>,
}
-impl<'a> Terms<'a>
+impl<const MAX_TERM_CNT: usize> Terms<MAX_TERM_CNT>
{
- pub fn builder() -> TermsBuilder<'a>
+ pub fn builder() -> TermsBuilder<MAX_TERM_CNT>
{
TermsBuilder::default()
}
}
#[derive(Debug, Default)]
-pub struct TermsBuilder<'a>
+pub struct TermsBuilder<const MAX_TERM_CNT: usize>
{
- required_components: Cow<'a, [Uid]>,
- excluded_components: Cow<'a, [Uid]>,
+ required_components: ArrayVec<Uid, MAX_TERM_CNT>,
+ excluded_components: ArrayVec<Uid, MAX_TERM_CNT>,
}
-pub trait TermsBuilderInterface<'a>
+pub trait TermsBuilderInterface
{
fn with<ComponentT: Component>(self) -> Self;
fn without<ComponentT: Component>(self) -> Self;
- fn with_required_ids(self, ids: &'a mut [Uid]) -> Self;
+ fn with_required(self, ids: impl Array<Uid>) -> Self;
}
macro_rules! impl_terms_builder {
($($impl_content: tt)*) => {
- impl<'a> TermsBuilderInterface<'a> for TermsBuilder<'a> {
+ impl<const MAX_TERM_CNT: usize>
+ TermsBuilderInterface for TermsBuilder<MAX_TERM_CNT>
+ {
$($impl_content)*
}
- impl<'a> TermsBuilderInterface<'a> for &mut TermsBuilder<'a> {
+ impl<const MAX_TERM_CNT: usize>
+ TermsBuilderInterface for &mut TermsBuilder<MAX_TERM_CNT>
+ {
$($impl_content)*
}
};
@@ -197,9 +202,11 @@ impl_terms_builder! {
return self;
}
+ let insert_index = self.required_components
+ .partition_point(|id| *id <= ComponentT::id());
+
self.required_components
- .to_mut()
- .insert_at_partition_point_by_key(ComponentT::id(), |id| *id);
+ .insert(insert_index, ComponentT::id());
self
}
@@ -214,48 +221,51 @@ impl_terms_builder! {
);
}
+ let insert_index = self.excluded_components
+ .partition_point(|id| *id <= ComponentT::id());
+
self.excluded_components
- .to_mut()
- .insert_at_partition_point_by_key(ComponentT::id(), |id| *id);
+ .insert(insert_index, ComponentT::id());
self
}
#[allow(unused_mut)]
- fn with_required_ids(mut self, ids: &'a mut [Uid]) -> Self
+ fn with_required(mut self, mut ids: impl Array<Uid>) -> Self
{
- if ids.is_empty() {
- return self;
+ if !ids.as_ref().is_sorted() {
+ ids.as_mut().sort();
}
- if !ids.is_sorted() {
- ids.sort();
+ if self.required_components.len() == 0 {
+ self.required_components.extend(ids);
+ return self;
}
- if self.required_components.is_empty() {
- self.required_components = Cow::Borrowed(ids);
+ let mut id_iter = ids.into_iter();
- return self;
- }
+ while let Some(id) = id_iter.next() {
+ let insert_index = self.required_components
+ .partition_point(|other_id| *other_id <= id);
- let first_id_pp_index = self.required_components.partition_point(|req_comp_id| {
- req_comp_id <= ids.first().expect("Cannot happend since not empty")
- });
+ if insert_index == self.required_components.len() {
+ self.required_components.extend([id].into_iter().chain(id_iter));
- let removed = self
- .required_components
- .to_mut()
- .splice(first_id_pp_index..first_id_pp_index, ids.iter().copied());
+ return self;
+ }
- assert_eq!(removed.count(), 0);
+ self.required_components
+ .insert(insert_index, id);
+
+ }
self
}
}
-impl<'a> TermsBuilder<'a>
+impl<const MAX_TERM_CNT: usize> TermsBuilder<MAX_TERM_CNT>
{
- pub fn build(self) -> Terms<'a>
+ pub fn build(self) -> Terms<MAX_TERM_CNT>
{
assert!(self.required_components.is_sorted());
assert!(self.excluded_components.is_sorted());
@@ -269,14 +279,18 @@ impl<'a> TermsBuilder<'a>
pub trait TermWithoutField
{
- fn apply_to_terms_builder(terms_builder: &mut TermsBuilder<'_>);
+ fn apply_to_terms_builder<const MAX_TERM_CNT: usize>(
+ terms_builder: &mut TermsBuilder<MAX_TERM_CNT>,
+ );
}
pub trait TermWithField
{
type Field<'a>;
- fn apply_to_terms_builder(terms_builder: &mut TermsBuilder<'_>);
+ fn apply_to_terms_builder<const MAX_TERM_CNT: usize>(
+ terms_builder: &mut TermsBuilder<MAX_TERM_CNT>,
+ );
fn get_field<'world>(
entity_handle: &EntityHandle<'world>,
@@ -288,7 +302,9 @@ impl<ComponentRefT: ComponentRef> TermWithField for ComponentRefT
{
type Field<'a> = ComponentRefT::Handle<'a>;
- fn apply_to_terms_builder(terms_builder: &mut TermsBuilder<'_>)
+ fn apply_to_terms_builder<const MAX_TERM_CNT: usize>(
+ terms_builder: &mut TermsBuilder<MAX_TERM_CNT>,
+ )
{
terms_builder.with::<ComponentRefT::Component>();
}
@@ -315,14 +331,18 @@ impl<ComponentRefT: ComponentRef> TermWithField for ComponentRefT
pub trait TermWithoutFieldTuple
{
- fn apply_terms_to_builder(terms_builder: &mut TermsBuilder<'_>);
+ fn apply_terms_to_builder<const MAX_TERM_CNT: usize>(
+ terms_builder: &mut TermsBuilder<MAX_TERM_CNT>,
+ );
}
pub trait TermWithFieldTuple
{
type Fields<'component>;
- fn apply_terms_to_builder(terms_builder: &mut TermsBuilder<'_>);
+ fn apply_terms_to_builder<const MAX_TERM_CNT: usize>(
+ terms_builder: &mut TermsBuilder<MAX_TERM_CNT>,
+ );
fn get_fields<'component>(
entity_handle: &EntityHandle<'component>,
@@ -411,7 +431,9 @@ macro_rules! impl_term_sequence {
seq!(I in 0..=$c {
impl<#(Term~I: TermWithoutField,)*> TermWithoutFieldTuple for (#(Term~I,)*)
{
- fn apply_terms_to_builder(terms_builder: &mut TermsBuilder<'_>)
+ fn apply_terms_to_builder<const MAX_TERM_CNT: usize>(
+ terms_builder: &mut TermsBuilder<MAX_TERM_CNT>
+ )
{
#(
Term~I::apply_to_terms_builder(terms_builder);
@@ -423,7 +445,9 @@ macro_rules! impl_term_sequence {
{
type Fields<'component> = (#(Term~I::Field<'component>,)*);
- fn apply_terms_to_builder(terms_builder: &mut TermsBuilder<'_>)
+ fn apply_terms_to_builder<const MAX_TERM_CNT: usize>(
+ terms_builder: &mut TermsBuilder<MAX_TERM_CNT>
+ )
{
#(
Term~I::apply_to_terms_builder(terms_builder);
@@ -448,14 +472,22 @@ seq!(C in 0..=16 {
impl TermWithoutFieldTuple for ()
{
- fn apply_terms_to_builder(_terms_builder: &mut TermsBuilder<'_>) {}
+ fn apply_terms_to_builder<const MAX_TERM_CNT: usize>(
+ _terms_builder: &mut TermsBuilder<MAX_TERM_CNT>,
+ )
+ {
+ }
}
impl TermWithFieldTuple for ()
{
type Fields<'component> = ();
- fn apply_terms_to_builder(_terms_builder: &mut TermsBuilder<'_>) {}
+ fn apply_terms_to_builder<const MAX_TERM_CNT: usize>(
+ _terms_builder: &mut TermsBuilder<MAX_TERM_CNT>,
+ )
+ {
+ }
fn get_fields<'component>(
_entity_handle: &EntityHandle<'_>,