From 3e509487b6f241f60c77bf3eb62c79a8aafa1143 Mon Sep 17 00:00:00 2001 From: HampusM Date: Fri, 10 Jan 2025 20:47:48 +0100 Subject: feat(ecs): add support for custom inner ComponentIter iter --- ecs/src/query.rs | 52 +++++++++++++++++++++++++++++++++++++++-------- ecs/src/query/flexible.rs | 2 +- 2 files changed, 44 insertions(+), 10 deletions(-) (limited to 'ecs') diff --git a/ecs/src/query.rs b/ecs/src/query.rs index 2f8b285..8c1ede5 100644 --- a/ecs/src/query.rs +++ b/ecs/src/query.rs @@ -1,7 +1,11 @@ use std::marker::PhantomData; use crate::component::RefSequence as ComponentRefSequence; -use crate::query::flexible::{Iter as FlexibleQueryIter, Query as FlexibleQuery}; +use crate::query::flexible::{ + EntityHandle, + Iter as FlexibleQueryIter, + Query as FlexibleQuery, +}; use crate::query::options::Options; use crate::system::{Param as SystemParam, System}; use crate::uid::Uid; @@ -27,12 +31,13 @@ where { /// Iterates over the entities matching this query. #[must_use] - pub fn iter<'query>(&'query self) -> ComponentIter<'query, 'world, Comps> + pub fn iter<'query>( + &'query self, + ) -> ComponentIter<'query, 'world, Comps, FlexibleQueryIter<'query>> { #[cfg(feature = "debug")] tracing::debug!("Searching for {}", std::any::type_name::()); - #[allow(clippy::map_flatten)] ComponentIter { world: self.world, iter: self.inner.iter::(), @@ -40,6 +45,29 @@ where } } + /// Iterates over the entities matching this query using the iterator returned by + /// `func`. + /// + /// This function exists so that a custom [`EntityHandle`] iterator can be given to + /// [`ComponentIter`] without giving the user access to a reference to the [`World`]. + #[must_use] + pub fn iter_with<'query, OutIter>( + &'query self, + func: impl FnOnce(FlexibleQueryIter<'query>) -> OutIter, + ) -> ComponentIter<'query, 'world, Comps, OutIter> + where + OutIter: Iterator>, + { + #[cfg(feature = "debug")] + tracing::debug!("Searching for {}", std::any::type_name::()); + + ComponentIter { + world: self.world, + iter: func(self.inner.iter::()), + comps_pd: PhantomData, + } + } + /// Returns the UID of the entity at the given query iteration index. #[must_use] pub fn get_entity_uid(&self, entity_index: usize) -> Option @@ -63,7 +91,7 @@ where Comps: ComponentRefSequence + 'world, OptionsT: Options, { - type IntoIter = ComponentIter<'query, 'world, Comps>; + type IntoIter = ComponentIter<'query, 'world, Comps, FlexibleQueryIter<'query>>; type Item = Comps::Handles<'query>; fn into_iter(self) -> Self::IntoIter @@ -95,27 +123,33 @@ where } } -pub struct ComponentIter<'query, 'world, Comps> +pub struct ComponentIter<'query, 'world, Comps, EntityHandleIter> +where + EntityHandleIter: Iterator>, { world: &'world World, - iter: FlexibleQueryIter<'query>, + iter: EntityHandleIter, comps_pd: PhantomData, } -impl<'query, 'world, Comps> ComponentIter<'query, 'world, Comps> +impl<'query, 'world, Comps, EntityHandleIter> + ComponentIter<'query, 'world, Comps, EntityHandleIter> where Comps: ComponentRefSequence + 'world, + EntityHandleIter: Iterator>, 'world: 'query, { - pub(crate) fn new(world: &'world World, iter: FlexibleQueryIter<'query>) -> Self + pub(crate) fn new(world: &'world World, iter: EntityHandleIter) -> Self { Self { world, iter, comps_pd: PhantomData } } } -impl<'query, 'world, Comps> Iterator for ComponentIter<'query, 'world, Comps> +impl<'query, 'world, Comps, EntityHandleIter> Iterator + for ComponentIter<'query, 'world, Comps, EntityHandleIter> where Comps: ComponentRefSequence + 'world, + EntityHandleIter: Iterator>, 'world: 'query, { type Item = Comps::Handles<'query>; diff --git a/ecs/src/query/flexible.rs b/ecs/src/query/flexible.rs index d081d31..5c23e68 100644 --- a/ecs/src/query/flexible.rs +++ b/ecs/src/query/flexible.rs @@ -84,7 +84,7 @@ impl<'query> Iter<'query> pub fn into_component_iter<'world, Comps>( self, world: &'world World, - ) -> ComponentIter<'query, 'world, Comps> + ) -> ComponentIter<'query, 'world, Comps, Self> where Comps: ComponentRefSequence + 'world, 'world: 'query, -- cgit v1.2.3-18-g5258