diff options
Diffstat (limited to 'ecs/src/query')
| -rw-r--r-- | ecs/src/query/flexible.rs | 43 | ||||
| -rw-r--r-- | ecs/src/query/term.rs | 55 |
2 files changed, 67 insertions, 31 deletions
diff --git a/ecs/src/query/flexible.rs b/ecs/src/query/flexible.rs index 3e72b34..936ab82 100644 --- a/ecs/src/query/flexible.rs +++ b/ecs/src/query/flexible.rs @@ -2,13 +2,8 @@ use std::iter::{repeat_n, FlatMap, RepeatN, Zip}; use crate::component::storage::archetype::{Archetype, EntityIter}; -use crate::component::storage::{ - ArchetypeRefIter, - ArchetypeSearchTerms, - Storage as ComponentStorage, -}; +use crate::component::storage::{ArchetypeRefIter, ArchetypeSearchTerms}; use crate::entity::Handle as EntityHandle; -use crate::lock::ReadGuard; use crate::query::Terms; use crate::World; @@ -17,7 +12,6 @@ use crate::World; pub struct Query<'world, const MAX_TERM_CNT: usize> { world: &'world World, - component_storage: ReadGuard<'world, ComponentStorage>, terms: Terms<MAX_TERM_CNT>, } @@ -28,8 +22,9 @@ impl<'world, const MAX_TERM_CNT: usize> Query<'world, MAX_TERM_CNT> pub fn iter(&self) -> Iter<'_> { Iter { - world: self.world, iter: self + .world + .data .component_storage .search_archetypes(ArchetypeSearchTerms { required_components: &self.terms.required_components, @@ -41,27 +36,37 @@ impl<'world, const MAX_TERM_CNT: usize> Query<'world, MAX_TERM_CNT> .zip(archetype.entities()) }) as ComponentIterMapFn, ), + world: self.world, } } + #[must_use] + pub fn world(&self) -> &'world World + { + self.world + } + pub(crate) fn new(world: &'world World, terms: Terms<MAX_TERM_CNT>) -> Self { - Self { - world, - component_storage: world - .data - .component_storage - .read_nonblock() - .expect("Failed to acquire read-only component storage lock"), - terms, - } + Self { world, terms } + } +} + +impl<'query, const MAX_TERM_CNT: usize> IntoIterator for &'query Query<'_, MAX_TERM_CNT> +{ + type IntoIter = Iter<'query>; + type Item = EntityHandle<'query>; + + fn into_iter(self) -> Self::IntoIter + { + self.iter() } } pub struct Iter<'query> { - world: &'query World, iter: QueryEntityIter<'query>, + world: &'query World, } impl<'query> Iterator for Iter<'query> @@ -72,7 +77,7 @@ impl<'query> Iterator for Iter<'query> { let (archetype, entity) = self.iter.next()?; - Some(EntityHandle::new(self.world, archetype, entity)) + Some(EntityHandle::new(archetype, entity, self.world)) } } diff --git a/ecs/src/query/term.rs b/ecs/src/query/term.rs index 597dd1a..0683918 100644 --- a/ecs/src/query/term.rs +++ b/ecs/src/query/term.rs @@ -1,7 +1,11 @@ use std::any::type_name; use std::marker::PhantomData; -use crate::component::{Component, HandleFromEntityComponentRef, Ref as ComponentRef}; +use crate::component::{ + Component, + Handle as ComponentHandle, + HandleMut as ComponentHandleMut, +}; use crate::query::{ TermWithField, TermWithoutField, @@ -48,11 +52,40 @@ where } } -impl<ComponentRefT> TermWithField for Option<ComponentRefT> -where - ComponentRefT: ComponentRef, +impl<ComponentT: Component> TermWithField for Option<&ComponentT> +{ + type Field<'a> = Option<ComponentHandle<'a, ComponentT>>; + + fn apply_to_terms_builder<const MAX_TERM_CNT: usize>( + _terms_builder: &mut TermsBuilder<MAX_TERM_CNT>, + ) + { + } + + fn get_field<'world>( + entity_handle: &crate::entity::Handle<'world>, + _world: &'world crate::World, + ) -> Self::Field<'world> + { + Some( + ComponentHandle::<'world, ComponentT>::from_entity_component_ref( + &entity_handle + .get_matching_components(ComponentT::id()) + .next()?, + ) + .unwrap_or_else(|err| { + panic!( + "Creating handle to component {} failed: {err}", + type_name::<ComponentT>() + ); + }), + ) + } +} + +impl<ComponentT: Component> TermWithField for Option<&mut ComponentT> { - type Field<'a> = Option<ComponentRefT::Handle<'a>>; + type Field<'a> = Option<ComponentHandleMut<'a, ComponentT>>; fn apply_to_terms_builder<const MAX_TERM_CNT: usize>( _terms_builder: &mut TermsBuilder<MAX_TERM_CNT>, @@ -66,18 +99,16 @@ where ) -> Self::Field<'world> { Some( - ComponentRefT::Handle::<'world>::from_entity_component_ref( - Some( - entity_handle - .get_matching_components(ComponentRefT::Component::id()) - .next()?, - ), + ComponentHandleMut::<'world, ComponentT>::from_entity_component_ref( + &entity_handle + .get_matching_components(ComponentT::id()) + .next()?, world, ) .unwrap_or_else(|err| { panic!( "Creating handle to component {} failed: {err}", - type_name::<ComponentRefT::Component>() + type_name::<ComponentT>() ); }), ) |
