//! Low-level querying. use crate::component::storage::archetype::{Archetype, EntityIter}; use crate::component::storage::{ArchetypeRefIter, TraversalResult}; use crate::entity::Handle as EntityHandle; use crate::query::Terms; use crate::util::array_vec::ArrayVec; use crate::World; /// Low-level entity query structure. #[derive(Debug)] pub struct Query<'world, const TERM_CAP: usize> { world: &'world World, terms: Terms, } impl<'world, const TERM_CAP: usize> Query<'world, TERM_CAP> { /// Iterates over the entities matching this query. #[must_use] pub fn iter<'this>(&'this self) -> Iter<'this, TERM_CAP> where 'world: 'this, { Iter { archetype_iter: self .world .data .component_storage .search_archetypes(&self.terms), current: None, world: self.world, } } #[must_use] pub fn world(&self) -> &'world World { self.world } pub(crate) fn new(world: &'world World, terms: Terms) -> Self { Self { world, terms } } } impl<'query, 'world, const TERM_CAP: usize> IntoIterator for &'query Query<'world, TERM_CAP> where 'world: 'query, { type IntoIter = Iter<'query, TERM_CAP>; type Item = EntityHandle<'query>; fn into_iter(self) -> Self::IntoIter { self.iter() } } pub struct Iter<'query, const TERM_CAP: usize> { archetype_iter: ArchetypeRefIter<'query, 'query, TERM_CAP>, current: Option<( &'query Archetype, ArrayVec, EntityIter<'query>, )>, world: &'query World, } impl<'query, const TERM_CAP: usize> Iter<'query, TERM_CAP> { pub fn traversal_results(&self) -> Option<&[TraversalResult]> { self.current .as_ref() .map(|(_, traversal_results, _)| traversal_results.as_ref()) } } impl<'query, const TERM_CAP: usize> Iterator for Iter<'query, TERM_CAP> { type Item = EntityHandle<'query>; fn next(&mut self) -> Option { if let Some((archetype, _, entity_iter)) = self.current.as_mut() { if let Some(entity) = entity_iter.next() { return Some(EntityHandle::new(archetype, entity, self.world)); } } let (archetype, traversal_results) = self.archetype_iter.next()?; self.current = Some((archetype, traversal_results, archetype.entities())); self.next() } }