diff --git a/crates/bevy_ecs/src/query/state.rs b/crates/bevy_ecs/src/query/state.rs index 00d8b6f97085b..9cd8d911907ec 100644 --- a/crates/bevy_ecs/src/query/state.rs +++ b/crates/bevy_ecs/src/query/state.rs @@ -2020,7 +2020,7 @@ mod tests { .run_system_once(|query: Query<&mut A>| { let mut readonly = query.as_readonly(); let mut lens: QueryLens<&mut A> = readonly.transmute_lens(); - bad(lens.query(), query.as_readonly()); + bad(lens.reborrow(), query.as_readonly()); }) .unwrap(); } @@ -2146,7 +2146,7 @@ mod tests { .run_system_once(|query_a: Query<&mut A>, mut query_b: Query<&mut B>| { let mut readonly = query_a.as_readonly(); let mut lens: QueryLens<(&mut A, &mut B)> = readonly.join(&mut query_b); - bad(lens.query(), query_a.as_readonly()); + bad(lens.reborrow(), query_a.as_readonly()); }) .unwrap(); } diff --git a/crates/bevy_ecs/src/relationship/relationship_query.rs b/crates/bevy_ecs/src/relationship/relationship_query.rs index a7acea7de0732..d6827b4c94688 100644 --- a/crates/bevy_ecs/src/relationship/relationship_query.rs +++ b/crates/bevy_ecs/src/relationship/relationship_query.rs @@ -1,6 +1,8 @@ +use core::ops::Deref; + use crate::{ entity::Entity, - query::{QueryData, QueryFilter}, + query::{QueryData, QueryFilter, QueryState}, relationship::{Relationship, RelationshipTarget}, system::Query, }; @@ -9,24 +11,26 @@ use smallvec::SmallVec; use super::SourceIter; -impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { +impl<'w, 's, D: QueryData, F: QueryFilter, S: Deref>> + Query<'w, 's, D, F, S> +{ /// If the given `entity` contains the `R` [`Relationship`] component, returns the /// target entity of that relationship. pub fn related(&'w self, entity: Entity) -> Option where - ::ReadOnly: QueryData = &'w R>, + D::ReadOnly: QueryData = &'w R>, { self.get(entity).map(R::get).ok() } /// If the given `entity` contains the `S` [`RelationshipTarget`] component, returns the /// source entities stored on that component. - pub fn relationship_sources( + pub fn relationship_sources( &'w self, entity: Entity, ) -> impl Iterator + 'w where - ::ReadOnly: QueryData = &'w S>, + D::ReadOnly: QueryData = &'w R>, { self.get(entity) .into_iter() @@ -42,7 +46,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { /// If your relationship is not a tree (like Bevy's hierarchy), be sure to stop if you encounter a duplicate entity. pub fn root_ancestor(&'w self, entity: Entity) -> Entity where - ::ReadOnly: QueryData = &'w R>, + D::ReadOnly: QueryData = &'w R>, { // Recursively search up the tree until we're out of parents match self.get(entity) { @@ -57,13 +61,13 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { /// /// For relationship graphs that contain loops, this could loop infinitely. /// If your relationship is not a tree (like Bevy's hierarchy), be sure to stop if you encounter a duplicate entity. - pub fn iter_leaves( + pub fn iter_leaves( &'w self, entity: Entity, - ) -> impl Iterator + use<'w, 's, S, D, F> + ) -> impl Iterator + use<'w, 's, D, F, S, R> where - ::ReadOnly: QueryData = &'w S>, - SourceIter<'w, S>: DoubleEndedIterator, + D::ReadOnly: QueryData = &'w R>, + SourceIter<'w, R>: DoubleEndedIterator, { self.iter_descendants_depth_first(entity).filter(|entity| { self.get(*entity) @@ -80,7 +84,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { entity: Entity, ) -> impl Iterator + 'w where - D::ReadOnly: QueryData = (Option<&'w R>, Option<&'w R::RelationshipTarget>)>, + D::ReadOnly: QueryData = (Option<&'w R>, Option<&'w R::RelationshipTarget>)>, { self.get(entity) .ok() @@ -98,12 +102,12 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { /// /// For relationship graphs that contain loops, this could loop infinitely. /// If your relationship is not a tree (like Bevy's hierarchy), be sure to stop if you encounter a duplicate entity. - pub fn iter_descendants( + pub fn iter_descendants( &'w self, entity: Entity, - ) -> DescendantIter<'w, 's, D, F, S> + ) -> DescendantIter<'w, 's, D, F, S, R> where - D::ReadOnly: QueryData = &'w S>, + D::ReadOnly: QueryData = &'w R>, { DescendantIter::new(self, entity) } @@ -115,13 +119,13 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { /// /// For relationship graphs that contain loops, this could loop infinitely. /// If your relationship is not a tree (like Bevy's hierarchy), be sure to stop if you encounter a duplicate entity. - pub fn iter_descendants_depth_first( + pub fn iter_descendants_depth_first( &'w self, entity: Entity, - ) -> DescendantDepthFirstIter<'w, 's, D, F, S> + ) -> DescendantDepthFirstIter<'w, 's, D, F, S, R> where - D::ReadOnly: QueryData = &'w S>, - SourceIter<'w, S>: DoubleEndedIterator, + D::ReadOnly: QueryData = &'w R>, + SourceIter<'w, R>: DoubleEndedIterator, { DescendantDepthFirstIter::new(self, entity) } @@ -135,9 +139,9 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { pub fn iter_ancestors( &'w self, entity: Entity, - ) -> AncestorIter<'w, 's, D, F, R> + ) -> AncestorIter<'w, 's, D, F, S, R> where - D::ReadOnly: QueryData = &'w R>, + D::ReadOnly: QueryData = &'w R>, { AncestorIter::new(self, entity) } @@ -146,20 +150,33 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { /// An [`Iterator`] of [`Entity`]s over the descendants of an [`Entity`]. /// /// Traverses the hierarchy breadth-first. -pub struct DescendantIter<'w, 's, D: QueryData, F: QueryFilter, S: RelationshipTarget> -where - D::ReadOnly: QueryData = &'w S>, +pub struct DescendantIter< + 'w, + 's, + D: QueryData, + F: QueryFilter, + S: Deref>, + R: RelationshipTarget, +> where + D::ReadOnly: QueryData = &'w R>, { - children_query: &'w Query<'w, 's, D, F>, + children_query: &'w Query<'w, 's, D, F, S>, vecdeque: VecDeque, } -impl<'w, 's, D: QueryData, F: QueryFilter, S: RelationshipTarget> DescendantIter<'w, 's, D, F, S> +impl< + 'w, + 's, + D: QueryData, + F: QueryFilter, + S: Deref>, + R: RelationshipTarget, + > DescendantIter<'w, 's, D, F, S, R> where - D::ReadOnly: QueryData = &'w S>, + D::ReadOnly: QueryData = &'w R>, { /// Returns a new [`DescendantIter`]. - pub fn new(children_query: &'w Query<'w, 's, D, F>, entity: Entity) -> Self { + pub fn new(children_query: &'w Query<'w, 's, D, F, S>, entity: Entity) -> Self { DescendantIter { children_query, vecdeque: children_query @@ -171,10 +188,16 @@ where } } -impl<'w, 's, D: QueryData, F: QueryFilter, S: RelationshipTarget> Iterator - for DescendantIter<'w, 's, D, F, S> +impl< + 'w, + 's, + D: QueryData, + F: QueryFilter, + S: Deref>, + R: RelationshipTarget, + > Iterator for DescendantIter<'w, 's, D, F, S, R> where - D::ReadOnly: QueryData = &'w S>, + D::ReadOnly: QueryData = &'w R>, { type Item = Entity; @@ -192,22 +215,34 @@ where /// An [`Iterator`] of [`Entity`]s over the descendants of an [`Entity`]. /// /// Traverses the hierarchy depth-first. -pub struct DescendantDepthFirstIter<'w, 's, D: QueryData, F: QueryFilter, S: RelationshipTarget> -where - D::ReadOnly: QueryData = &'w S>, +pub struct DescendantDepthFirstIter< + 'w, + 's, + D: QueryData, + F: QueryFilter, + S: Deref>, + R: RelationshipTarget, +> where + D::ReadOnly: QueryData = &'w R>, { - children_query: &'w Query<'w, 's, D, F>, + children_query: &'w Query<'w, 's, D, F, S>, stack: SmallVec<[Entity; 8]>, } -impl<'w, 's, D: QueryData, F: QueryFilter, S: RelationshipTarget> - DescendantDepthFirstIter<'w, 's, D, F, S> +impl< + 'w, + 's, + D: QueryData, + F: QueryFilter, + S: Deref>, + R: RelationshipTarget, + > DescendantDepthFirstIter<'w, 's, D, F, S, R> where - D::ReadOnly: QueryData = &'w S>, - SourceIter<'w, S>: DoubleEndedIterator, + D::ReadOnly: QueryData = &'w R>, + SourceIter<'w, R>: DoubleEndedIterator, { /// Returns a new [`DescendantDepthFirstIter`]. - pub fn new(children_query: &'w Query<'w, 's, D, F>, entity: Entity) -> Self { + pub fn new(children_query: &'w Query<'w, 's, D, F, S>, entity: Entity) -> Self { DescendantDepthFirstIter { children_query, stack: children_query @@ -217,11 +252,17 @@ where } } -impl<'w, 's, D: QueryData, F: QueryFilter, S: RelationshipTarget> Iterator - for DescendantDepthFirstIter<'w, 's, D, F, S> +impl< + 'w, + 's, + D: QueryData, + F: QueryFilter, + S: Deref>, + R: RelationshipTarget, + > Iterator for DescendantDepthFirstIter<'w, 's, D, F, S, R> where - D::ReadOnly: QueryData = &'w S>, - SourceIter<'w, S>: DoubleEndedIterator, + D::ReadOnly: QueryData = &'w R>, + SourceIter<'w, R>: DoubleEndedIterator, { type Item = Entity; @@ -237,20 +278,33 @@ where } /// An [`Iterator`] of [`Entity`]s over the ancestors of an [`Entity`]. -pub struct AncestorIter<'w, 's, D: QueryData, F: QueryFilter, R: Relationship> -where - D::ReadOnly: QueryData = &'w R>, +pub struct AncestorIter< + 'w, + 's, + D: QueryData, + F: QueryFilter, + S: Deref>, + R: Relationship, +> where + D::ReadOnly: QueryData = &'w R>, { - parent_query: &'w Query<'w, 's, D, F>, + parent_query: &'w Query<'w, 's, D, F, S>, next: Option, } -impl<'w, 's, D: QueryData, F: QueryFilter, R: Relationship> AncestorIter<'w, 's, D, F, R> +impl< + 'w, + 's, + D: QueryData, + F: QueryFilter, + S: Deref>, + R: Relationship, + > AncestorIter<'w, 's, D, F, S, R> where - D::ReadOnly: QueryData = &'w R>, + D::ReadOnly: QueryData = &'w R>, { /// Returns a new [`AncestorIter`]. - pub fn new(parent_query: &'w Query<'w, 's, D, F>, entity: Entity) -> Self { + pub fn new(parent_query: &'w Query<'w, 's, D, F, S>, entity: Entity) -> Self { AncestorIter { parent_query, next: Some(entity), @@ -258,10 +312,16 @@ where } } -impl<'w, 's, D: QueryData, F: QueryFilter, R: Relationship> Iterator - for AncestorIter<'w, 's, D, F, R> +impl< + 'w, + 's, + D: QueryData, + F: QueryFilter, + S: Deref>, + R: Relationship, + > Iterator for AncestorIter<'w, 's, D, F, S, R> where - D::ReadOnly: QueryData = &'w R>, + D::ReadOnly: QueryData = &'w R>, { type Item = Entity; diff --git a/crates/bevy_ecs/src/system/query.rs b/crates/bevy_ecs/src/system/query.rs index 6e44301b18cb1..c13fdc21cf4be 100644 --- a/crates/bevy_ecs/src/system/query.rs +++ b/crates/bevy_ecs/src/system/query.rs @@ -11,6 +11,7 @@ use crate::{ }, world::unsafe_world_cell::UnsafeWorldCell, }; +use alloc::boxed::Box; use core::{ marker::PhantomData, mem::MaybeUninit, @@ -482,12 +483,23 @@ use core::{ /// ``` /// /// [autovectorization]: https://en.wikipedia.org/wiki/Automatic_vectorization -pub struct Query<'world, 'state, D: QueryData, F: QueryFilter = ()> { +pub struct Query< + 'world, + // Note that `'state` is only used in the default type for `S`. + // That's necessary to make `Query` be a valid `SystemParam`. + 'state, + D: QueryData, + F: QueryFilter = (), + S: Deref> = &'state QueryState, +> { // SAFETY: Must have access to the components registered in `state`. world: UnsafeWorldCell<'world>, - state: &'state QueryState, + state: S, last_run: Tick, this_run: Tick, + // Note that `&'state QueryState` won't work because + // `QueryLens` uses `'static`, but `D` and `F` might not be `'static`. + marker: PhantomData<(&'state (), fn() -> QueryState)>, } impl Clone for Query<'_, '_, D, F> { @@ -510,7 +522,9 @@ impl core::fmt::Debug for Query<'_, '_, D, F> { } } -impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { +impl<'w, 's, D: QueryData, F: QueryFilter, S: Deref>> + Query<'w, 's, D, F, S> +{ /// Creates a new query. /// /// # Safety @@ -521,7 +535,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { #[inline] pub(crate) unsafe fn new( world: UnsafeWorldCell<'w>, - state: &'s QueryState, + state: S, last_run: Tick, this_run: Tick, ) -> Self { @@ -530,6 +544,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { state, last_run, this_run, + marker: PhantomData, } } @@ -542,14 +557,14 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { /// # See also /// /// [`into_readonly`](Self::into_readonly) for a version that consumes the `Query` to return one with the full `'world` lifetime. - pub fn as_readonly(&self) -> Query<'_, 's, D::ReadOnly, F> { + pub fn as_readonly(&self) -> Query<'_, '_, D::ReadOnly, F> { // SAFETY: The reborrowed query is converted to read-only, so it cannot perform mutable access, // and the original query is held with a shared borrow, so it cannot perform mutable access either. unsafe { self.reborrow_unsafe() }.into_readonly() } /// Returns another `Query` from this does not return any data, which can be faster. - fn as_nop(&self) -> Query<'_, 's, NopWorldQuery, F> { + fn as_nop(&self) -> Query<'_, '_, NopWorldQuery, F> { let new_state = self.state.as_nop(); // SAFETY: // - The reborrowed query is converted to read-only, so it cannot perform mutable access, @@ -560,23 +575,6 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { unsafe { Query::new(self.world, new_state, self.last_run, self.this_run) } } - /// Returns another `Query` from this that fetches the read-only version of the query items. - /// - /// For example, `Query<(&mut D1, &D2, &mut D3), With>` will become `Query<(&D1, &D2, &D3), With>`. - /// This can be useful when working around the borrow checker, - /// or reusing functionality between systems via functions that accept query types. - /// - /// # See also - /// - /// [`as_readonly`](Self::as_readonly) for a version that borrows the `Query` instead of consuming it. - pub fn into_readonly(self) -> Query<'w, 's, D::ReadOnly, F> { - let new_state = self.state.as_readonly(); - // SAFETY: - // - This is memory safe because it turns the query immutable. - // - The world matches because it was the same one used to construct self. - unsafe { Query::new(self.world, new_state, self.last_run, self.this_run) } - } - /// Returns a new `Query` reborrowing the access from this one. The current query will be unusable /// while the new one exists. /// @@ -601,7 +599,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { /// } /// } /// ``` - pub fn reborrow(&mut self) -> Query<'_, 's, D, F> { + pub fn reborrow(&mut self) -> Query<'_, '_, D, F> { // SAFETY: this query is exclusively borrowed while the new one exists, so // no overlapping access can occur. unsafe { self.reborrow_unsafe() } @@ -618,29 +616,11 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { /// # See also /// /// - [`reborrow`](Self::reborrow) for the safe versions. - pub unsafe fn reborrow_unsafe(&self) -> Query<'_, 's, D, F> { - // SAFETY: - // - This is memory safe because the caller ensures that there are no conflicting references. - // - The world matches because it was the same one used to construct self. - unsafe { self.copy_unsafe() } - } - - /// Returns a new `Query` copying the access from this one. - /// The current query will still be usable while the new one exists, but must not be used in a way that violates aliasing. - /// - /// # Safety - /// - /// This function makes it possible to violate Rust's aliasing guarantees. - /// You must make sure this call does not result in a mutable or shared reference to a component with a mutable reference. - /// - /// # See also - /// - /// - [`reborrow_unsafe`](Self::reborrow_unsafe) for a safer version that constrains the returned `'w` lifetime to the length of the borrow. - unsafe fn copy_unsafe(&self) -> Query<'w, 's, D, F> { + pub unsafe fn reborrow_unsafe(&self) -> Query<'_, '_, D, F> { // SAFETY: // - This is memory safe because the caller ensures that there are no conflicting references. // - The world matches because it was the same one used to construct self. - unsafe { Query::new(self.world, self.state, self.last_run, self.this_run) } + unsafe { Query::new(self.world, &self.state, self.last_run, self.this_run) } } /// Returns an [`Iterator`] over the read-only query items. @@ -670,7 +650,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { /// /// [`iter_mut`](Self::iter_mut) for mutable query items. #[inline] - pub fn iter(&self) -> QueryIter<'_, 's, D::ReadOnly, F> { + pub fn iter(&self) -> QueryIter<'_, '_, D::ReadOnly, F> { self.as_readonly().into_iter() } @@ -701,7 +681,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { /// /// [`iter`](Self::iter) for read-only query items. #[inline] - pub fn iter_mut(&mut self) -> QueryIter<'_, 's, D, F> { + pub fn iter_mut(&mut self) -> QueryIter<'_, '_, D, F> { self.reborrow().into_iter() } @@ -731,7 +711,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { #[inline] pub fn iter_combinations( &self, - ) -> QueryCombinationIter<'_, 's, D::ReadOnly, F, K> { + ) -> QueryCombinationIter<'_, '_, D::ReadOnly, F, K> { self.as_readonly().iter_combinations_inner() } @@ -761,40 +741,10 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { #[inline] pub fn iter_combinations_mut( &mut self, - ) -> QueryCombinationIter<'_, 's, D, F, K> { + ) -> QueryCombinationIter<'_, '_, D, F, K> { self.reborrow().iter_combinations_inner() } - /// Returns a [`QueryCombinationIter`] over all combinations of `K` query items without repetition. - /// This consumes the [`Query`] to return results with the actual "inner" world lifetime. - /// - /// This iterator is always guaranteed to return results from each unique pair of matching entities. - /// Iteration order is not guaranteed. - /// - /// # Example - /// - /// ``` - /// # use bevy_ecs::prelude::*; - /// # #[derive(Component)] - /// # struct ComponentA; - /// fn some_system(query: Query<&mut ComponentA>) { - /// let mut combinations = query.iter_combinations_inner(); - /// while let Some([mut a1, mut a2]) = combinations.fetch_next() { - /// // mutably access components data - /// } - /// } - /// ``` - /// - /// # See also - /// - /// - [`iter_combinations`](Self::iter_combinations) for read-only query item combinations. - /// - [`iter_combinations_mut`](Self::iter_combinations_mut) for mutable query item combinations. - #[inline] - pub fn iter_combinations_inner(self) -> QueryCombinationIter<'w, 's, D, F, K> { - // SAFETY: `self.world` has permission to access the required components. - unsafe { QueryCombinationIter::new(self.world, self.state, self.last_run, self.this_run) } - } - /// Returns an [`Iterator`] over the read-only query items generated from an [`Entity`] list. /// /// Items are returned in the order of the list of entities, and may not be unique if the input @@ -836,7 +786,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { pub fn iter_many>( &self, entities: EntityList, - ) -> QueryManyIter<'_, 's, D::ReadOnly, F, EntityList::IntoIter> { + ) -> QueryManyIter<'_, '_, D::ReadOnly, F, EntityList::IntoIter> { self.as_readonly().iter_many_inner(entities) } @@ -881,37 +831,10 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { pub fn iter_many_mut>( &mut self, entities: EntityList, - ) -> QueryManyIter<'_, 's, D, F, EntityList::IntoIter> { + ) -> QueryManyIter<'_, '_, D, F, EntityList::IntoIter> { self.reborrow().iter_many_inner(entities) } - /// Returns an iterator over the query items generated from an [`Entity`] list. - /// This consumes the [`Query`] to return results with the actual "inner" world lifetime. - /// - /// Items are returned in the order of the list of entities, and may not be unique if the input - /// doesn't guarantee uniqueness. Entities that don't match the query are skipped. - /// - /// # See also - /// - /// - [`iter_many`](Self::iter_many) to get read-only query items. - /// - [`iter_many_mut`](Self::iter_many_mut) to get mutable query items. - #[inline] - pub fn iter_many_inner>( - self, - entities: EntityList, - ) -> QueryManyIter<'w, 's, D, F, EntityList::IntoIter> { - // SAFETY: `self.world` has permission to access the required components. - unsafe { - QueryManyIter::new( - self.world, - self.state, - entities, - self.last_run, - self.this_run, - ) - } - } - /// Returns an [`Iterator`] over the unique read-only query items generated from an [`EntitySet`]. /// /// Items are returned in the order of the list of entities. Entities that don't match the query are skipped. @@ -964,7 +887,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { pub fn iter_many_unique( &self, entities: EntityList, - ) -> QueryManyUniqueIter<'_, 's, D::ReadOnly, F, EntityList::IntoIter> { + ) -> QueryManyUniqueIter<'_, '_, D::ReadOnly, F, EntityList::IntoIter> { self.as_readonly().iter_many_unique_inner(entities) } @@ -1019,74 +942,10 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { pub fn iter_many_unique_mut( &mut self, entities: EntityList, - ) -> QueryManyUniqueIter<'_, 's, D, F, EntityList::IntoIter> { + ) -> QueryManyUniqueIter<'_, '_, D, F, EntityList::IntoIter> { self.reborrow().iter_many_unique_inner(entities) } - /// Returns an iterator over the unique query items generated from an [`EntitySet`]. - /// This consumes the [`Query`] to return results with the actual "inner" world lifetime. - /// - /// Items are returned in the order of the list of entities. Entities that don't match the query are skipped. - /// - /// # Examples - /// - /// ``` - /// # use bevy_ecs::{prelude::*, entity::{EntitySet, UniqueEntityIter}}; - /// # use core::slice; - /// #[derive(Component)] - /// struct Counter { - /// value: i32 - /// } - /// - /// // `Friends` ensures that it only lists unique entities. - /// #[derive(Component)] - /// struct Friends { - /// unique_list: Vec, - /// } - /// - /// impl<'a> IntoIterator for &'a Friends { - /// type Item = &'a Entity; - /// type IntoIter = UniqueEntityIter>; - /// - /// fn into_iter(self) -> Self::IntoIter { - /// // SAFETY: `Friends` ensures that it unique_list contains only unique entities. - /// unsafe { UniqueEntityIter::from_iterator_unchecked(self.unique_list.iter()) } - /// } - /// } - /// - /// fn system( - /// friends_query: Query<&Friends>, - /// mut counter_query: Query<&mut Counter>, - /// ) { - /// let friends = friends_query.single().unwrap(); - /// for mut counter in counter_query.iter_many_unique_inner(friends) { - /// println!("Friend's counter: {:?}", counter.value); - /// counter.value += 1; - /// } - /// } - /// # bevy_ecs::system::assert_is_system(system); - /// ``` - /// # See also - /// - /// - [`iter_many_unique`](Self::iter_many_unique) to get read-only query items. - /// - [`iter_many_unique_mut`](Self::iter_many_unique_mut) to get mutable query items. - #[inline] - pub fn iter_many_unique_inner( - self, - entities: EntityList, - ) -> QueryManyUniqueIter<'w, 's, D, F, EntityList::IntoIter> { - // SAFETY: `self.world` has permission to access the required components. - unsafe { - QueryManyUniqueIter::new( - self.world, - self.state, - entities, - self.last_run, - self.this_run, - ) - } - } - /// Returns an [`Iterator`] over the query items. /// /// This iterator is always guaranteed to return results from each matching entity once and only once. @@ -1101,7 +960,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { /// /// - [`iter`](Self::iter) and [`iter_mut`](Self::iter_mut) for the safe versions. #[inline] - pub unsafe fn iter_unsafe(&self) -> QueryIter<'_, 's, D, F> { + pub unsafe fn iter_unsafe(&self) -> QueryIter<'_, '_, D, F> { // SAFETY: The caller promises that this will not result in multiple mutable references. unsafe { self.reborrow_unsafe() }.into_iter() } @@ -1122,7 +981,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { #[inline] pub unsafe fn iter_combinations_unsafe( &self, - ) -> QueryCombinationIter<'_, 's, D, F, K> { + ) -> QueryCombinationIter<'_, '_, D, F, K> { // SAFETY: The caller promises that this will not result in multiple mutable references. unsafe { self.reborrow_unsafe() }.iter_combinations_inner() } @@ -1144,7 +1003,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { pub unsafe fn iter_many_unsafe>( &self, entities: EntityList, - ) -> QueryManyIter<'_, 's, D, F, EntityList::IntoIter> { + ) -> QueryManyIter<'_, '_, D, F, EntityList::IntoIter> { // SAFETY: The caller promises that this will not result in multiple mutable references. unsafe { self.reborrow_unsafe() }.iter_many_inner(entities) } @@ -1166,7 +1025,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { pub unsafe fn iter_many_unique_unsafe( &self, entities: EntityList, - ) -> QueryManyUniqueIter<'_, 's, D, F, EntityList::IntoIter> { + ) -> QueryManyUniqueIter<'_, '_, D, F, EntityList::IntoIter> { // SAFETY: The caller promises that this will not result in multiple mutable references. unsafe { self.reborrow_unsafe() }.iter_many_unique_inner(entities) } @@ -1187,7 +1046,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { /// [`par_iter_mut`]: Self::par_iter_mut /// [`World`]: crate::world::World #[inline] - pub fn par_iter(&self) -> QueryParIter<'_, 's, D::ReadOnly, F> { + pub fn par_iter(&self) -> QueryParIter<'_, '_, D::ReadOnly, F> { self.as_readonly().par_iter_inner() } @@ -1222,47 +1081,10 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { /// [`par_iter`]: Self::par_iter /// [`World`]: crate::world::World #[inline] - pub fn par_iter_mut(&mut self) -> QueryParIter<'_, 's, D, F> { + pub fn par_iter_mut(&mut self) -> QueryParIter<'_, '_, D, F> { self.reborrow().par_iter_inner() } - /// Returns a parallel iterator over the query results for the given [`World`](crate::world::World). - /// This consumes the [`Query`] to return results with the actual "inner" world lifetime. - /// - /// This parallel iterator is always guaranteed to return results from each matching entity once and - /// only once. Iteration order and thread assignment is not guaranteed. - /// - /// If the `multithreaded` feature is disabled, iterating with this operates identically to [`Iterator::for_each`] - /// on [`QueryIter`]. - /// - /// # Example - /// - /// Here, the `gravity_system` updates the `Velocity` component of every entity that contains it: - /// - /// ``` - /// # use bevy_ecs::prelude::*; - /// # - /// # #[derive(Component)] - /// # struct Velocity { x: f32, y: f32, z: f32 } - /// fn gravity_system(query: Query<&mut Velocity>) { - /// const DELTA: f32 = 1.0 / 60.0; - /// query.par_iter_inner().for_each(|mut velocity| { - /// velocity.y -= 9.8 * DELTA; - /// }); - /// } - /// # bevy_ecs::system::assert_is_system(gravity_system); - /// ``` - #[inline] - pub fn par_iter_inner(self) -> QueryParIter<'w, 's, D, F> { - QueryParIter { - world: self.world, - state: self.state, - last_run: self.last_run, - this_run: self.this_run, - batching_strategy: BatchingStrategy::new(), - } - } - /// Returns a parallel iterator over the read-only query items generated from an [`Entity`] list. /// /// Entities that don't match the query are skipped. Iteration order and thread assignment is not guaranteed. @@ -1282,7 +1104,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { pub fn par_iter_many>( &self, entities: EntityList, - ) -> QueryParManyIter<'_, 's, D::ReadOnly, F, EntityList::Item> { + ) -> QueryParManyIter<'_, '_, D::ReadOnly, F, EntityList::Item> { QueryParManyIter { world: self.world, state: self.state.as_readonly(), @@ -1311,7 +1133,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { pub fn par_iter_many_unique>( &self, entities: EntityList, - ) -> QueryParManyUniqueIter<'_, 's, D::ReadOnly, F, EntityList::Item> { + ) -> QueryParManyUniqueIter<'_, '_, D::ReadOnly, F, EntityList::Item> { QueryParManyUniqueIter { world: self.world, state: self.state.as_readonly(), @@ -1340,10 +1162,10 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { pub fn par_iter_many_unique_mut>( &mut self, entities: EntityList, - ) -> QueryParManyUniqueIter<'_, 's, D, F, EntityList::Item> { + ) -> QueryParManyUniqueIter<'_, '_, D, F, EntityList::Item> { QueryParManyUniqueIter { world: self.world, - state: self.state, + state: &self.state, entity_list: entities.into_iter().collect(), last_run: self.last_run, this_run: self.this_run, @@ -1385,7 +1207,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { /// /// - [`get_mut`](Self::get_mut) to get a mutable query item. #[inline] - pub fn get(&self, entity: Entity) -> Result, QueryEntityError> { + pub fn get(&self, entity: Entity) -> Result, QueryEntityError> { self.as_readonly().get_inner(entity) } @@ -1436,7 +1258,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { pub fn get_many( &self, entities: [Entity; N], - ) -> Result<[ROQueryItem<'_, 's, D>; N], QueryEntityError> { + ) -> Result<[ROQueryItem<'_, '_, D>; N], QueryEntityError> { // Note that we call a separate `*_inner` method from `get_many_mut` // because we don't need to check for duplicates. self.as_readonly().get_many_inner(entities) @@ -1487,7 +1309,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { pub fn get_many_unique( &self, entities: UniqueEntityArray, - ) -> Result<[ROQueryItem<'_, 's, D>; N], QueryEntityError> { + ) -> Result<[ROQueryItem<'_, '_, D>; N], QueryEntityError> { self.as_readonly().get_many_unique_inner(entities) } @@ -1521,98 +1343,20 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { /// /// - [`get`](Self::get) to get a read-only query item. #[inline] - pub fn get_mut(&mut self, entity: Entity) -> Result, QueryEntityError> { + pub fn get_mut(&mut self, entity: Entity) -> Result, QueryEntityError> { self.reborrow().get_inner(entity) } - /// Returns the query item for the given [`Entity`]. - /// This consumes the [`Query`] to return results with the actual "inner" world lifetime. + /// Returns the query items for the given array of [`Entity`]. /// - /// In case of a nonexisting entity or mismatched component, a [`QueryEntityError`] is returned instead. + /// The returned query items are in the same order as the input. + /// In case of a nonexisting entity, duplicate entities or mismatched component, a [`QueryEntityError`] is returned instead. /// - /// This is always guaranteed to run in `O(1)` time. + /// # Examples /// - /// # See also - /// - /// - [`get_mut`](Self::get_mut) to get the item using a mutable borrow of the [`Query`]. - #[inline] - pub fn get_inner(self, entity: Entity) -> Result, QueryEntityError> { - // SAFETY: system runs without conflicts with other systems. - // same-system queries have runtime borrow checks when they conflict - unsafe { - let location = self - .world - .entities() - .get(entity) - .ok_or(EntityDoesNotExistError::new(entity, self.world.entities()))?; - if !self - .state - .matched_archetypes - .contains(location.archetype_id.index()) - { - return Err(QueryEntityError::QueryDoesNotMatch( - entity, - location.archetype_id, - )); - } - let archetype = self - .world - .archetypes() - .get(location.archetype_id) - .debug_checked_unwrap(); - let mut fetch = D::init_fetch( - self.world, - &self.state.fetch_state, - self.last_run, - self.this_run, - ); - let mut filter = F::init_fetch( - self.world, - &self.state.filter_state, - self.last_run, - self.this_run, - ); - - let table = self - .world - .storages() - .tables - .get(location.table_id) - .debug_checked_unwrap(); - D::set_archetype(&mut fetch, &self.state.fetch_state, archetype, table); - F::set_archetype(&mut filter, &self.state.filter_state, archetype, table); - - if F::filter_fetch( - &self.state.filter_state, - &mut filter, - entity, - location.table_row, - ) { - Ok(D::fetch( - &self.state.fetch_state, - &mut fetch, - entity, - location.table_row, - )) - } else { - Err(QueryEntityError::QueryDoesNotMatch( - entity, - location.archetype_id, - )) - } - } - } - - /// Returns the query items for the given array of [`Entity`]. - /// - /// The returned query items are in the same order as the input. - /// In case of a nonexisting entity, duplicate entities or mismatched component, a [`QueryEntityError`] is returned instead. - /// - /// # Examples - /// - /// ``` - /// use bevy_ecs::prelude::*; - /// use bevy_ecs::query::QueryEntityError; + /// ``` + /// use bevy_ecs::prelude::*; + /// use bevy_ecs::query::QueryEntityError; /// /// #[derive(Component, PartialEq, Debug)] /// struct A(usize); @@ -1674,7 +1418,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { pub fn get_many_mut( &mut self, entities: [Entity; N], - ) -> Result<[D::Item<'_, 's>; N], QueryEntityError> { + ) -> Result<[D::Item<'_, '_>; N], QueryEntityError> { self.reborrow().get_many_mut_inner(entities) } @@ -1742,103 +1486,9 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { pub fn get_many_unique_mut( &mut self, entities: UniqueEntityArray, - ) -> Result<[D::Item<'_, 's>; N], QueryEntityError> { + ) -> Result<[D::Item<'_, '_>; N], QueryEntityError> { self.reborrow().get_many_unique_inner(entities) } - - /// Returns the query items for the given array of [`Entity`]. - /// This consumes the [`Query`] to return results with the actual "inner" world lifetime. - /// - /// The returned query items are in the same order as the input. - /// In case of a nonexisting entity, duplicate entities or mismatched component, a [`QueryEntityError`] is returned instead. - /// - /// # See also - /// - /// - [`get_many`](Self::get_many) to get read-only query items without checking for duplicate entities. - /// - [`get_many_mut`](Self::get_many_mut) to get items using a mutable reference. - /// - [`get_many_inner`](Self::get_many_mut_inner) to get read-only query items with the actual "inner" world lifetime. - #[inline] - pub fn get_many_mut_inner( - self, - entities: [Entity; N], - ) -> Result<[D::Item<'w, 's>; N], QueryEntityError> { - // Verify that all entities are unique - for i in 0..N { - for j in 0..i { - if entities[i] == entities[j] { - return Err(QueryEntityError::AliasedMutability(entities[i])); - } - } - } - // SAFETY: All entities are unique, so the results don't alias. - unsafe { self.get_many_impl(entities) } - } - - /// Returns the query items for the given array of [`Entity`]. - /// This consumes the [`Query`] to return results with the actual "inner" world lifetime. - /// - /// The returned query items are in the same order as the input. - /// In case of a nonexisting entity or mismatched component, a [`QueryEntityError`] is returned instead. - /// - /// # See also - /// - /// - [`get_many`](Self::get_many) to get read-only query items without checking for duplicate entities. - /// - [`get_many_mut`](Self::get_many_mut) to get items using a mutable reference. - /// - [`get_many_mut_inner`](Self::get_many_mut_inner) to get mutable query items with the actual "inner" world lifetime. - #[inline] - pub fn get_many_inner( - self, - entities: [Entity; N], - ) -> Result<[D::Item<'w, 's>; N], QueryEntityError> - where - D: ReadOnlyQueryData, - { - // SAFETY: The query results are read-only, so they don't conflict if there are duplicate entities. - unsafe { self.get_many_impl(entities) } - } - - /// Returns the query items for the given [`UniqueEntityArray`]. - /// This consumes the [`Query`] to return results with the actual "inner" world lifetime. - /// - /// The returned query items are in the same order as the input. - /// In case of a nonexisting entity, duplicate entities or mismatched component, a [`QueryEntityError`] is returned instead. - /// - /// # See also - /// - /// - [`get_many_unique`](Self::get_many_unique) to get read-only query items without checking for duplicate entities. - /// - [`get_many_unique_mut`](Self::get_many_unique_mut) to get items using a mutable reference. - #[inline] - pub fn get_many_unique_inner( - self, - entities: UniqueEntityArray, - ) -> Result<[D::Item<'w, 's>; N], QueryEntityError> { - // SAFETY: All entities are unique, so the results don't alias. - unsafe { self.get_many_impl(entities.into_inner()) } - } - - /// Returns the query items for the given array of [`Entity`]. - /// This consumes the [`Query`] to return results with the actual "inner" world lifetime. - /// - /// # Safety - /// - /// The caller must ensure that the query data returned for the entities does not conflict, - /// either because they are all unique or because the data is read-only. - unsafe fn get_many_impl( - self, - entities: [Entity; N], - ) -> Result<[D::Item<'w, 's>; N], QueryEntityError> { - let mut values = [(); N].map(|_| MaybeUninit::uninit()); - - for (value, entity) in core::iter::zip(&mut values, entities) { - // SAFETY: The caller asserts that the results don't alias - let item = unsafe { self.copy_unsafe() }.get_inner(entity)?; - *value = MaybeUninit::new(item); - } - - // SAFETY: Each value has been fully initialized. - Ok(values.map(|x| unsafe { x.assume_init() })) - } - /// Returns the query item for the given [`Entity`]. /// /// In case of a nonexisting entity or mismatched component, a [`QueryEntityError`] is returned instead. @@ -1857,7 +1507,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { pub unsafe fn get_unchecked( &self, entity: Entity, - ) -> Result, QueryEntityError> { + ) -> Result, QueryEntityError> { // SAFETY: The caller promises that this will not result in multiple mutable references. unsafe { self.reborrow_unsafe() }.get_inner(entity) } @@ -1893,7 +1543,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { /// /// - [`single_mut`](Self::single_mut) to get the mutable query item. #[inline] - pub fn single(&self) -> Result, QuerySingleError> { + pub fn single(&self) -> Result, QuerySingleError> { self.as_readonly().single_inner() } @@ -1922,52 +1572,10 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { /// /// - [`single`](Self::single) to get the read-only query item. #[inline] - pub fn single_mut(&mut self) -> Result, QuerySingleError> { + pub fn single_mut(&mut self) -> Result, QuerySingleError> { self.reborrow().single_inner() } - /// Returns a single query item when there is exactly one entity matching the query. - /// This consumes the [`Query`] to return results with the actual "inner" world lifetime. - /// - /// If the number of query items is not exactly one, a [`QuerySingleError`] is returned instead. - /// - /// # Example - /// - /// ``` - /// # use bevy_ecs::prelude::*; - /// # - /// # #[derive(Component)] - /// # struct Player; - /// # #[derive(Component)] - /// # struct Health(u32); - /// # - /// fn regenerate_player_health_system(query: Query<&mut Health, With>) { - /// let mut health = query.single_inner().expect("Error: Could not find a single player."); - /// health.0 += 1; - /// } - /// # bevy_ecs::system::assert_is_system(regenerate_player_health_system); - /// ``` - /// - /// # See also - /// - /// - [`single`](Self::single) to get the read-only query item. - /// - [`single_mut`](Self::single_mut) to get the mutable query item. - /// - [`single_inner`](Self::single_inner) for the panicking version. - #[inline] - pub fn single_inner(self) -> Result, QuerySingleError> { - let mut query = self.into_iter(); - let first = query.next(); - let extra = query.next().is_some(); - - match (first, extra) { - (Some(r), false) => Ok(r), - (None, _) => Err(QuerySingleError::NoEntities(DebugName::type_name::())), - (Some(_), _) => Err(QuerySingleError::MultipleEntities(DebugName::type_name::< - Self, - >())), - } - } - /// Returns `true` if there are no query items. /// /// This is equivalent to `self.iter().next().is_none()`, and thus the worst case runtime will be `O(n)` @@ -2110,7 +1718,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { /// # world.spawn((A(10), B(5))); /// # /// fn reusable_function(lens: &mut QueryLens<&A>) { - /// assert_eq!(lens.query().single().unwrap().0, 10); + /// assert_eq!(lens.single().unwrap().0, 10); /// } /// /// // We can use the function in a system that takes the exact query. @@ -2239,7 +1847,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { /// # world.spawn((A(10), B(5))); /// # /// fn reusable_function(mut lens: QueryLens<&A>) { - /// assert_eq!(lens.query().single().unwrap().0, 10); + /// assert_eq!(lens.single().unwrap().0, 10); /// } /// /// // We can use the function in a system that takes the exact query. @@ -2302,12 +1910,10 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { self, ) -> QueryLens<'w, NewD, NewF> { let state = self.state.transmute_filtered::(self.world); - QueryLens { - world: self.world, - state, - last_run: self.last_run, - this_run: self.this_run, - } + // SAFETY: + // - This is memory safe because the original query had compatible access and was consumed. + // - The world matches because it was the same one used to construct self. + unsafe { Query::new(self.world, Box::new(state), self.last_run, self.this_run) } } /// Gets a [`QueryLens`] with the same accesses as the existing query @@ -2356,12 +1962,12 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { /// mut enemies: Query<&Enemy> /// ) { /// let mut players_transforms: QueryLens<(&Transform, &Player)> = transforms.join(&mut players); - /// for (transform, player) in &players_transforms.query() { + /// for (transform, player) in &players_transforms { /// // do something with a and b /// } /// /// let mut enemies_transforms: QueryLens<(&Transform, &Enemy)> = transforms.join(&mut enemies); - /// for (transform, enemy) in &enemies_transforms.query() { + /// for (transform, enemy) in &enemies_transforms { /// // do something with a and b /// } /// } @@ -2456,98 +2062,502 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { let state = self .state .join_filtered::(self.world, other.state); - QueryLens { - world: self.world, - state, - last_run: self.last_run, - this_run: self.this_run, - } - } -} - -impl<'w, 's, D: QueryData, F: QueryFilter> IntoIterator for Query<'w, 's, D, F> { - type Item = D::Item<'w, 's>; - type IntoIter = QueryIter<'w, 's, D, F>; - - fn into_iter(self) -> Self::IntoIter { // SAFETY: - // - `self.world` has permission to access the required components. - // - We consume the query, so mutable queries cannot alias. - // Read-only queries are `Copy`, but may alias themselves. - unsafe { QueryIter::new(self.world, self.state, self.last_run, self.this_run) } - } -} - -impl<'w, 's, D: QueryData, F: QueryFilter> IntoIterator for &'w Query<'_, 's, D, F> { - type Item = ROQueryItem<'w, 's, D>; - type IntoIter = QueryIter<'w, 's, D::ReadOnly, F>; - - fn into_iter(self) -> Self::IntoIter { - self.iter() + // - This is memory safe because the original query had compatible access and was consumed. + // - The world matches because it was the same one used to construct self. + unsafe { Query::new(self.world, Box::new(state), self.last_run, self.this_run) } } } -impl<'w, 's, D: QueryData, F: QueryFilter> IntoIterator for &'w mut Query<'_, 's, D, F> { - type Item = D::Item<'w, 's>; - type IntoIter = QueryIter<'w, 's, D, F>; - - fn into_iter(self) -> Self::IntoIter { - self.iter_mut() +impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { + /// Returns another `Query` from this that fetches the read-only version of the query items. + /// + /// For example, `Query<(&mut D1, &D2, &mut D3), With>` will become `Query<(&D1, &D2, &D3), With>`. + /// This can be useful when working around the borrow checker, + /// or reusing functionality between systems via functions that accept query types. + /// + /// # See also + /// + /// [`as_readonly`](Self::as_readonly) for a version that borrows the `Query` instead of consuming it. + pub fn into_readonly(self) -> Query<'w, 's, D::ReadOnly, F> { + let new_state = self.state.as_readonly(); + // SAFETY: + // - This is memory safe because it turns the query immutable. + // - The world matches because it was the same one used to construct self. + unsafe { Query::new(self.world, new_state, self.last_run, self.this_run) } } -} -impl<'w, 's, D: ReadOnlyQueryData, F: QueryFilter> Query<'w, 's, D, F> { - /// Returns an [`Iterator`] over the query items, with the actual "inner" world lifetime. + /// Returns a [`QueryCombinationIter`] over all combinations of `K` query items without repetition. + /// This consumes the [`Query`] to return results with the actual "inner" world lifetime. /// - /// This can only return immutable data (mutable data will be cast to an immutable form). - /// See [`Self::iter_mut`] for queries that contain at least one mutable component. + /// This iterator is always guaranteed to return results from each unique pair of matching entities. + /// Iteration order is not guaranteed. /// /// # Example /// - /// Here, the `report_names_system` iterates over the `Player` component of every entity - /// that contains it: - /// /// ``` /// # use bevy_ecs::prelude::*; - /// # /// # #[derive(Component)] - /// # struct Player { name: String } - /// # - /// fn report_names_system(query: Query<&Player>) { - /// for player in &query { - /// println!("Say hello to {}!", player.name); + /// # struct ComponentA; + /// fn some_system(query: Query<&mut ComponentA>) { + /// let mut combinations = query.iter_combinations_inner(); + /// while let Some([mut a1, mut a2]) = combinations.fetch_next() { + /// // mutably access components data /// } /// } - /// # bevy_ecs::system::assert_is_system(report_names_system); /// ``` + /// + /// # See also + /// + /// - [`iter_combinations`](Self::iter_combinations) for read-only query item combinations. + /// - [`iter_combinations_mut`](Self::iter_combinations_mut) for mutable query item combinations. #[inline] - pub fn iter_inner(&self) -> QueryIter<'w, 's, D::ReadOnly, F> { - (*self).into_iter() + pub fn iter_combinations_inner(self) -> QueryCombinationIter<'w, 's, D, F, K> { + // SAFETY: `self.world` has permission to access the required components. + unsafe { QueryCombinationIter::new(self.world, self.state, self.last_run, self.this_run) } } -} - -/// Type returned from [`Query::transmute_lens`] containing the new [`QueryState`]. -/// -/// Call [`query`](QueryLens::query) or [`into`](Into::into) to construct the resulting [`Query`] -pub struct QueryLens<'w, Q: QueryData, F: QueryFilter = ()> { - world: UnsafeWorldCell<'w>, - state: QueryState, - last_run: Tick, - this_run: Tick, -} -impl<'w, Q: QueryData, F: QueryFilter> QueryLens<'w, Q, F> { - /// Create a [`Query`] from the underlying [`QueryState`]. - pub fn query(&mut self) -> Query<'_, '_, Q, F> { - Query { + /// Returns an iterator over the query items generated from an [`Entity`] list. + /// This consumes the [`Query`] to return results with the actual "inner" world lifetime. + /// + /// Items are returned in the order of the list of entities, and may not be unique if the input + /// doesn't guarantee uniqueness. Entities that don't match the query are skipped. + /// + /// # See also + /// + /// - [`iter_many`](Self::iter_many) to get read-only query items. + /// - [`iter_many_mut`](Self::iter_many_mut) to get mutable query items. + #[inline] + pub fn iter_many_inner>( + self, + entities: EntityList, + ) -> QueryManyIter<'w, 's, D, F, EntityList::IntoIter> { + // SAFETY: `self.world` has permission to access the required components. + unsafe { + QueryManyIter::new( + self.world, + self.state, + entities, + self.last_run, + self.this_run, + ) + } + } + + /// Returns an iterator over the unique query items generated from an [`EntitySet`]. + /// This consumes the [`Query`] to return results with the actual "inner" world lifetime. + /// + /// Items are returned in the order of the list of entities. Entities that don't match the query are skipped. + /// + /// # Examples + /// + /// ``` + /// # use bevy_ecs::{prelude::*, entity::{EntitySet, UniqueEntityIter}}; + /// # use core::slice; + /// #[derive(Component)] + /// struct Counter { + /// value: i32 + /// } + /// + /// // `Friends` ensures that it only lists unique entities. + /// #[derive(Component)] + /// struct Friends { + /// unique_list: Vec, + /// } + /// + /// impl<'a> IntoIterator for &'a Friends { + /// type Item = &'a Entity; + /// type IntoIter = UniqueEntityIter>; + /// + /// fn into_iter(self) -> Self::IntoIter { + /// // SAFETY: `Friends` ensures that it unique_list contains only unique entities. + /// unsafe { UniqueEntityIter::from_iterator_unchecked(self.unique_list.iter()) } + /// } + /// } + /// + /// fn system( + /// friends_query: Query<&Friends>, + /// mut counter_query: Query<&mut Counter>, + /// ) { + /// let friends = friends_query.single().unwrap(); + /// for mut counter in counter_query.iter_many_unique_inner(friends) { + /// println!("Friend's counter: {:?}", counter.value); + /// counter.value += 1; + /// } + /// } + /// # bevy_ecs::system::assert_is_system(system); + /// ``` + /// # See also + /// + /// - [`iter_many_unique`](Self::iter_many_unique) to get read-only query items. + /// - [`iter_many_unique_mut`](Self::iter_many_unique_mut) to get mutable query items. + #[inline] + pub fn iter_many_unique_inner( + self, + entities: EntityList, + ) -> QueryManyUniqueIter<'w, 's, D, F, EntityList::IntoIter> { + // SAFETY: `self.world` has permission to access the required components. + unsafe { + QueryManyUniqueIter::new( + self.world, + self.state, + entities, + self.last_run, + self.this_run, + ) + } + } + + /// Returns a parallel iterator over the query results for the given [`World`](crate::world::World). + /// This consumes the [`Query`] to return results with the actual "inner" world lifetime. + /// + /// This parallel iterator is always guaranteed to return results from each matching entity once and + /// only once. Iteration order and thread assignment is not guaranteed. + /// + /// If the `multithreaded` feature is disabled, iterating with this operates identically to [`Iterator::for_each`] + /// on [`QueryIter`]. + /// + /// # Example + /// + /// Here, the `gravity_system` updates the `Velocity` component of every entity that contains it: + /// + /// ``` + /// # use bevy_ecs::prelude::*; + /// # + /// # #[derive(Component)] + /// # struct Velocity { x: f32, y: f32, z: f32 } + /// fn gravity_system(query: Query<&mut Velocity>) { + /// const DELTA: f32 = 1.0 / 60.0; + /// query.par_iter_inner().for_each(|mut velocity| { + /// velocity.y -= 9.8 * DELTA; + /// }); + /// } + /// # bevy_ecs::system::assert_is_system(gravity_system); + /// ``` + #[inline] + pub fn par_iter_inner(self) -> QueryParIter<'w, 's, D, F> { + QueryParIter { world: self.world, - state: &self.state, + state: self.state, last_run: self.last_run, this_run: self.this_run, + batching_strategy: BatchingStrategy::new(), + } + } + + /// Returns the query item for the given [`Entity`]. + /// This consumes the [`Query`] to return results with the actual "inner" world lifetime. + /// + /// In case of a nonexisting entity or mismatched component, a [`QueryEntityError`] is returned instead. + /// + /// This is always guaranteed to run in `O(1)` time. + /// + /// # See also + /// + /// - [`get_mut`](Self::get_mut) to get the item using a mutable borrow of the [`Query`]. + #[inline] + pub fn get_inner(self, entity: Entity) -> Result, QueryEntityError> { + // SAFETY: This query has access to this item, + // and we consume the query so it is never used again. + unsafe { self.get_unchecked_inner(entity) } + } + + /// Returns the query item for the given [`Entity`]. + /// + /// This is similar to [`Self::get_unchecked`], but returns results with the actual "inner" world lifetime. + /// + /// # Safety + /// + /// This function makes it possible to violate Rust's aliasing guarantees. + /// You must make sure this call does not result in multiple mutable references to the same component. + #[inline] + unsafe fn get_unchecked_inner( + &self, + entity: Entity, + ) -> Result, QueryEntityError> { + // SAFETY: system runs without conflicts with other systems. + // same-system queries have runtime borrow checks when they conflict + unsafe { + let location = self + .world + .entities() + .get(entity) + .ok_or(EntityDoesNotExistError::new(entity, self.world.entities()))?; + if !self + .state + .matched_archetypes + .contains(location.archetype_id.index()) + { + return Err(QueryEntityError::QueryDoesNotMatch( + entity, + location.archetype_id, + )); + } + let archetype = self + .world + .archetypes() + .get(location.archetype_id) + .debug_checked_unwrap(); + let mut fetch = D::init_fetch( + self.world, + &self.state.fetch_state, + self.last_run, + self.this_run, + ); + let mut filter = F::init_fetch( + self.world, + &self.state.filter_state, + self.last_run, + self.this_run, + ); + + let table = self + .world + .storages() + .tables + .get(location.table_id) + .debug_checked_unwrap(); + D::set_archetype(&mut fetch, &self.state.fetch_state, archetype, table); + F::set_archetype(&mut filter, &self.state.filter_state, archetype, table); + + if F::filter_fetch( + &self.state.filter_state, + &mut filter, + entity, + location.table_row, + ) { + Ok(D::fetch( + &self.state.fetch_state, + &mut fetch, + entity, + location.table_row, + )) + } else { + Err(QueryEntityError::QueryDoesNotMatch( + entity, + location.archetype_id, + )) + } + } + } + + /// Returns the query items for the given array of [`Entity`]. + /// This consumes the [`Query`] to return results with the actual "inner" world lifetime. + /// + /// The returned query items are in the same order as the input. + /// In case of a nonexisting entity, duplicate entities or mismatched component, a [`QueryEntityError`] is returned instead. + /// + /// # See also + /// + /// - [`get_many`](Self::get_many) to get read-only query items without checking for duplicate entities. + /// - [`get_many_mut`](Self::get_many_mut) to get items using a mutable reference. + /// - [`get_many_inner`](Self::get_many_mut_inner) to get read-only query items with the actual "inner" world lifetime. + #[inline] + pub fn get_many_mut_inner( + self, + entities: [Entity; N], + ) -> Result<[D::Item<'w, 's>; N], QueryEntityError> { + // Verify that all entities are unique + for i in 0..N { + for j in 0..i { + if entities[i] == entities[j] { + return Err(QueryEntityError::AliasedMutability(entities[i])); + } + } + } + // SAFETY: All entities are unique, so the results don't alias. + unsafe { self.get_many_impl(entities) } + } + + /// Returns the query items for the given array of [`Entity`]. + /// This consumes the [`Query`] to return results with the actual "inner" world lifetime. + /// + /// The returned query items are in the same order as the input. + /// In case of a nonexisting entity or mismatched component, a [`QueryEntityError`] is returned instead. + /// + /// # See also + /// + /// - [`get_many`](Self::get_many) to get read-only query items without checking for duplicate entities. + /// - [`get_many_mut`](Self::get_many_mut) to get items using a mutable reference. + /// - [`get_many_mut_inner`](Self::get_many_mut_inner) to get mutable query items with the actual "inner" world lifetime. + #[inline] + pub fn get_many_inner( + self, + entities: [Entity; N], + ) -> Result<[D::Item<'w, 's>; N], QueryEntityError> + where + D: ReadOnlyQueryData, + { + // SAFETY: The query results are read-only, so they don't conflict if there are duplicate entities. + unsafe { self.get_many_impl(entities) } + } + + /// Returns the query items for the given [`UniqueEntityArray`]. + /// This consumes the [`Query`] to return results with the actual "inner" world lifetime. + /// + /// The returned query items are in the same order as the input. + /// In case of a nonexisting entity, duplicate entities or mismatched component, a [`QueryEntityError`] is returned instead. + /// + /// # See also + /// + /// - [`get_many_unique`](Self::get_many_unique) to get read-only query items without checking for duplicate entities. + /// - [`get_many_unique_mut`](Self::get_many_unique_mut) to get items using a mutable reference. + #[inline] + pub fn get_many_unique_inner( + self, + entities: UniqueEntityArray, + ) -> Result<[D::Item<'w, 's>; N], QueryEntityError> { + // SAFETY: All entities are unique, so the results don't alias. + unsafe { self.get_many_impl(entities.into_inner()) } + } + + /// Returns the query items for the given array of [`Entity`]. + /// This consumes the [`Query`] to return results with the actual "inner" world lifetime. + /// + /// # Safety + /// + /// The caller must ensure that the query data returned for the entities does not conflict, + /// either because they are all unique or because the data is read-only. + unsafe fn get_many_impl( + self, + entities: [Entity; N], + ) -> Result<[D::Item<'w, 's>; N], QueryEntityError> { + let mut values = [(); N].map(|_| MaybeUninit::uninit()); + + for (value, entity) in core::iter::zip(&mut values, entities) { + // SAFETY: The caller asserts that the results don't alias + let item = unsafe { self.get_unchecked_inner(entity)? }; + *value = MaybeUninit::new(item); + } + + // SAFETY: Each value has been fully initialized. + Ok(values.map(|x| unsafe { x.assume_init() })) + } + + /// Returns a single query item when there is exactly one entity matching the query. + /// This consumes the [`Query`] to return results with the actual "inner" world lifetime. + /// + /// If the number of query items is not exactly one, a [`QuerySingleError`] is returned instead. + /// + /// # Example + /// + /// ``` + /// # use bevy_ecs::prelude::*; + /// # + /// # #[derive(Component)] + /// # struct Player; + /// # #[derive(Component)] + /// # struct Health(u32); + /// # + /// fn regenerate_player_health_system(query: Query<&mut Health, With>) { + /// let mut health = query.single_inner().expect("Error: Could not find a single player."); + /// health.0 += 1; + /// } + /// # bevy_ecs::system::assert_is_system(regenerate_player_health_system); + /// ``` + /// + /// # See also + /// + /// - [`single`](Self::single) to get the read-only query item. + /// - [`single_mut`](Self::single_mut) to get the mutable query item. + /// - [`single_inner`](Self::single_inner) for the panicking version. + #[inline] + pub fn single_inner(self) -> Result, QuerySingleError> { + let mut query = self.into_iter(); + let first = query.next(); + let extra = query.next().is_some(); + + match (first, extra) { + (Some(r), false) => Ok(r), + (None, _) => Err(QuerySingleError::NoEntities(DebugName::type_name::())), + (Some(_), _) => Err(QuerySingleError::MultipleEntities(DebugName::type_name::< + Self, + >())), } } } +impl<'w, 's, D: QueryData, F: QueryFilter> IntoIterator for Query<'w, 's, D, F> { + type Item = D::Item<'w, 's>; + type IntoIter = QueryIter<'w, 's, D, F>; + + fn into_iter(self) -> Self::IntoIter { + // SAFETY: + // - `self.world` has permission to access the required components. + // - We consume the query, so mutable queries cannot alias. + // Read-only queries are `Copy`, but may alias themselves. + unsafe { QueryIter::new(self.world, self.state, self.last_run, self.this_run) } + } +} + +impl<'w, D: QueryData, F: QueryFilter, S: Deref>> IntoIterator + for &'w Query<'_, '_, D, F, S> +{ + type Item = ROQueryItem<'w, 'w, D>; + type IntoIter = QueryIter<'w, 'w, D::ReadOnly, F>; + + fn into_iter(self) -> Self::IntoIter { + self.iter() + } +} + +impl<'w, D: QueryData, F: QueryFilter, S: Deref>> IntoIterator + for &'w mut Query<'_, '_, D, F, S> +{ + type Item = D::Item<'w, 'w>; + type IntoIter = QueryIter<'w, 'w, D, F>; + + fn into_iter(self) -> Self::IntoIter { + self.iter_mut() + } +} + +impl<'w, 's, D: ReadOnlyQueryData, F: QueryFilter> Query<'w, 's, D, F> { + /// Returns an [`Iterator`] over the query items, with the actual "inner" world lifetime. + /// + /// This can only return immutable data (mutable data will be cast to an immutable form). + /// See [`Self::iter_mut`] for queries that contain at least one mutable component. + /// + /// # Example + /// + /// Here, the `report_names_system` iterates over the `Player` component of every entity + /// that contains it: + /// + /// ``` + /// # use bevy_ecs::prelude::*; + /// # + /// # #[derive(Component)] + /// # struct Player { name: String } + /// # + /// fn report_names_system(query: Query<&Player>) { + /// for player in &query { + /// println!("Say hello to {}!", player.name); + /// } + /// } + /// # bevy_ecs::system::assert_is_system(report_names_system); + /// ``` + #[inline] + pub fn iter_inner(&self) -> QueryIter<'w, 's, D::ReadOnly, F> { + (*self).into_iter() + } +} + +/// A [`Query`] with an owned [`QueryState`]. +/// +/// This is returned from methods like [`Query::transmute_lens`] that construct a fresh [`QueryState`]. +pub type QueryLens<'w, Q, F = ()> = Query<'w, 'static, Q, F, Box>>; + +impl<'w, Q: QueryData, F: QueryFilter> QueryLens<'w, Q, F> { + /// Create a [`Query`] from the underlying [`QueryState`]. + #[deprecated( + since = "0.17.0", + note = "This can usually be removed, since `QueryLens` supports all methods from `Query`. If you need to consume the resulting `Query`, call `reborrow()` instead." + )] + pub fn query(&mut self) -> Query<'_, '_, Q, F> { + self.reborrow() + } +} + impl<'w, Q: ReadOnlyQueryData, F: QueryFilter> QueryLens<'w, Q, F> { /// Create a [`Query`] from the underlying [`QueryState`]. /// This returns results with the actual "inner" world lifetime, @@ -2558,6 +2568,7 @@ impl<'w, Q: ReadOnlyQueryData, F: QueryFilter> QueryLens<'w, Q, F> { state: &self.state, last_run: self.last_run, this_run: self.this_run, + marker: PhantomData, } } } @@ -2566,7 +2577,7 @@ impl<'w, 's, Q: QueryData, F: QueryFilter> From<&'s mut QueryLens<'w, Q, F>> for Query<'s, 's, Q, F> { fn from(value: &'s mut QueryLens<'w, Q, F>) -> Query<'s, 's, Q, F> { - value.query() + value.reborrow() } } diff --git a/release-content/migration-guides/combine_query_and_query_lens.md b/release-content/migration-guides/combine_query_and_query_lens.md new file mode 100644 index 0000000000000..ddf22d41aae2a --- /dev/null +++ b/release-content/migration-guides/combine_query_and_query_lens.md @@ -0,0 +1,20 @@ +--- +title: Combine `Query` and `QueryLens` +pull_requests: [18162] +--- + +The `QueryLens::query()` method has been deprecated. +The `QueryLens` type has now been combined with `Query`, so most methods can be called directly on the `QueryLens` and the call can simply be removed. +If that doesn't work and you do need a fresh `Query`, the call to `.query()` can be replaced with `.reborrow()`. + +```rust +fn with_query(query: Query<&T>) {} +fn with_lens(lens: QueryLens<&T>) -> Result { + // 0.16 + for item in lens.query().iter() {} + with_query(lens.query()); + // 0.17 + for item in lens.iter() {} + with_query(lens.reborrow()); +} +```