diff --git a/crates/bevy_ecs/src/query/state.rs b/crates/bevy_ecs/src/query/state.rs index 79ecf09b20176..54321643fabb1 100644 --- a/crates/bevy_ecs/src/query/state.rs +++ b/crates/bevy_ecs/src/query/state.rs @@ -14,9 +14,9 @@ use crate::{ #[cfg(all(not(target_arch = "wasm32"), feature = "multi_threaded"))] use crate::entity::UniqueEntityEquivalentSlice; -use alloc::vec::Vec; +use alloc::{boxed::Box, vec::Vec}; use bevy_utils::prelude::DebugName; -use core::{fmt, ptr}; +use core::{fmt, ops::Deref, ptr}; use fixedbitset::FixedBitSet; use log::warn; #[cfg(feature = "trace")] @@ -89,6 +89,30 @@ pub struct QueryState { par_iter_span: Span, } +/// Indicates how the internal state of a [`Query`] is stored. +pub trait QueryType { + /// The type used to store the internal state of a [`Query`]. + type QueryState<'s, D: QueryData + 's, F: QueryFilter + 's>: Deref>; +} + +/// A [`Query`] that holds a shared borrow of its internal state. +/// +/// This is the default [`QueryType`] for a [`Query`], and is used by [system parameters](crate::system::SystemParam). +pub struct BorrowedQuery; + +impl QueryType for BorrowedQuery { + type QueryState<'s, D: QueryData + 's, F: QueryFilter + 's> = &'s QueryState; +} + +/// A [`Query`] that owns its internal state. +/// +/// This is the [`QueryType`] for a [`QueryLens`](crate::system::QueryLens). +pub struct OwnedQuery; + +impl QueryType for OwnedQuery { + type QueryState<'s, D: QueryData + 's, F: QueryFilter + 's> = Box>; +} + impl fmt::Debug for QueryState { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("QueryState") @@ -2043,7 +2067,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(); } @@ -2222,7 +2246,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..510e7ef985541 100644 --- a/crates/bevy_ecs/src/relationship/relationship_query.rs +++ b/crates/bevy_ecs/src/relationship/relationship_query.rs @@ -1,6 +1,6 @@ use crate::{ entity::Entity, - query::{QueryData, QueryFilter}, + query::{QueryData, QueryFilter, QueryType}, relationship::{Relationship, RelationshipTarget}, system::Query, }; @@ -9,12 +9,12 @@ 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, T: QueryType> Query<'w, 's, D, F, T> { /// 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() } @@ -26,7 +26,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { entity: Entity, ) -> impl Iterator + 'w where - ::ReadOnly: QueryData = &'w S>, + D::ReadOnly: QueryData = &'w S>, { self.get(entity) .into_iter() @@ -42,7 +42,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) { @@ -60,9 +60,9 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { pub fn iter_leaves( &'w self, entity: Entity, - ) -> impl Iterator + use<'w, 's, S, D, F> + ) -> impl Iterator + use<'w, 's, S, D, F, T> where - ::ReadOnly: QueryData = &'w S>, + D::ReadOnly: QueryData = &'w S>, SourceIter<'w, S>: DoubleEndedIterator, { self.iter_descendants_depth_first(entity).filter(|entity| { @@ -80,7 +80,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() @@ -101,9 +101,9 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { pub fn iter_descendants( &'w self, entity: Entity, - ) -> DescendantIter<'w, 's, D, F, S> + ) -> DescendantIter<'w, 's, D, F, T, S> where - D::ReadOnly: QueryData = &'w S>, + D::ReadOnly: QueryData = &'w S>, { DescendantIter::new(self, entity) } @@ -118,9 +118,9 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { pub fn iter_descendants_depth_first( &'w self, entity: Entity, - ) -> DescendantDepthFirstIter<'w, 's, D, F, S> + ) -> DescendantDepthFirstIter<'w, 's, D, F, T, S> where - D::ReadOnly: QueryData = &'w S>, + D::ReadOnly: QueryData = &'w S>, SourceIter<'w, S>: DoubleEndedIterator, { DescendantDepthFirstIter::new(self, entity) @@ -135,9 +135,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, T, R> where - D::ReadOnly: QueryData = &'w R>, + D::ReadOnly: QueryData = &'w R>, { AncestorIter::new(self, entity) } @@ -146,20 +146,21 @@ 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> +pub struct DescendantIter<'w, 's, D: QueryData, F: QueryFilter, T: QueryType, S: RelationshipTarget> where - D::ReadOnly: QueryData = &'w S>, + D::ReadOnly: QueryData = &'w S>, { - children_query: &'w Query<'w, 's, D, F>, + children_query: &'w Query<'w, 's, D, F, T>, vecdeque: VecDeque, } -impl<'w, 's, D: QueryData, F: QueryFilter, S: RelationshipTarget> DescendantIter<'w, 's, D, F, S> +impl<'w, 's, D: QueryData, F: QueryFilter, T: QueryType, S: RelationshipTarget> + DescendantIter<'w, 's, D, F, T, S> where - D::ReadOnly: QueryData = &'w S>, + D::ReadOnly: QueryData = &'w S>, { /// 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, T>, entity: Entity) -> Self { DescendantIter { children_query, vecdeque: children_query @@ -171,10 +172,10 @@ 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, T: QueryType, S: RelationshipTarget> Iterator + for DescendantIter<'w, 's, D, F, T, S> where - D::ReadOnly: QueryData = &'w S>, + D::ReadOnly: QueryData = &'w S>, { type Item = Entity; @@ -192,22 +193,28 @@ 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, + T: QueryType, + S: RelationshipTarget, +> where + D::ReadOnly: QueryData = &'w S>, { - children_query: &'w Query<'w, 's, D, F>, + children_query: &'w Query<'w, 's, D, F, T>, 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, T: QueryType, S: RelationshipTarget> + DescendantDepthFirstIter<'w, 's, D, F, T, S> where - D::ReadOnly: QueryData = &'w S>, + D::ReadOnly: QueryData = &'w S>, SourceIter<'w, S>: 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, T>, entity: Entity) -> Self { DescendantDepthFirstIter { children_query, stack: children_query @@ -217,10 +224,10 @@ 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, T: QueryType, S: RelationshipTarget> Iterator + for DescendantDepthFirstIter<'w, 's, D, F, T, S> where - D::ReadOnly: QueryData = &'w S>, + D::ReadOnly: QueryData = &'w S>, SourceIter<'w, S>: DoubleEndedIterator, { type Item = Entity; @@ -237,20 +244,21 @@ where } /// An [`Iterator`] of [`Entity`]s over the ancestors of an [`Entity`]. -pub struct AncestorIter<'w, 's, D: QueryData, F: QueryFilter, R: Relationship> +pub struct AncestorIter<'w, 's, D: QueryData, F: QueryFilter, T: QueryType, R: Relationship> where - D::ReadOnly: QueryData = &'w R>, + D::ReadOnly: QueryData = &'w R>, { - parent_query: &'w Query<'w, 's, D, F>, + parent_query: &'w Query<'w, 's, D, F, T>, next: Option, } -impl<'w, 's, D: QueryData, F: QueryFilter, R: Relationship> AncestorIter<'w, 's, D, F, R> +impl<'w, 's, D: QueryData, F: QueryFilter, T: QueryType, R: Relationship> + AncestorIter<'w, 's, D, F, T, 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, T>, entity: Entity) -> Self { AncestorIter { parent_query, next: Some(entity), @@ -258,10 +266,10 @@ 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, T: QueryType, R: Relationship> Iterator + for AncestorIter<'w, 's, D, F, T, 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 b8c29d448adbf..4360687897539 100644 --- a/crates/bevy_ecs/src/system/query.rs +++ b/crates/bevy_ecs/src/system/query.rs @@ -5,12 +5,14 @@ use crate::{ change_detection::Tick, entity::{Entity, EntityEquivalent, EntitySet, UniqueEntityArray}, query::{ - DebugCheckedUnwrap, NopWorldQuery, QueryCombinationIter, QueryData, QueryEntityError, - QueryFilter, QueryIter, QueryManyIter, QueryManyUniqueIter, QueryParIter, QueryParManyIter, - QueryParManyUniqueIter, QuerySingleError, QueryState, ROQueryItem, ReadOnlyQueryData, + BorrowedQuery, DebugCheckedUnwrap, NopWorldQuery, OwnedQuery, QueryCombinationIter, + QueryData, QueryEntityError, QueryFilter, QueryIter, QueryManyIter, QueryManyUniqueIter, + QueryParIter, QueryParManyIter, QueryParManyUniqueIter, QuerySingleError, QueryState, + QueryType, ROQueryItem, ReadOnlyQueryData, }, world::unsafe_world_cell::UnsafeWorldCell, }; +use alloc::boxed::Box; use core::{ marker::PhantomData, mem::MaybeUninit, @@ -22,7 +24,7 @@ use core::{ /// Queries enable systems to access [entity identifiers] and [components] without requiring direct access to the [`World`]. /// Its iterators and getter methods return *query items*, which are types containing data related to an entity. /// -/// `Query` is a generic data structure that accepts two type parameters: +/// `Query` is a generic data structure that accepts three type parameters: /// /// - **`D` (query data)**: /// The type of data fetched by the query, which will be returned as the query item. @@ -32,6 +34,11 @@ use core::{ /// An optional set of conditions that determine whether query items should be kept or discarded. /// This defaults to [`unit`], which means no additional filters will be applied. /// Must implement the [`QueryFilter`] trait. +/// - **`T` (query type)**: +/// An optional type that indicates how the internal state of the query is stored. +/// For the query to be a system parameter, this must be the default of [`BorrowedQuery`]. +/// That stores the state along with the system, and borrows from it when running. +/// For cases where a query needs to contain an owned state, use the [`QueryLens`] type alias. /// /// [system parameter]: crate::system::SystemParam /// [`Component`]: crate::component::Component @@ -482,12 +489,15 @@ use core::{ /// ``` /// /// [autovectorization]: https://en.wikipedia.org/wiki/Automatic_vectorization -pub struct Query<'world, 'state, D: QueryData, F: QueryFilter = ()> { +pub struct Query<'world, 'state, D: QueryData, F: QueryFilter = (), T: QueryType = BorrowedQuery> { // SAFETY: Must have access to the components registered in `state`. world: UnsafeWorldCell<'world>, - state: &'state QueryState, + state: T::QueryState<'state, D, F>, last_run: Tick, this_run: Tick, + // This `PhantomData` creates implied bounds that `D: 'state` and `F: 'state`, + // making `T::QueryState<'state, D, F>` a valid type without needing explicit bounds + marker: PhantomData<&'state QueryState>, } impl Clone for Query<'_, '_, D, F> { @@ -510,7 +520,7 @@ 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, T: QueryType> Query<'w, 's, D, F, T> { /// Creates a new query. /// /// # Safety @@ -521,7 +531,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: T::QueryState<'s, D, F>, last_run: Tick, this_run: Tick, ) -> Self { @@ -530,6 +540,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { state, last_run, this_run, + marker: PhantomData, } } @@ -542,7 +553,7 @@ 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() @@ -552,7 +563,7 @@ impl<'w, 's, D: QueryData, F: QueryFilter> Query<'w, 's, D, F> { /// /// The resulting query will ignore any non-archetypal filters in `D`, /// so this is only equivalent if `D::IS_ARCHETYPAL` is `true`. - 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, @@ -563,23 +574,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. /// @@ -604,7 +598,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() } @@ -621,29 +615,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. @@ -673,7 +649,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() } @@ -704,7 +680,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() } @@ -734,7 +710,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() } @@ -764,40 +740,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 @@ -839,7 +785,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) } @@ -884,37 +830,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. @@ -967,7 +886,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) } @@ -1022,74 +941,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. @@ -1104,7 +959,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() } @@ -1125,7 +980,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() } @@ -1147,7 +1002,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) } @@ -1169,7 +1024,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) } @@ -1190,7 +1045,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() } @@ -1225,47 +1080,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. @@ -1285,7 +1103,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(), @@ -1314,7 +1132,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(), @@ -1343,10 +1161,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, @@ -1388,7 +1206,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) } @@ -1439,7 +1257,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) @@ -1490,7 +1308,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) } @@ -1524,94 +1342,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_spawned(entity)?; - 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, - ) && let Some(item) = D::fetch( - &self.state.fetch_state, - &mut fetch, - entity, - location.table_row, - ) { - Ok(item) - } 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); @@ -1673,7 +1417,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) } @@ -1741,103 +1485,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. @@ -1856,7 +1506,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) } @@ -1892,7 +1542,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() } @@ -1921,51 +1571,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. - #[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)` @@ -2157,7 +1766,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. @@ -2286,7 +1895,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. @@ -2349,12 +1958,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 @@ -2403,12 +2010,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 /// } /// } @@ -2503,95 +2110,494 @@ 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 { - world: self.world, - state: &self.state, + /// 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, 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_spawned(entity)?; + 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, + ) && let Some(item) = D::fetch( + &self.state.fetch_state, + &mut fetch, + entity, + location.table_row, + ) { + Ok(item) + } 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. + #[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, T: QueryType> IntoIterator for &'w Query<'_, '_, D, F, T> { + 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, T: QueryType> IntoIterator + for &'w mut Query<'_, '_, D, F, T> +{ + 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`]. +// The `'state` lifetime is ignored by `OwnedQuery`, but `Query` still requires `D` and `F` outlive it. +// Using `'w` here allows `as_query_lens()` to work for all source queries, since `D: 'w`. +pub type QueryLens<'w, Q, F = ()> = Query<'w, 'w, Q, F, OwnedQuery>; + +impl<'w, Q: QueryData, F: QueryFilter> QueryLens<'w, Q, F> { + /// Create a [`Query`] from the underlying [`QueryState`]. + #[deprecated( + since = "0.18.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() } } @@ -2605,6 +2611,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, } } } @@ -2613,7 +2620,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/crates/bevy_text/src/text_access.rs b/crates/bevy_text/src/text_access.rs index 9d04c1dbb5da8..cb4de4ddccbc4 100644 --- a/crates/bevy_text/src/text_access.rs +++ b/crates/bevy_text/src/text_access.rs @@ -77,7 +77,7 @@ pub struct TextReader<'w, 's, R: TextRoot> { impl<'w, 's, R: TextRoot> TextReader<'w, 's, R> { /// Returns an iterator over text spans in a text block, starting with the root entity. - pub fn iter(&mut self, root_entity: Entity) -> TextSpanIter<'_, R> { + pub fn iter(&mut self, root_entity: Entity) -> TextSpanIter<'_, 's, R> { let stack = self.scratch.take(); TextSpanIter { @@ -154,14 +154,14 @@ impl<'w, 's, R: TextRoot> TextReader<'w, 's, R> { /// Iterates all spans in a text block according to hierarchy traversal order. /// Does *not* flatten interspersed ghost nodes. Only contiguous spans are traversed. // TODO: Use this iterator design in UiChildrenIter to reduce allocations. -pub struct TextSpanIter<'a, R: TextRoot> { +pub struct TextSpanIter<'a, 's, R: TextRoot> { scratch: &'a mut TextIterScratch, root_entity: Option, /// Stack of (children, next index into children). stack: Vec<(&'a Children, usize)>, roots: &'a Query< 'a, - 'a, + 's, ( &'static R, &'static TextFont, @@ -172,7 +172,7 @@ pub struct TextSpanIter<'a, R: TextRoot> { >, spans: &'a Query< 'a, - 'a, + 's, ( &'static TextSpan, &'static TextFont, @@ -183,7 +183,7 @@ pub struct TextSpanIter<'a, R: TextRoot> { >, } -impl<'a, R: TextRoot> Iterator for TextSpanIter<'a, R> { +impl<'a, R: TextRoot> Iterator for TextSpanIter<'a, '_, R> { /// Item = (entity in text block, hierarchy depth in the block, span text, span style). type Item = (Entity, usize, &'a str, &'a TextFont, Color, LineHeight); fn next(&mut self) -> Option { @@ -246,7 +246,7 @@ impl<'a, R: TextRoot> Iterator for TextSpanIter<'a, R> { } } -impl<'a, R: TextRoot> Drop for TextSpanIter<'a, R> { +impl<'a, R: TextRoot> Drop for TextSpanIter<'a, '_, R> { fn drop(&mut self) { // Return the internal stack. let stack = core::mem::take(&mut self.stack); diff --git a/crates/bevy_ui/src/experimental/ghost_hierarchy.rs b/crates/bevy_ui/src/experimental/ghost_hierarchy.rs index 79d081c6bfd4d..3de3c58dde51c 100644 --- a/crates/bevy_ui/src/experimental/ghost_hierarchy.rs +++ b/crates/bevy_ui/src/experimental/ghost_hierarchy.rs @@ -41,7 +41,7 @@ pub type UiRootNodes<'w, 's> = Query<'w, 's, Entity, (With, Without UiRootNodes<'w, 's> { - pub fn iter(&'s self) -> impl Iterator + 's { + pub fn iter(&self) -> impl Iterator + '_ { self.root_node_query .iter() .chain(self.root_ghost_node_query.iter().flat_map(|root_ghost| { @@ -85,7 +85,7 @@ impl<'w, 's> UiChildren<'w, 's> { /// # Performance /// /// This iterator allocates if the `entity` node has more than 8 children (including ghost nodes). - pub fn iter_ui_children(&'s self, entity: Entity) -> UiChildrenIter<'w, 's> { + pub fn iter_ui_children(&self, entity: Entity) -> UiChildrenIter<'_, 's> { UiChildrenIter { stack: self .ui_children_query @@ -98,14 +98,14 @@ impl<'w, 's> UiChildren<'w, 's> { } /// Returns the UI parent of the provided entity, skipping over [`GhostNode`]. - pub fn get_parent(&'s self, entity: Entity) -> Option { + pub fn get_parent(&self, entity: Entity) -> Option { self.parents_query .iter_ancestors(entity) .find(|entity| !self.ghost_nodes_query.contains(*entity)) } /// Iterates the [`GhostNode`]s between this entity and its UI children. - pub fn iter_ghost_nodes(&'s self, entity: Entity) -> Box + 's> { + pub fn iter_ghost_nodes(&self, entity: Entity) -> Box + '_> { Box::new( self.children_query .get(entity) @@ -121,7 +121,7 @@ impl<'w, 's> UiChildren<'w, 's> { } /// Given an entity in the UI hierarchy, check if its set of children has changed, e.g if children has been added/removed or if the order has changed. - pub fn is_changed(&'s self, entity: Entity) -> bool { + pub fn is_changed(&self, entity: Entity) -> bool { self.changed_children_query.contains(entity) || self .iter_ghost_nodes(entity) @@ -129,7 +129,7 @@ impl<'w, 's> UiChildren<'w, 's> { } /// Returns `true` if the given entity is either a [`Node`] or a [`GhostNode`]. - pub fn is_ui_node(&'s self, entity: Entity) -> bool { + pub fn is_ui_node(&self, entity: Entity) -> bool { self.ui_children_query.contains(entity) } } @@ -137,7 +137,7 @@ impl<'w, 's> UiChildren<'w, 's> { #[cfg(not(feature = "ghost_nodes"))] impl<'w, 's> UiChildren<'w, 's> { /// Iterates the children of `entity`. - pub fn iter_ui_children(&'s self, entity: Entity) -> impl Iterator + 's { + pub fn iter_ui_children(&self, entity: Entity) -> impl Iterator + '_ { self.ui_children_query .get(entity) .ok() @@ -149,17 +149,17 @@ impl<'w, 's> UiChildren<'w, 's> { } /// Returns the UI parent of the provided entity. - pub fn get_parent(&'s self, entity: Entity) -> Option { + pub fn get_parent(&self, entity: Entity) -> Option { self.parents_query.get(entity).ok().map(ChildOf::parent) } /// Given an entity in the UI hierarchy, check if its set of children has changed, e.g if children has been added/removed or if the order has changed. - pub fn is_changed(&'s self, entity: Entity) -> bool { + pub fn is_changed(&self, entity: Entity) -> bool { self.changed_children_query.contains(entity) } /// Returns `true` if the given entity is either a [`Node`] or a [`GhostNode`]. - pub fn is_ui_node(&'s self, entity: Entity) -> bool { + pub fn is_ui_node(&self, entity: Entity) -> bool { self.ui_children_query.contains(entity) } } @@ -167,7 +167,7 @@ impl<'w, 's> UiChildren<'w, 's> { #[cfg(feature = "ghost_nodes")] pub struct UiChildrenIter<'w, 's> { stack: SmallVec<[Entity; 8]>, - query: &'s Query< + query: &'w Query< 'w, 's, (Option<&'static Children>, Has), 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..2d4377517057c --- /dev/null +++ b/release-content/migration-guides/combine_query_and_query_lens.md @@ -0,0 +1,61 @@ +--- +title: Combine `Query` and `QueryLens` +pull_requests: [19787] +--- + +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.17 + for item in lens.query().iter() {} + with_query(lens.query()); + // 0.18 + for item in lens.iter() {} + with_query(lens.reborrow()); +} +``` + +One consequence of this change is that `Query<'w, 's, D, F>` is no longer covariant in `'s`. +This means trying to convert a `&'a Query<'w, 's, D, F>` to a `&'a Query<'w, 'a, D, F>` will now fail with `lifetime may not live long enough`. + +Note that `'w` is still covariant, so converting `&'a Query<'w, 's, D, F>` to `&'a Query<'a, 's, D, F>` will still succeed. + +You can usually resolve that error by introducing a new lifetime parameter for `'s`, +although in many cases it will be simpler to use the `reborrow()` or `as_readonly()` methods to shorten the lifetimes and create an owned query. + +```rust +// 0.17 +struct HasQueryBorrow<'a> { + query: &'a Query<'a, 'a, &'static C>, +} + +fn create(query: &Query<&'static C>) { + let hqb = HasQueryBorrow { query }; + // ^^^^^ + // This now fails with + // error: lifetime may not live long enough +} + +// 0.18 - Add additional lifetime parameter +struct HasQueryBorrow<'a, 's> { + query: &'a Query<'a, 's, &'static C>, +} + +fn create(query: &Query<&'static C>) { + let hqb = HasQueryBorrow { query }; +} + +// 0.18 - Or store an owned query instead of a reference +// and use `reborrow()` or `as_readonly()` +struct HasQueryBorrow<'a> { + query: Query<'a, 'a, &'static C>, +} + +fn create(query: &Query<&'static C>) { + let hqb = HasQueryBorrow { query: query.as_readonly() }; +} +```