summaryrefslogtreecommitdiff
path: root/ecs/src/query
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2025-03-21 20:05:53 +0100
committerHampusM <hampus@hampusmat.com>2025-03-22 15:16:01 +0100
commitfe62665b1d62d36ee0839e6bf24e3841ea667da9 (patch)
tree0533941d2cbbe5bf0a1995a33f05bca37da949fd /ecs/src/query
parent76e7e612e7b516bf52b508ae5bb367b1ddc3babc (diff)
refactor(ecs): replace query options with fieldless terms
Diffstat (limited to 'ecs/src/query')
-rw-r--r--ecs/src/query/flexible.rs44
-rw-r--r--ecs/src/query/options.rs59
-rw-r--r--ecs/src/query/term.rs38
3 files changed, 57 insertions, 84 deletions
diff --git a/ecs/src/query/flexible.rs b/ecs/src/query/flexible.rs
index a3e8701..7d24dc9 100644
--- a/ecs/src/query/flexible.rs
+++ b/ecs/src/query/flexible.rs
@@ -1,10 +1,13 @@
//! Low-level querying.
-use std::iter::{repeat_n, Filter, FlatMap, RepeatN, Zip};
+use std::iter::{repeat_n, FlatMap, RepeatN, Zip};
use crate::component::storage::archetype::{Archetype, ArchetypeEntity, EntityIter};
-use crate::component::storage::{ArchetypeRefIter, Storage as ComponentStorage};
+use crate::component::storage::{
+ ArchetypeRefIter,
+ ArchetypeSearchTerms,
+ Storage as ComponentStorage,
+};
use crate::lock::ReadGuard;
-use crate::query::options::Options;
use crate::query::Terms;
use crate::uid::Uid;
use crate::{EntityComponent, World};
@@ -21,19 +24,21 @@ impl<'world, 'terms> Query<'world, 'terms>
{
/// Iterates over the entities matching this query.
#[must_use]
- pub fn iter<OptionsT: Options>(&self) -> Iter<'_>
+ pub fn iter(&self) -> Iter<'_>
{
Iter {
iter: self
.component_storage
- .search_archetypes(self.terms.required_components.as_ref())
+ .search_archetypes(ArchetypeSearchTerms {
+ required_components: &self.terms.required_components,
+ excluded_components: &self.terms.excluded_components,
+ })
.flat_map(
(|archetype| {
repeat_n(archetype, archetype.entity_cnt())
.zip(archetype.entities())
}) as ComponentIterMapFn,
- )
- .filter(|(_, entity)| OptionsT::entity_filter(&entity.components)),
+ ),
}
}
@@ -85,16 +90,11 @@ impl<'query> EntityHandle<'query>
#[inline]
#[must_use]
- pub fn components(&self) -> &'query [EntityComponent]
+ pub fn get_component(&self, component_uid: Uid) -> Option<&'query EntityComponent>
{
- &self.entity.components
- }
+ let index = self.archetype.get_index_for_component(component_uid)?;
- #[inline]
- #[must_use]
- pub fn get_component_index(&self, component_uid: Uid) -> Option<usize>
- {
- self.archetype.get_index_for_component(component_uid)
+ Some(self.entity.components.get(index).unwrap())
}
}
@@ -102,14 +102,8 @@ type ComponentIterMapFnOutput<'a> = Zip<RepeatN<&'a Archetype>, EntityIter<'a>>;
type ComponentIterMapFn = for<'a> fn(&'a Archetype) -> ComponentIterMapFnOutput<'a>;
-type ComponentIterFilterFn =
- for<'a, 'b> fn(&'a (&'b Archetype, &'b ArchetypeEntity)) -> bool;
-
-type QueryEntityIter<'query> = Filter<
- FlatMap<
- ArchetypeRefIter<'query>,
- ComponentIterMapFnOutput<'query>,
- ComponentIterMapFn,
- >,
- ComponentIterFilterFn,
+type QueryEntityIter<'query> = FlatMap<
+ ArchetypeRefIter<'query, 'query>,
+ ComponentIterMapFnOutput<'query>,
+ ComponentIterMapFn,
>;
diff --git a/ecs/src/query/options.rs b/ecs/src/query/options.rs
deleted file mode 100644
index 6318359..0000000
--- a/ecs/src/query/options.rs
+++ /dev/null
@@ -1,59 +0,0 @@
-use std::marker::PhantomData;
-
-use hashbrown::HashSet;
-
-use crate::component::Component;
-use crate::EntityComponent;
-
-/// Query options.
-pub trait Options
-{
- fn entity_filter(components: &[EntityComponent]) -> bool;
-}
-
-impl Options for ()
-{
- fn entity_filter(_components: &[EntityComponent]) -> bool
- {
- true
- }
-}
-
-pub struct With<ComponentT>
-where
- ComponentT: Component,
-{
- _pd: PhantomData<ComponentT>,
-}
-
-impl<ComponentT> Options for With<ComponentT>
-where
- ComponentT: Component,
-{
- fn entity_filter(components: &[EntityComponent]) -> bool
- {
- let ids_set = components
- .iter()
- .map(|component| component.id)
- .collect::<HashSet<_>>();
-
- ids_set.contains(&ComponentT::id())
- }
-}
-
-pub struct Not<OptionsT>
-where
- OptionsT: Options,
-{
- _pd: PhantomData<OptionsT>,
-}
-
-impl<OptionsT> Options for Not<OptionsT>
-where
- OptionsT: Options,
-{
- fn entity_filter(components: &[EntityComponent]) -> bool
- {
- !OptionsT::entity_filter(components)
- }
-}
diff --git a/ecs/src/query/term.rs b/ecs/src/query/term.rs
new file mode 100644
index 0000000..7f24147
--- /dev/null
+++ b/ecs/src/query/term.rs
@@ -0,0 +1,38 @@
+use std::marker::PhantomData;
+
+use crate::component::Component;
+use crate::query::{TermWithoutField, TermsBuilder, TermsBuilderInterface};
+
+pub struct With<ComponentT>
+where
+ ComponentT: Component,
+{
+ _pd: PhantomData<ComponentT>,
+}
+
+impl<ComponentT> TermWithoutField for With<ComponentT>
+where
+ ComponentT: Component,
+{
+ fn apply_to_terms_builder(terms_builder: &mut TermsBuilder<'_>)
+ {
+ terms_builder.with::<ComponentT>();
+ }
+}
+
+pub struct Without<ComponentT>
+where
+ ComponentT: Component,
+{
+ _pd: PhantomData<ComponentT>,
+}
+
+impl<ComponentT> TermWithoutField for Without<ComponentT>
+where
+ ComponentT: Component,
+{
+ fn apply_to_terms_builder(terms_builder: &mut TermsBuilder<'_>)
+ {
+ terms_builder.without::<ComponentT>();
+ }
+}