Skip to main content

bevy_ecs/query/
state.rs

1use crate::{
2    archetype::{Archetype, ArchetypeGeneration, ArchetypeId},
3    change_detection::Tick,
4    component::ComponentId,
5    entity::{Entity, EntityEquivalent, EntitySet, UniqueEntityArray},
6    entity_disabling::DefaultQueryFilters,
7    prelude::FromWorld,
8    query::{
9        ArchetypeFilter, ContiguousQueryData, FilteredAccess, FilteredAccessSet, IterQueryData,
10        QueryCombinationIter, QueryContiguousIter, QueryContiguousParIter, QueryIter,
11        QueryNotDenseError, QueryParIter, SingleEntityQueryData, WorldQuery,
12    },
13    storage::TableId,
14    system::Query,
15    world::{unsafe_world_cell::UnsafeWorldCell, DeferredWorld, World, WorldId},
16};
17
18#[cfg(all(not(target_arch = "wasm32"), feature = "multi_threaded"))]
19use crate::entity::UniqueEntityEquivalentSlice;
20
21use alloc::{format, vec::Vec};
22use bevy_utils::prelude::DebugName;
23use core::{fmt, ptr};
24use fixedbitset::FixedBitSet;
25use log::warn;
26#[cfg(feature = "trace")]
27use tracing::Span;
28
29use super::{
30    NopWorldQuery, QueryBuilder, QueryData, QueryEntityError, QueryFilter, QueryManyIter,
31    QueryManyUniqueIter, QuerySingleError, ROQueryItem, ReadOnlyQueryData,
32};
33
34/// An ID for either a table or an archetype. Used for Query iteration.
35///
36/// Query iteration is exclusively dense (over tables) or archetypal (over archetypes) based on whether
37/// the query filters are dense or not. This is represented by the [`QueryState::is_dense`] field.
38///
39/// Note that `D::IS_DENSE` and `F::IS_DENSE` have no relationship with `QueryState::is_dense` and
40/// any combination of their values can happen.
41///
42/// This is a union instead of an enum as the usage is determined at compile time, as all [`StorageId`]s for
43/// a [`QueryState`] will be all [`TableId`]s or all [`ArchetypeId`]s, and not a mixture of both. This
44/// removes the need for discriminator to minimize memory usage and branching during iteration, but requires
45/// a safety invariant be verified when disambiguating them.
46///
47/// # Safety
48/// Must be initialized and accessed as a [`TableId`], if both generic parameters to the query are dense.
49/// Must be initialized and accessed as an [`ArchetypeId`] otherwise.
50#[derive(Clone, Copy)]
51pub(super) union StorageId {
52    pub(super) table_id: TableId,
53    pub(super) archetype_id: ArchetypeId,
54}
55
56/// Provides scoped access to a [`World`] state according to a given [`QueryData`] and [`QueryFilter`].
57///
58/// This data is cached between system runs, and is used to:
59/// - store metadata about which [`Table`] or [`Archetype`] are matched by the query. "Matched" means
60///   that the query will iterate over the data in the matched table/archetype.
61/// - cache the [`State`] needed to compute the [`Fetch`] struct used to retrieve data
62///   from a specific [`Table`] or [`Archetype`]
63/// - build iterators that can iterate over the query results
64///
65/// [`State`]: crate::query::world_query::WorldQuery::State
66/// [`Fetch`]: crate::query::world_query::WorldQuery::Fetch
67/// [`Table`]: crate::storage::Table
68///
69/// # Safety
70///
71/// If the query is not read-only,
72/// then before calling any other methods on a new `QueryState`
73/// other than [`QueryState::update_archetypes`], [`QueryState::update_archetypes_unsafe_world_cell`],
74/// [`Self::init_access`] must be called.
75#[repr(C)]
76// SAFETY NOTE:
77// Do not add any new fields that use the `D` or `F` generic parameters as this may
78// make `QueryState::as_transmuted_state` unsound if not done with care.
79pub struct QueryState<D: QueryData, F: QueryFilter = ()> {
80    world_id: WorldId,
81    pub(crate) archetype_generation: ArchetypeGeneration,
82    /// Metadata about the [`Table`](crate::storage::Table)s matched by this query.
83    pub(crate) matched_tables: FixedBitSet,
84    /// Metadata about the [`Archetype`]s matched by this query.
85    pub(crate) matched_archetypes: FixedBitSet,
86    /// [`FilteredAccess`] computed by combining the `D` and `F` access. Used to check which other queries
87    /// this query can run in parallel with.
88    /// Note that because we do a zero-cost reference conversion in `Query::as_readonly`,
89    /// the access for a read-only query may include accesses for the original mutable version,
90    /// but the `Query` does not have exclusive access to those components.
91    pub(crate) component_access: FilteredAccess,
92    // NOTE: we maintain both a bitset and a vec because iterating the vec is faster
93    pub(super) matched_storage_ids: Vec<StorageId>,
94    // Represents whether this query iteration is dense or not. When this is true
95    // `matched_storage_ids` stores `TableId`s, otherwise it stores `ArchetypeId`s.
96    pub(super) is_dense: bool,
97    pub(crate) fetch_state: D::State,
98    pub(crate) filter_state: F::State,
99    #[cfg(feature = "trace")]
100    par_iter_span: Span,
101}
102
103impl<D: QueryData, F: QueryFilter> fmt::Debug for QueryState<D, F> {
104    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
105        f.debug_struct("QueryState")
106            .field("world_id", &self.world_id)
107            .field("matched_table_count", &self.matched_tables.count_ones(..))
108            .field(
109                "matched_archetype_count",
110                &self.matched_archetypes.count_ones(..),
111            )
112            .finish_non_exhaustive()
113    }
114}
115
116impl<D: QueryData, F: QueryFilter> FromWorld for QueryState<D, F> {
117    fn from_world(world: &mut World) -> Self {
118        world.query_filtered()
119    }
120}
121
122impl<D: QueryData, F: QueryFilter> QueryState<D, F> {
123    /// Converts this `QueryState` reference to a `QueryState` that does not access anything mutably.
124    pub fn as_readonly(&self) -> &QueryState<D::ReadOnly, F> {
125        // SAFETY: invariant on `WorldQuery` trait upholds that `D::ReadOnly` and `F::ReadOnly`
126        // have a subset of the access, and match the exact same archetypes/tables as `D`/`F` respectively.
127        unsafe { self.as_transmuted_state::<D::ReadOnly, F>() }
128    }
129
130    /// Converts this `QueryState` reference to a `QueryState` that does not return any data
131    /// which can be faster.
132    ///
133    /// This doesn't use `NopWorldQuery` as it loses filter functionality, for example
134    /// `NopWorldQuery<Changed<T>>` is functionally equivalent to `With<T>`.
135    pub(crate) fn as_nop(&self) -> &QueryState<NopWorldQuery<D>, F> {
136        // SAFETY: `NopWorldQuery` doesn't have any accesses and defers to
137        // `D` for table/archetype matching
138        unsafe { self.as_transmuted_state::<NopWorldQuery<D>, F>() }
139    }
140
141    /// Converts this `QueryState` reference to any other `QueryState` with
142    /// the same `WorldQuery::State` associated types.
143    ///
144    /// Consider using `as_readonly` or `as_nop` instead which are safe functions.
145    ///
146    /// # Safety
147    ///
148    /// `NewD` must have a subset of the access that `D` does and match the exact same archetypes/tables
149    /// `NewF` must have a subset of the access that `F` does and match the exact same archetypes/tables
150    pub(crate) unsafe fn as_transmuted_state<
151        NewD: ReadOnlyQueryData<State = D::State>,
152        NewF: QueryFilter<State = F::State>,
153    >(
154        &self,
155    ) -> &QueryState<NewD, NewF> {
156        &*ptr::from_ref(self).cast::<QueryState<NewD, NewF>>()
157    }
158
159    /// Returns the components accessed by this query.
160    pub fn component_access(&self) -> &FilteredAccess {
161        &self.component_access
162    }
163
164    /// Returns the tables matched by this query.
165    pub fn matched_tables(&self) -> impl Iterator<Item = TableId> + '_ {
166        self.matched_tables.ones().map(TableId::from_usize)
167    }
168
169    /// Returns the archetypes matched by this query.
170    pub fn matched_archetypes(&self) -> impl Iterator<Item = ArchetypeId> + '_ {
171        self.matched_archetypes.ones().map(ArchetypeId::new)
172    }
173
174    /// Creates a new [`QueryState`] from a given [`World`] and inherits the result of `world.id()`.
175    ///
176    /// Unlike [`QueryState::new`], this does not check access of nested queries,
177    /// so [`Self::init_access`] must be called before querying using this state or returning it to safe code.
178    ///
179    /// # Safety
180    ///
181    /// If the query is not read-only,
182    /// then before calling any other methods on the returned `QueryState`
183    /// other than [`QueryState::update_archetypes`], [`QueryState::update_archetypes_unsafe_world_cell`],
184    /// [`Self::init_access`] must be called.
185    pub unsafe fn new_unchecked(world: &mut World) -> Self {
186        let fetch_state = D::init_state(world);
187        let filter_state = F::init_state(world);
188        // SAFETY: Caller ensures `init_access` is called
189        let mut state =
190            unsafe { Self::from_states_uninitialized(world, fetch_state, filter_state) };
191        state.update_archetypes(world);
192        state
193    }
194
195    /// Adds all access from this query and any nested queries to the `component_access_set`.
196    /// Panics if the access from this query and any nested queries conflict with each other
197    /// or with any previous access.
198    pub fn init_access(
199        &self,
200        system_name: Option<&str>,
201        component_access_set: &mut FilteredAccessSet,
202        world: UnsafeWorldCell,
203    ) {
204        let conflicts = component_access_set.get_conflicts_single(&self.component_access);
205        if !conflicts.is_empty() {
206            let mut accesses = conflicts.format_conflict_list(world);
207            // Access list may be empty (if access to all components requested)
208            if !accesses.is_empty() {
209                accesses.push(' ');
210            }
211            let type_name = DebugName::type_name::<Query<D, F>>();
212            let type_name = type_name.shortname();
213            let system = system_name
214                .map(|name| format!(" in system {name}"))
215                .unwrap_or_default();
216            panic!("error[B0001]: {type_name}{system} accesses component(s) {accesses}in a way that conflicts with a previous system parameter. Consider using `Without<T>` to create disjoint Queries or merging conflicting Queries into a `ParamSet`. See: https://bevy.org/learn/errors/b0001",);
217        }
218
219        component_access_set.add(self.component_access.clone());
220        D::init_nested_access(&self.fetch_state, system_name, component_access_set, world);
221        F::init_nested_access(&self.filter_state, system_name, component_access_set, world);
222    }
223
224    /// Creates a new [`QueryState`] from a given [`World`] and inherits the result of `world.id()`.
225    pub fn new(world: &mut World) -> Self {
226        // SAFETY: We immediately call `init_access`
227        let state = unsafe { Self::new_unchecked(world) };
228        state.init_access(None, &mut FilteredAccessSet::new(), world.into());
229        state
230    }
231
232    /// Creates a new [`QueryState`] from an immutable [`World`] reference and inherits the result of `world.id()`.
233    ///
234    /// This function may fail if, for example,
235    /// the components that make up this query have not been registered into the world.
236    pub fn try_new(world: &World) -> Option<Self> {
237        let fetch_state = D::get_state(world.components())?;
238        let filter_state = F::get_state(world.components())?;
239        // SAFETY: We immediately call `init_access`
240        let mut state =
241            unsafe { Self::from_states_uninitialized(world, fetch_state, filter_state) };
242        state.init_access(None, &mut FilteredAccessSet::new(), world.into());
243        state.update_archetypes(world);
244        Some(state)
245    }
246
247    /// Creates a new [`QueryState`] but does not populate it with the matched results from the World yet
248    ///
249    /// `new_archetype` and its variants must be called on all of the World's archetypes before the
250    /// state can return valid query results.
251    ///
252    /// # Safety
253    ///
254    /// If the query is not read-only,
255    /// then before calling any other methods on the returned `QueryState`
256    /// other than [`QueryState::update_archetypes`], [`QueryState::update_archetypes_unsafe_world_cell`],
257    /// [`Self::init_access`] must be called.
258    unsafe fn from_states_uninitialized(
259        world: &World,
260        fetch_state: <D as WorldQuery>::State,
261        filter_state: <F as WorldQuery>::State,
262    ) -> Self {
263        let mut component_access = FilteredAccess::default();
264        D::update_component_access(&fetch_state, &mut component_access);
265
266        // Use a temporary empty FilteredAccess for filters. This prevents them from conflicting with the
267        // main Query's `fetch_state` access. Filters are allowed to conflict with the main query fetch
268        // because they are evaluated *before* a specific reference is constructed.
269        let mut filter_component_access = FilteredAccess::default();
270        F::update_component_access(&filter_state, &mut filter_component_access);
271
272        // Merge the temporary filter access with the main access. This ensures that filter access is
273        // properly considered in a global "cross-query" context (both within systems and across systems).
274        component_access.extend(&filter_component_access);
275
276        // For queries without dynamic filters the dense-ness of the query is equal to the dense-ness
277        // of its static type parameters.
278        let mut is_dense = D::IS_DENSE && F::IS_DENSE;
279
280        if let Some(default_filters) = world.get_resource::<DefaultQueryFilters>() {
281            default_filters.modify_access(&mut component_access);
282            is_dense &= default_filters.is_dense(world.components());
283        }
284
285        // SAFETY: Caller ensures `init_access` is called
286        Self {
287            world_id: world.id(),
288            archetype_generation: ArchetypeGeneration::initial(),
289            matched_storage_ids: Vec::new(),
290            is_dense,
291            fetch_state,
292            filter_state,
293            component_access,
294            matched_tables: Default::default(),
295            matched_archetypes: Default::default(),
296            #[cfg(feature = "trace")]
297            par_iter_span: tracing::info_span!(
298                "par_for_each",
299                query = core::any::type_name::<D>(),
300                filter = core::any::type_name::<F>(),
301            ),
302        }
303    }
304
305    /// Creates a new [`QueryState`] from a given [`QueryBuilder`] and inherits its [`FilteredAccess`].
306    pub fn from_builder(builder: &mut QueryBuilder<D, F>) -> Self {
307        let mut fetch_state = D::init_state(builder.world_mut());
308        let filter_state = F::init_state(builder.world_mut());
309
310        let mut component_access = FilteredAccess::default();
311        D::update_component_access(&fetch_state, &mut component_access);
312        D::provide_extra_access(
313            &mut fetch_state,
314            component_access.access_mut(),
315            builder.access().access(),
316        );
317
318        let mut component_access = builder.access().clone();
319
320        // For dynamic queries the dense-ness is given by the query builder.
321        let mut is_dense = builder.is_dense();
322
323        if let Some(default_filters) = builder.world().get_resource::<DefaultQueryFilters>() {
324            default_filters.modify_access(&mut component_access);
325            is_dense &= default_filters.is_dense(builder.world().components());
326        }
327
328        // SAFETY: We immediately call `init_access`
329        let mut state = Self {
330            world_id: builder.world().id(),
331            archetype_generation: ArchetypeGeneration::initial(),
332            matched_storage_ids: Vec::new(),
333            is_dense,
334            fetch_state,
335            filter_state,
336            component_access,
337            matched_tables: Default::default(),
338            matched_archetypes: Default::default(),
339            #[cfg(feature = "trace")]
340            par_iter_span: tracing::info_span!(
341                "par_for_each",
342                data = core::any::type_name::<D>(),
343                filter = core::any::type_name::<F>(),
344            ),
345        };
346        state.init_access(None, &mut FilteredAccessSet::new(), builder.world().into());
347        state.update_archetypes(builder.world());
348        state
349    }
350
351    /// Creates a [`Query`] from the given [`QueryState`] and [`World`].
352    ///
353    /// This will create read-only queries, see [`Self::query_mut`] for mutable queries.
354    pub fn query<'w, 's>(&'s mut self, world: &'w World) -> Query<'w, 's, D::ReadOnly, F> {
355        self.update_archetypes(world);
356        self.query_manual(world)
357    }
358
359    /// Creates a [`Query`] from the given [`QueryState`] and [`World`].
360    ///
361    /// This method is slightly more efficient than [`QueryState::query`] in some situations, since
362    /// it does not update this instance's internal cache. The resulting query may skip an entity that
363    /// belongs to an archetype that has not been cached.
364    ///
365    /// To ensure that the cache is up to date, call [`QueryState::update_archetypes`] before this method.
366    /// The cache is also updated in [`QueryState::new`], [`QueryState::get`], or any method with mutable
367    /// access to `self`.
368    ///
369    /// This will create read-only queries, see [`Self::query_mut`] for mutable queries.
370    pub fn query_manual<'w, 's>(&'s self, world: &'w World) -> Query<'w, 's, D::ReadOnly, F> {
371        self.validate_world(world.id());
372        // SAFETY:
373        // - We have read access to the entire world, and we call `as_readonly()` so the query only performs read access.
374        // - We called `validate_world`.
375        unsafe {
376            self.as_readonly()
377                .query_unchecked_manual(world.as_unsafe_world_cell_readonly())
378        }
379    }
380
381    /// Creates a [`Query`] from the given [`QueryState`] and [`World`].
382    pub fn query_mut<'w, 's>(
383        &'s mut self,
384        world: impl Into<DeferredWorld<'w>>,
385    ) -> Query<'w, 's, D, F> {
386        let mut world = world.into();
387        let last_run = world.last_change_tick();
388        let this_run = world.change_tick();
389        // SAFETY: We have exclusive access to the entire world.
390        unsafe {
391            self.query_unchecked_with_ticks(world.into_unsafe_world_cell(), last_run, this_run)
392        }
393    }
394
395    /// Creates a [`Query`] from the given [`QueryState`] and [`World`].
396    ///
397    /// # Safety
398    ///
399    /// This does not check for mutable query correctness. To be safe, make sure mutable queries
400    /// have unique access to the components they query.
401    pub unsafe fn query_unchecked<'w, 's>(
402        &'s mut self,
403        world: UnsafeWorldCell<'w>,
404    ) -> Query<'w, 's, D, F> {
405        self.update_archetypes_unsafe_world_cell(world);
406        // SAFETY: Caller ensures we have the required access
407        unsafe { self.query_unchecked_manual(world) }
408    }
409
410    /// Creates a [`Query`] from the given [`QueryState`] and [`World`].
411    ///
412    /// This method is slightly more efficient than [`QueryState::query_unchecked`] in some situations, since
413    /// it does not update this instance's internal cache. The resulting query may skip an entity that
414    /// belongs to an archetype that has not been cached.
415    ///
416    /// To ensure that the cache is up to date, call [`QueryState::update_archetypes`] before this method.
417    /// The cache is also updated in [`QueryState::new`], [`QueryState::get`], or any method with mutable
418    /// access to `self`.
419    ///
420    /// # Safety
421    ///
422    /// This does not check for mutable query correctness. To be safe, make sure mutable queries
423    /// have unique access to the components they query.
424    /// This does not validate that `world.id()` matches `self.world_id`. Calling this on a `world`
425    /// with a mismatched [`WorldId`] is unsound.
426    pub unsafe fn query_unchecked_manual<'w, 's>(
427        &'s self,
428        world: UnsafeWorldCell<'w>,
429    ) -> Query<'w, 's, D, F> {
430        let last_run = world.last_change_tick();
431        let this_run = world.change_tick();
432        // SAFETY:
433        // - The caller ensured we have the correct access to the world.
434        // - The caller ensured that the world matches.
435        unsafe { self.query_unchecked_manual_with_ticks(world, last_run, this_run) }
436    }
437
438    /// Creates a [`Query`] from the given [`QueryState`] and [`World`].
439    ///
440    /// # Safety
441    ///
442    /// This does not check for mutable query correctness. To be safe, make sure mutable queries
443    /// have unique access to the components they query.
444    pub unsafe fn query_unchecked_with_ticks<'w, 's>(
445        &'s mut self,
446        world: UnsafeWorldCell<'w>,
447        last_run: Tick,
448        this_run: Tick,
449    ) -> Query<'w, 's, D, F> {
450        self.update_archetypes_unsafe_world_cell(world);
451        // SAFETY:
452        // - The caller ensured we have the correct access to the world.
453        // - We called `update_archetypes_unsafe_world_cell`, which calls `validate_world`.
454        unsafe { self.query_unchecked_manual_with_ticks(world, last_run, this_run) }
455    }
456
457    /// Creates a [`Query`] from the given [`QueryState`] and [`World`].
458    ///
459    /// This method is slightly more efficient than [`QueryState::query_unchecked_with_ticks`] in some situations, since
460    /// it does not update this instance's internal cache. The resulting query may skip an entity that
461    /// belongs to an archetype that has not been cached.
462    ///
463    /// To ensure that the cache is up to date, call [`QueryState::update_archetypes`] before this method.
464    /// The cache is also updated in [`QueryState::new`], [`QueryState::get`], or any method with mutable
465    /// access to `self`.
466    ///
467    /// # Safety
468    ///
469    /// This does not check for mutable query correctness. To be safe, make sure mutable queries
470    /// have unique access to the components they query.
471    /// This does not validate that `world.id()` matches `self.world_id`. Calling this on a `world`
472    /// with a mismatched [`WorldId`] is unsound.
473    pub unsafe fn query_unchecked_manual_with_ticks<'w, 's>(
474        &'s self,
475        world: UnsafeWorldCell<'w>,
476        last_run: Tick,
477        this_run: Tick,
478    ) -> Query<'w, 's, D, F> {
479        // SAFETY:
480        // - The caller ensured we have the correct access to the world.
481        // - The caller ensured that the world matches.
482        unsafe { Query::new(world, self, last_run, this_run) }
483    }
484
485    /// Checks if the query is empty for the given [`World`], where the last change and current tick are given.
486    ///
487    /// This is equivalent to `self.iter().next().is_none()`, and thus the worst case runtime will be `O(n)`
488    /// where `n` is the number of *potential* matches. This can be notably expensive for queries that rely
489    /// on non-archetypal filters such as [`Added`], [`Changed`] or [`Spawned`] which must individually check
490    /// each query result for a match.
491    ///
492    /// # Panics
493    ///
494    /// If `world` does not match the one used to call `QueryState::new` for this instance.
495    ///
496    /// [`Added`]: crate::query::Added
497    /// [`Changed`]: crate::query::Changed
498    /// [`Spawned`]: crate::query::Spawned
499    #[inline]
500    pub fn is_empty(&self, world: &World, last_run: Tick, this_run: Tick) -> bool {
501        self.validate_world(world.id());
502        // SAFETY:
503        // - We have read access to the entire world, and `is_empty()` only performs read access.
504        // - We called `validate_world`.
505        unsafe {
506            self.query_unchecked_manual_with_ticks(
507                world.as_unsafe_world_cell_readonly(),
508                last_run,
509                this_run,
510            )
511        }
512        .is_empty()
513    }
514
515    /// Returns `true` if the given [`Entity`] matches the query.
516    ///
517    /// This is always guaranteed to run in `O(1)` time.
518    #[inline]
519    pub fn contains(&self, entity: Entity, world: &World, last_run: Tick, this_run: Tick) -> bool {
520        self.validate_world(world.id());
521        // SAFETY:
522        // - We have read access to the entire world, and `is_empty()` only performs read access.
523        // - We called `validate_world`.
524        unsafe {
525            self.query_unchecked_manual_with_ticks(
526                world.as_unsafe_world_cell_readonly(),
527                last_run,
528                this_run,
529            )
530        }
531        .contains(entity)
532    }
533
534    /// Updates the state's internal view of the [`World`]'s archetypes. If this is not called before querying data,
535    /// the results may not accurately reflect what is in the `world`.
536    ///
537    /// This is only required if a `manual` method (such as [`Self::get_manual`]) is being called, and it only needs to
538    /// be called if the `world` has been structurally mutated (i.e. added/removed a component or resource). Users using
539    /// non-`manual` methods such as [`QueryState::get`] do not need to call this as it will be automatically called for them.
540    ///
541    /// If you have an [`UnsafeWorldCell`] instead of `&World`, consider using [`QueryState::update_archetypes_unsafe_world_cell`].
542    ///
543    /// # Panics
544    ///
545    /// If `world` does not match the one used to call `QueryState::new` for this instance.
546    #[inline]
547    pub fn update_archetypes(&mut self, world: &World) {
548        self.update_archetypes_unsafe_world_cell(world.as_unsafe_world_cell_readonly());
549    }
550
551    /// Updates the state's internal view of the `world`'s archetypes. If this is not called before querying data,
552    /// the results may not accurately reflect what is in the `world`.
553    ///
554    /// This is only required if a `manual` method (such as [`Self::get_manual`]) is being called, and it only needs to
555    /// be called if the `world` has been structurally mutated (i.e. added/removed a component or resource). Users using
556    /// non-`manual` methods such as [`QueryState::get`] do not need to call this as it will be automatically called for them.
557    ///
558    /// # Note
559    ///
560    /// This method only accesses world metadata.
561    ///
562    /// # Panics
563    ///
564    /// If `world` does not match the one used to call `QueryState::new` for this instance.
565    pub fn update_archetypes_unsafe_world_cell(&mut self, world: UnsafeWorldCell) {
566        self.validate_world(world.id());
567        D::update_archetypes(&mut self.fetch_state, world);
568        F::update_archetypes(&mut self.filter_state, world);
569        if self.component_access.required.is_clear() {
570            let archetypes = world.archetypes();
571            let old_generation =
572                core::mem::replace(&mut self.archetype_generation, archetypes.generation());
573
574            for archetype in &archetypes[old_generation..] {
575                // SAFETY: The validate_world call ensures that the world is the same the QueryState
576                // was initialized from.
577                unsafe {
578                    self.new_archetype(archetype);
579                }
580            }
581        } else {
582            // skip if we are already up to date
583            if self.archetype_generation == world.archetypes().generation() {
584                return;
585            }
586            // if there are required components, we can optimize by only iterating through archetypes
587            // that contain at least one of the required components
588            let potential_archetypes = self
589                .component_access
590                .required
591                .iter()
592                .filter_map(|component_id| {
593                    world
594                        .archetypes()
595                        .component_index()
596                        .get(&component_id)
597                        .map(|index| index.keys())
598                })
599                // select the component with the fewest archetypes
600                .min_by_key(ExactSizeIterator::len);
601            if let Some(archetypes) = potential_archetypes {
602                for archetype_id in archetypes {
603                    // exclude archetypes that have already been processed
604                    if archetype_id < &self.archetype_generation.0 {
605                        continue;
606                    }
607                    // SAFETY: get_potential_archetypes only returns archetype ids that are valid for the world
608                    let archetype = &world.archetypes()[*archetype_id];
609                    // SAFETY: The validate_world call ensures that the world is the same the QueryState
610                    // was initialized from.
611                    unsafe {
612                        self.new_archetype(archetype);
613                    }
614                }
615            }
616            self.archetype_generation = world.archetypes().generation();
617        }
618    }
619
620    /// # Panics
621    ///
622    /// If `world_id` does not match the [`World`] used to call `QueryState::new` for this instance.
623    ///
624    /// Many unsafe query methods require the world to match for soundness. This function is the easiest
625    /// way of ensuring that it matches.
626    #[inline]
627    #[track_caller]
628    pub fn validate_world(&self, world_id: WorldId) {
629        #[inline(never)]
630        #[track_caller]
631        #[cold]
632        fn panic_mismatched(this: WorldId, other: WorldId) -> ! {
633            panic!("Encountered a mismatched World. This QueryState was created from {this:?}, but a method was called using {other:?}.");
634        }
635
636        if self.world_id != world_id {
637            panic_mismatched(self.world_id, world_id);
638        }
639    }
640
641    /// Update the current [`QueryState`] with information from the provided [`Archetype`]
642    /// (if applicable, i.e. if the archetype has any intersecting [`ComponentId`] with the current [`QueryState`]).
643    ///
644    /// # Safety
645    /// `archetype` must be from the `World` this state was initialized from.
646    pub unsafe fn new_archetype(&mut self, archetype: &Archetype) {
647        if D::matches_component_set(&self.fetch_state, &|id| archetype.contains(id))
648            && F::matches_component_set(&self.filter_state, &|id| archetype.contains(id))
649            && self.matches_component_set(&|id| archetype.contains(id))
650        {
651            let archetype_index = archetype.id().index();
652            if !self.matched_archetypes.contains(archetype_index) {
653                self.matched_archetypes.grow_and_insert(archetype_index);
654                if !self.is_dense {
655                    self.matched_storage_ids.push(StorageId {
656                        archetype_id: archetype.id(),
657                    });
658                }
659            }
660            let table_index = archetype.table_id().as_usize();
661            if !self.matched_tables.contains(table_index) {
662                self.matched_tables.grow_and_insert(table_index);
663                if self.is_dense {
664                    self.matched_storage_ids.push(StorageId {
665                        table_id: archetype.table_id(),
666                    });
667                }
668            }
669        }
670    }
671
672    /// Returns `true` if this query matches a set of components. Otherwise, returns `false`.
673    pub fn matches_component_set(&self, set_contains_id: &impl Fn(ComponentId) -> bool) -> bool {
674        self.component_access.filter_sets.iter().any(|set| {
675            set.with.iter().all(set_contains_id)
676                && set.without.iter().all(|index| !set_contains_id(index))
677        })
678    }
679
680    /// Use this to transform a [`QueryState`] into a more generic [`QueryState`].
681    /// This can be useful for passing to another function that might take the more general form.
682    /// See [`Query::transmute_lens`](crate::system::Query::transmute_lens) for more details.
683    ///
684    /// You should not call [`update_archetypes`](Self::update_archetypes) on the returned [`QueryState`] as the result will be unpredictable.
685    /// You might end up with a mix of archetypes that only matched the original query + archetypes that only match
686    /// the new [`QueryState`]. Most of the safe methods on [`QueryState`] call [`QueryState::update_archetypes`] internally, so this
687    /// best used through a [`Query`]
688    pub fn transmute<'a, NewD: SingleEntityQueryData>(
689        &self,
690        world: impl Into<UnsafeWorldCell<'a>>,
691    ) -> QueryState<NewD> {
692        self.transmute_filtered::<NewD, ()>(world.into())
693    }
694
695    /// Creates a new [`QueryState`] with the same underlying [`FilteredAccess`], matched tables and archetypes
696    /// as self but with a new type signature.
697    ///
698    /// Panics if `NewD` or `NewF` require accesses that this query does not have.
699    pub fn transmute_filtered<'a, NewD: SingleEntityQueryData, NewF: QueryFilter>(
700        &self,
701        world: impl Into<UnsafeWorldCell<'a>>,
702    ) -> QueryState<NewD, NewF> {
703        let world = world.into();
704        self.validate_world(world.id());
705
706        let mut component_access = FilteredAccess::default();
707        let mut fetch_state = NewD::get_state(world.components()).expect("Could not create fetch_state, Please initialize all referenced components before transmuting.");
708        let filter_state = NewF::get_state(world.components()).expect("Could not create filter_state, Please initialize all referenced components before transmuting.");
709
710        let mut self_access = self.component_access.clone();
711        if D::IS_READ_ONLY {
712            // The current state was transmuted from a mutable
713            // `QueryData` to a read-only one.
714            // Ignore any write access in the current state.
715            self_access.access_mut().clear_writes();
716        }
717
718        NewD::update_component_access(&fetch_state, &mut component_access);
719        NewD::provide_extra_access(
720            &mut fetch_state,
721            component_access.access_mut(),
722            self_access.access(),
723        );
724
725        let mut filter_component_access = FilteredAccess::default();
726        NewF::update_component_access(&filter_state, &mut filter_component_access);
727
728        component_access.extend(&filter_component_access);
729        assert!(
730            component_access.is_subset(&self_access),
731            "Transmuted state for {} attempts to access terms that are not allowed by original state {}.",
732            DebugName::type_name::<(NewD, NewF)>(), DebugName::type_name::<(D, F)>()
733        );
734
735        // For transmuted queries, the dense-ness of the query is equal to the dense-ness of the original query.
736        //
737        // We ensure soundness using `FilteredAccess::required`.
738        //
739        // Any `WorldQuery` implementations that rely on a query being sparse for soundness,
740        // including `&`, `&mut`, `Ref`, and `Mut`, will add a sparse set component to the `required` set.
741        // (`Option<&Sparse>` and `Has<Sparse>` will incorrectly report a component as never being present
742        // when doing dense iteration, but are not unsound.  See https://github.com/bevyengine/bevy/issues/16397)
743        //
744        // And any query with a sparse set component in the `required` set must have `is_dense = false`.
745        // For static queries, the `WorldQuery` implementations ensure this.
746        // For dynamic queries, anything that adds a `required` component also adds a `with` filter.
747        //
748        // The `component_access.is_subset()` check ensures that if the new query has a sparse set component in the `required` set,
749        // then the original query must also have had that component in the `required` set.
750        // Therefore, if the `WorldQuery` implementations rely on a query being sparse for soundness,
751        // then there was a sparse set component in the `required` set, and the query has `is_dense = false`.
752        let is_dense = self.is_dense;
753
754        // SAFETY: `D: SingleEntityQueryData`, so we do not need to call `init_access`
755        QueryState {
756            world_id: self.world_id,
757            archetype_generation: self.archetype_generation,
758            matched_storage_ids: self.matched_storage_ids.clone(),
759            is_dense,
760            fetch_state,
761            filter_state,
762            component_access: self_access,
763            matched_tables: self.matched_tables.clone(),
764            matched_archetypes: self.matched_archetypes.clone(),
765            #[cfg(feature = "trace")]
766            par_iter_span: tracing::info_span!(
767                "par_for_each",
768                query = core::any::type_name::<NewD>(),
769                filter = core::any::type_name::<NewF>(),
770            ),
771        }
772    }
773
774    /// Use this to combine two queries. The data accessed will be the intersection
775    /// of archetypes included in both queries. This can be useful for accessing a
776    /// subset of the entities between two queries.
777    ///
778    /// You should not call `update_archetypes` on the returned `QueryState` as the result
779    /// could be unpredictable. You might end up with a mix of archetypes that only matched
780    /// the original query + archetypes that only match the new `QueryState`. Most of the
781    /// safe methods on `QueryState` call [`QueryState::update_archetypes`] internally, so
782    /// this is best used through a `Query`.
783    ///
784    /// ## Performance
785    ///
786    /// This will have similar performance as constructing a new `QueryState` since much of internal state
787    /// needs to be reconstructed. But it will be a little faster as it only needs to compare the intersection
788    /// of matching archetypes rather than iterating over all archetypes.
789    ///
790    /// ## Panics
791    ///
792    /// Will panic if `NewD` contains accesses not in `Q` or `OtherQ`.
793    pub fn join<'a, OtherD: QueryData, NewD: SingleEntityQueryData>(
794        &self,
795        world: impl Into<UnsafeWorldCell<'a>>,
796        other: &QueryState<OtherD>,
797    ) -> QueryState<NewD, ()> {
798        self.join_filtered::<_, (), NewD, ()>(world, other)
799    }
800
801    /// Use this to combine two queries. The data accessed will be the intersection
802    /// of archetypes included in both queries.
803    ///
804    /// ## Panics
805    ///
806    /// Will panic if `NewD` or `NewF` requires accesses not in `Q` or `OtherQ`.
807    pub fn join_filtered<
808        'a,
809        OtherD: QueryData,
810        OtherF: QueryFilter,
811        NewD: SingleEntityQueryData,
812        NewF: QueryFilter,
813    >(
814        &self,
815        world: impl Into<UnsafeWorldCell<'a>>,
816        other: &QueryState<OtherD, OtherF>,
817    ) -> QueryState<NewD, NewF> {
818        if self.world_id != other.world_id {
819            panic!("Joining queries initialized on different worlds is not allowed.");
820        }
821
822        let world = world.into();
823
824        self.validate_world(world.id());
825
826        let mut component_access = FilteredAccess::default();
827        let mut new_fetch_state = NewD::get_state(world.components())
828            .expect("Could not create fetch_state, Please initialize all referenced components before transmuting.");
829        let new_filter_state = NewF::get_state(world.components())
830            .expect("Could not create filter_state, Please initialize all referenced components before transmuting.");
831
832        let mut joined_component_access = self.component_access.clone();
833        joined_component_access.extend(&other.component_access);
834
835        if D::IS_READ_ONLY && self.component_access.access().has_any_write()
836            || OtherD::IS_READ_ONLY && other.component_access.access().has_any_write()
837        {
838            // One of the input states was transmuted from a mutable
839            // `QueryData` to a read-only one.
840            // Ignore any write access in that current state.
841            // The simplest way to do this is to clear *all* writes
842            // and then add back in any writes that are valid
843            joined_component_access.access_mut().clear_writes();
844            if !D::IS_READ_ONLY {
845                joined_component_access
846                    .access_mut()
847                    .extend(self.component_access.access());
848            }
849            if !OtherD::IS_READ_ONLY {
850                joined_component_access
851                    .access_mut()
852                    .extend(other.component_access.access());
853            }
854        }
855
856        NewD::update_component_access(&new_fetch_state, &mut component_access);
857        NewD::provide_extra_access(
858            &mut new_fetch_state,
859            component_access.access_mut(),
860            joined_component_access.access(),
861        );
862
863        let mut new_filter_component_access = FilteredAccess::default();
864        NewF::update_component_access(&new_filter_state, &mut new_filter_component_access);
865
866        component_access.extend(&new_filter_component_access);
867
868        assert!(
869            component_access.is_subset(&joined_component_access),
870            "Joined state for {} attempts to access terms that are not allowed by state {} joined with {}.",
871            DebugName::type_name::<(NewD, NewF)>(), DebugName::type_name::<(D, F)>(), DebugName::type_name::<(OtherD, OtherF)>()
872        );
873
874        if self.archetype_generation != other.archetype_generation {
875            warn!("You have tried to join queries with different archetype_generations. This could lead to unpredictable results.");
876        }
877
878        // the join is dense of both the queries were dense.
879        let is_dense = self.is_dense && other.is_dense;
880
881        // take the intersection of the matched ids
882        let mut matched_tables = self.matched_tables.clone();
883        let mut matched_archetypes = self.matched_archetypes.clone();
884        matched_tables.intersect_with(&other.matched_tables);
885        matched_archetypes.intersect_with(&other.matched_archetypes);
886        let matched_storage_ids = if is_dense {
887            matched_tables
888                .ones()
889                .map(|id| StorageId {
890                    table_id: TableId::from_usize(id),
891                })
892                .collect()
893        } else {
894            matched_archetypes
895                .ones()
896                .map(|id| StorageId {
897                    archetype_id: ArchetypeId::new(id),
898                })
899                .collect()
900        };
901
902        // SAFETY: `D: SingleEntityQueryData`, so we do not need to call `init_access`
903        QueryState {
904            world_id: self.world_id,
905            archetype_generation: self.archetype_generation,
906            matched_storage_ids,
907            is_dense,
908            fetch_state: new_fetch_state,
909            filter_state: new_filter_state,
910            component_access: joined_component_access,
911            matched_tables,
912            matched_archetypes,
913            #[cfg(feature = "trace")]
914            par_iter_span: tracing::info_span!(
915                "par_for_each",
916                query = core::any::type_name::<NewD>(),
917                filter = core::any::type_name::<NewF>(),
918            ),
919        }
920    }
921
922    /// Gets the query result for the given [`World`] and [`Entity`].
923    ///
924    /// This can only be called for read-only queries, see [`Self::get_mut`] for write-queries.
925    ///
926    /// If you need to get multiple items at once but get borrowing errors,
927    /// consider using [`Self::update_archetypes`] followed by multiple [`Self::get_manual`] calls,
928    /// or making a single call with [`Self::get_many`]  or [`Self::iter_many`].
929    ///
930    /// This is always guaranteed to run in `O(1)` time.
931    #[inline]
932    pub fn get<'w>(
933        &mut self,
934        world: &'w World,
935        entity: Entity,
936    ) -> Result<ROQueryItem<'w, '_, D>, QueryEntityError> {
937        self.query(world).get_inner(entity)
938    }
939
940    /// Returns the read-only query results for the given array of [`Entity`].
941    ///
942    /// In case of a nonexisting entity or mismatched component, a [`QueryEntityError`] is
943    /// returned instead.
944    ///
945    /// Note that the unlike [`QueryState::get_many_mut`], the entities passed in do not need to be unique.
946    ///
947    /// # Examples
948    ///
949    /// ```
950    /// use bevy_ecs::prelude::*;
951    /// use bevy_ecs::query::QueryEntityError;
952    ///
953    /// #[derive(Component, PartialEq, Debug)]
954    /// struct A(usize);
955    ///
956    /// let mut world = World::new();
957    /// let entity_vec: Vec<Entity> = (0..3).map(|i|world.spawn(A(i)).id()).collect();
958    /// let entities: [Entity; 3] = entity_vec.try_into().unwrap();
959    ///
960    /// world.spawn(A(73));
961    ///
962    /// let mut query_state = world.query::<&A>();
963    ///
964    /// let component_values = query_state.get_many(&world, entities).unwrap();
965    ///
966    /// assert_eq!(component_values, [&A(0), &A(1), &A(2)]);
967    ///
968    /// let wrong_entity = Entity::from_raw_u32(365).unwrap();
969    ///
970    /// assert_eq!(match query_state.get_many(&mut world, [wrong_entity]).unwrap_err() {QueryEntityError::NotSpawned(error) => error.entity(), _ => panic!()}, wrong_entity);
971    /// ```
972    #[inline]
973    pub fn get_many<'w, const N: usize>(
974        &mut self,
975        world: &'w World,
976        entities: [Entity; N],
977    ) -> Result<[ROQueryItem<'w, '_, D>; N], QueryEntityError> {
978        self.query(world).get_many_inner(entities)
979    }
980
981    /// Returns the read-only query results for the given [`UniqueEntityArray`].
982    ///
983    /// In case of a nonexisting entity or mismatched component, a [`QueryEntityError`] is
984    /// returned instead.
985    ///
986    /// # Examples
987    ///
988    /// ```
989    /// use bevy_ecs::{prelude::*, query::QueryEntityError, entity::{EntitySetIterator, UniqueEntityArray, UniqueEntityVec}};
990    ///
991    /// #[derive(Component, PartialEq, Debug)]
992    /// struct A(usize);
993    ///
994    /// let mut world = World::new();
995    /// let entity_set: UniqueEntityVec = world.spawn_batch((0..3).map(A)).collect_set();
996    /// let entity_set: UniqueEntityArray<3> = entity_set.try_into().unwrap();
997    ///
998    /// world.spawn(A(73));
999    ///
1000    /// let mut query_state = world.query::<&A>();
1001    ///
1002    /// let component_values = query_state.get_many_unique(&world, entity_set).unwrap();
1003    ///
1004    /// assert_eq!(component_values, [&A(0), &A(1), &A(2)]);
1005    ///
1006    /// let wrong_entity = Entity::from_raw_u32(365).unwrap();
1007    ///
1008    /// assert_eq!(match query_state.get_many_unique(&mut world, UniqueEntityArray::from([wrong_entity])).unwrap_err() {QueryEntityError::NotSpawned(error) => error.entity(), _ => panic!()}, wrong_entity);
1009    /// ```
1010    #[inline]
1011    pub fn get_many_unique<'w, const N: usize>(
1012        &mut self,
1013        world: &'w World,
1014        entities: UniqueEntityArray<N>,
1015    ) -> Result<[ROQueryItem<'w, '_, D>; N], QueryEntityError> {
1016        self.query(world).get_many_unique_inner(entities)
1017    }
1018
1019    /// Gets the query result for the given [`World`] and [`Entity`].
1020    ///
1021    /// This is always guaranteed to run in `O(1)` time.
1022    #[inline]
1023    pub fn get_mut<'w>(
1024        &mut self,
1025        world: &'w mut World,
1026        entity: Entity,
1027    ) -> Result<D::Item<'w, '_>, QueryEntityError> {
1028        self.query_mut(world).get_inner(entity)
1029    }
1030
1031    /// Returns the query results for the given array of [`Entity`].
1032    ///
1033    /// In case of a nonexisting entity or mismatched component, a [`QueryEntityError`] is
1034    /// returned instead.
1035    ///
1036    /// ```
1037    /// use bevy_ecs::prelude::*;
1038    /// use bevy_ecs::query::QueryEntityError;
1039    ///
1040    /// #[derive(Component, PartialEq, Debug)]
1041    /// struct A(usize);
1042    ///
1043    /// let mut world = World::new();
1044    ///
1045    /// let entities: Vec<Entity> = (0..3).map(|i|world.spawn(A(i)).id()).collect();
1046    /// let entities: [Entity; 3] = entities.try_into().unwrap();
1047    ///
1048    /// world.spawn(A(73));
1049    ///
1050    /// let mut query_state = world.query::<&mut A>();
1051    ///
1052    /// let mut mutable_component_values = query_state.get_many_mut(&mut world, entities).unwrap();
1053    ///
1054    /// for mut a in &mut mutable_component_values {
1055    ///     a.0 += 5;
1056    /// }
1057    ///
1058    /// let component_values = query_state.get_many(&world, entities).unwrap();
1059    ///
1060    /// assert_eq!(component_values, [&A(5), &A(6), &A(7)]);
1061    ///
1062    /// let wrong_entity = Entity::from_raw_u32(57).unwrap();
1063    /// let invalid_entity = world.spawn_empty().id();
1064    ///
1065    /// assert_eq!(match query_state.get_many(&mut world, [wrong_entity]).unwrap_err() {QueryEntityError::NotSpawned(error) => error.entity(), _ => panic!()}, wrong_entity);
1066    /// assert_eq!(match query_state.get_many_mut(&mut world, [invalid_entity]).unwrap_err() {QueryEntityError::QueryDoesNotMatch(entity, _) => entity, _ => panic!()}, invalid_entity);
1067    /// assert_eq!(query_state.get_many_mut(&mut world, [entities[0], entities[0]]).unwrap_err(), QueryEntityError::AliasedMutability(entities[0]));
1068    /// ```
1069    #[inline]
1070    pub fn get_many_mut<'w, const N: usize>(
1071        &mut self,
1072        world: &'w mut World,
1073        entities: [Entity; N],
1074    ) -> Result<[D::Item<'w, '_>; N], QueryEntityError>
1075    where
1076        D: IterQueryData,
1077    {
1078        self.query_mut(world).get_many_mut_inner(entities)
1079    }
1080
1081    /// Returns the query results for the given [`UniqueEntityArray`].
1082    ///
1083    /// In case of a nonexisting entity or mismatched component, a [`QueryEntityError`] is
1084    /// returned instead.
1085    ///
1086    /// ```
1087    /// use bevy_ecs::{prelude::*, query::QueryEntityError, entity::{EntitySetIterator, UniqueEntityArray, UniqueEntityVec}};
1088    ///
1089    /// #[derive(Component, PartialEq, Debug)]
1090    /// struct A(usize);
1091    ///
1092    /// let mut world = World::new();
1093    ///
1094    /// let entity_set: UniqueEntityVec = world.spawn_batch((0..3).map(A)).collect_set();
1095    /// let entity_set: UniqueEntityArray<3> = entity_set.try_into().unwrap();
1096    ///
1097    /// world.spawn(A(73));
1098    ///
1099    /// let mut query_state = world.query::<&mut A>();
1100    ///
1101    /// let mut mutable_component_values = query_state.get_many_unique_mut(&mut world, entity_set).unwrap();
1102    ///
1103    /// for mut a in &mut mutable_component_values {
1104    ///     a.0 += 5;
1105    /// }
1106    ///
1107    /// let component_values = query_state.get_many_unique(&world, entity_set).unwrap();
1108    ///
1109    /// assert_eq!(component_values, [&A(5), &A(6), &A(7)]);
1110    ///
1111    /// let wrong_entity = Entity::from_raw_u32(57).unwrap();
1112    /// let invalid_entity = world.spawn_empty().id();
1113    ///
1114    /// assert_eq!(match query_state.get_many_unique(&mut world, UniqueEntityArray::from([wrong_entity])).unwrap_err() {QueryEntityError::NotSpawned(error) => error.entity(), _ => panic!()}, wrong_entity);
1115    /// assert_eq!(match query_state.get_many_unique_mut(&mut world, UniqueEntityArray::from([invalid_entity])).unwrap_err() {QueryEntityError::QueryDoesNotMatch(entity, _) => entity, _ => panic!()}, invalid_entity);
1116    /// ```
1117    #[inline]
1118    pub fn get_many_unique_mut<'w, const N: usize>(
1119        &mut self,
1120        world: &'w mut World,
1121        entities: UniqueEntityArray<N>,
1122    ) -> Result<[D::Item<'w, '_>; N], QueryEntityError>
1123    where
1124        D: IterQueryData,
1125    {
1126        self.query_mut(world).get_many_unique_inner(entities)
1127    }
1128
1129    /// Gets the query result for the given [`World`] and [`Entity`].
1130    ///
1131    /// This method is slightly more efficient than [`QueryState::get`] in some situations, since
1132    /// it does not update this instance's internal cache. This method will return an error if `entity`
1133    /// belongs to an archetype that has not been cached.
1134    ///
1135    /// To ensure that the cache is up to date, call [`QueryState::update_archetypes`] before this method.
1136    /// The cache is also updated in [`QueryState::new`], `QueryState::get`, or any method with mutable
1137    /// access to `self`.
1138    ///
1139    /// This can only be called for read-only queries, see [`Self::get_mut`] for mutable queries.
1140    ///
1141    /// This is always guaranteed to run in `O(1)` time.
1142    #[inline]
1143    pub fn get_manual<'w>(
1144        &self,
1145        world: &'w World,
1146        entity: Entity,
1147    ) -> Result<ROQueryItem<'w, '_, D>, QueryEntityError> {
1148        self.query_manual(world).get_inner(entity)
1149    }
1150
1151    /// Gets the query result for the given [`World`] and [`Entity`].
1152    ///
1153    /// This is always guaranteed to run in `O(1)` time.
1154    ///
1155    /// # Safety
1156    ///
1157    /// This does not check for mutable query correctness. To be safe, make sure mutable queries
1158    /// have unique access to the components they query.
1159    #[inline]
1160    pub unsafe fn get_unchecked<'w>(
1161        &mut self,
1162        world: UnsafeWorldCell<'w>,
1163        entity: Entity,
1164    ) -> Result<D::Item<'w, '_>, QueryEntityError> {
1165        // SAFETY: Upheld by caller
1166        unsafe { self.query_unchecked(world) }.get_inner(entity)
1167    }
1168
1169    /// Returns an [`Iterator`] over the query results for the given [`World`].
1170    ///
1171    /// This can only be called for read-only queries, see [`Self::iter_mut`] for write-queries.
1172    ///
1173    /// If you need to iterate multiple times at once but get borrowing errors,
1174    /// consider using [`Self::update_archetypes`] followed by multiple [`Self::iter_manual`] calls.
1175    #[inline]
1176    pub fn iter<'w, 's>(&'s mut self, world: &'w World) -> QueryIter<'w, 's, D::ReadOnly, F> {
1177        self.query(world).iter_inner()
1178    }
1179
1180    /// Returns an [`Iterator`] over the query results for the given [`World`].
1181    ///
1182    /// This iterator is always guaranteed to return results from each matching entity once and only once.
1183    /// Iteration order is not guaranteed.
1184    #[inline]
1185    pub fn iter_mut<'w, 's>(&'s mut self, world: &'w mut World) -> QueryIter<'w, 's, D, F> {
1186        self.query_mut(world).iter_inner()
1187    }
1188
1189    /// Returns an [`Iterator`] over the query results for the given [`World`] without updating the query's archetypes.
1190    /// Archetypes must be manually updated before by using [`Self::update_archetypes`].
1191    ///
1192    /// This iterator is always guaranteed to return results from each matching entity once and only once.
1193    /// Iteration order is not guaranteed.
1194    ///
1195    /// This can only be called for read-only queries.
1196    #[inline]
1197    pub fn iter_manual<'w, 's>(&'s self, world: &'w World) -> QueryIter<'w, 's, D::ReadOnly, F> {
1198        self.query_manual(world).into_iter()
1199    }
1200
1201    /// Returns an [`Iterator`] over all possible combinations of `K` query results without repetition.
1202    /// This can only be called for read-only queries.
1203    ///
1204    /// A combination is an arrangement of a collection of items where order does not matter.
1205    ///
1206    /// `K` is the number of items that make up each subset, and the number of items returned by the iterator.
1207    /// `N` is the number of total entities output by query.
1208    ///
1209    /// For example, given the list [1, 2, 3, 4], where `K` is 2, the combinations without repeats are
1210    /// [1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4].
1211    /// And in this case, `N` would be defined as 4 since the size of the input list is 4.
1212    ///
1213    ///  For combinations of size `K` of query taking `N` inputs, you will get:
1214    /// - if `K == N`: one combination of all query results
1215    /// - if `K < N`: all possible `K`-sized combinations of query results, without repetition
1216    /// - if `K > N`: empty set (no `K`-sized combinations exist)
1217    ///
1218    /// The `iter_combinations` method does not guarantee order of iteration.
1219    ///
1220    /// This iterator is always guaranteed to return results from each unique pair of matching entities.
1221    /// Iteration order is not guaranteed.
1222    ///
1223    /// This can only be called for read-only queries, see [`Self::iter_combinations_mut`] for
1224    /// write-queries.
1225    #[inline]
1226    pub fn iter_combinations<'w, 's, const K: usize>(
1227        &'s mut self,
1228        world: &'w World,
1229    ) -> QueryCombinationIter<'w, 's, D::ReadOnly, F, K> {
1230        self.query(world).iter_combinations_inner()
1231    }
1232
1233    /// Returns an [`Iterator`] over all possible combinations of `K` query results without repetition.
1234    ///
1235    /// A combination is an arrangement of a collection of items where order does not matter.
1236    ///
1237    /// `K` is the number of items that make up each subset, and the number of items returned by the iterator.
1238    /// `N` is the number of total entities output by query.
1239    ///
1240    /// For example, given the list [1, 2, 3, 4], where `K` is 2, the combinations without repeats are
1241    /// [1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4].
1242    /// And in this case, `N` would be defined as 4 since the size of the input list is 4.
1243    ///
1244    ///  For combinations of size `K` of query taking `N` inputs, you will get:
1245    /// - if `K == N`: one combination of all query results
1246    /// - if `K < N`: all possible `K`-sized combinations of query results, without repetition
1247    /// - if `K > N`: empty set (no `K`-sized combinations exist)
1248    ///
1249    /// The `iter_combinations_mut` method does not guarantee order of iteration.
1250    #[inline]
1251    pub fn iter_combinations_mut<'w, 's, const K: usize>(
1252        &'s mut self,
1253        world: &'w mut World,
1254    ) -> QueryCombinationIter<'w, 's, D, F, K>
1255    where
1256        D: IterQueryData,
1257    {
1258        self.query_mut(world).iter_combinations_inner()
1259    }
1260
1261    /// Returns an [`Iterator`] over the read-only query items generated from an [`Entity`] list.
1262    ///
1263    /// Items are returned in the order of the list of entities.
1264    /// In case of a nonexisting entity or mismatched component, a [`QueryEntityError`] is generated instead.
1265    ///
1266    /// If you need to iterate multiple times at once but get borrowing errors,
1267    /// consider using [`Self::update_archetypes`] followed by multiple [`Self::iter_many_manual`] calls.
1268    ///
1269    /// # See also
1270    ///
1271    /// - [`iter_many_mut`](Self::iter_many_mut) to get mutable query items.
1272    #[inline]
1273    pub fn iter_many<'w, 's, EntityList: IntoIterator<Item: EntityEquivalent>>(
1274        &'s mut self,
1275        world: &'w World,
1276        entities: EntityList,
1277    ) -> QueryManyIter<'w, 's, D::ReadOnly, F, EntityList::IntoIter> {
1278        self.query(world).iter_many_inner(entities)
1279    }
1280
1281    /// Returns an [`Iterator`] over the read-only query items generated from an [`Entity`] list.
1282    ///
1283    /// Items are returned in the order of the list of entities.
1284    /// In case of a nonexisting entity or mismatched component, a [`QueryEntityError`] is generated instead.
1285    ///
1286    /// If `world` archetypes changed since [`Self::update_archetypes`] was last called,
1287    /// this will skip entities contained in new archetypes.
1288    ///
1289    /// This can only be called for read-only queries.
1290    ///
1291    /// # See also
1292    ///
1293    /// - [`iter_many`](Self::iter_many) to update archetypes.
1294    /// - [`iter_manual`](Self::iter_manual) to iterate over all query items.
1295    #[inline]
1296    pub fn iter_many_manual<'w, 's, EntityList: IntoIterator<Item: EntityEquivalent>>(
1297        &'s self,
1298        world: &'w World,
1299        entities: EntityList,
1300    ) -> QueryManyIter<'w, 's, D::ReadOnly, F, EntityList::IntoIter> {
1301        self.query_manual(world).iter_many_inner(entities)
1302    }
1303
1304    /// Returns an iterator over the query items generated from an [`Entity`] list.
1305    ///
1306    /// Items are returned in the order of the list of entities.
1307    /// In case of a nonexisting entity or mismatched component, a [`QueryEntityError`] is generated instead.
1308    #[inline]
1309    pub fn iter_many_mut<'w, 's, EntityList: IntoIterator<Item: EntityEquivalent>>(
1310        &'s mut self,
1311        world: &'w mut World,
1312        entities: EntityList,
1313    ) -> QueryManyIter<'w, 's, D, F, EntityList::IntoIter> {
1314        self.query_mut(world).iter_many_inner(entities)
1315    }
1316
1317    /// Returns an [`Iterator`] over the unique read-only query items generated from an [`EntitySet`].
1318    ///
1319    /// Items are returned in the order of the list of entities.
1320    /// In case of a nonexisting entity or mismatched component, a [`QueryEntityError`] is generated instead.
1321    ///
1322    /// # See also
1323    ///
1324    /// - [`iter_many_unique_mut`](Self::iter_many_unique_mut) to get mutable query items.
1325    #[inline]
1326    pub fn iter_many_unique<'w, 's, EntityList: EntitySet>(
1327        &'s mut self,
1328        world: &'w World,
1329        entities: EntityList,
1330    ) -> QueryManyUniqueIter<'w, 's, D::ReadOnly, F, EntityList::IntoIter> {
1331        self.query(world).iter_many_unique_inner(entities)
1332    }
1333
1334    /// Returns an [`Iterator`] over the unique read-only query items generated from an [`EntitySet`].
1335    ///
1336    /// Items are returned in the order of the list of entities.
1337    /// In case of a nonexisting entity or mismatched component, a [`QueryEntityError`] is generated instead.
1338    ///
1339    /// If `world` archetypes changed since [`Self::update_archetypes`] was last called,
1340    /// this will skip entities contained in new archetypes.
1341    ///
1342    /// This can only be called for read-only queries.
1343    ///
1344    /// # See also
1345    ///
1346    /// - [`iter_many_unique`](Self::iter_many) to update archetypes.
1347    /// - [`iter_many`](Self::iter_many) to iterate over a non-unique entity list.
1348    /// - [`iter_manual`](Self::iter_manual) to iterate over all query items.
1349    #[inline]
1350    pub fn iter_many_unique_manual<'w, 's, EntityList: EntitySet>(
1351        &'s self,
1352        world: &'w World,
1353        entities: EntityList,
1354    ) -> QueryManyUniqueIter<'w, 's, D::ReadOnly, F, EntityList::IntoIter> {
1355        self.query_manual(world).iter_many_unique_inner(entities)
1356    }
1357
1358    /// Returns an iterator over the unique query items generated from an [`EntitySet`].
1359    ///
1360    /// Items are returned in the order of the list of entities.
1361    /// In case of a nonexisting entity or mismatched component, a [`QueryEntityError`] is generated instead.
1362    #[inline]
1363    pub fn iter_many_unique_mut<'w, 's, EntityList: EntitySet>(
1364        &'s mut self,
1365        world: &'w mut World,
1366        entities: EntityList,
1367    ) -> QueryManyUniqueIter<'w, 's, D, F, EntityList::IntoIter>
1368    where
1369        D: IterQueryData,
1370    {
1371        self.query_mut(world).iter_many_unique_inner(entities)
1372    }
1373    /// Returns an [`Iterator`] over the query results for the given [`World`].
1374    ///
1375    /// This iterator is always guaranteed to return results from each matching entity once and only once.
1376    /// Iteration order is not guaranteed.
1377    ///
1378    /// # Safety
1379    ///
1380    /// This does not check for mutable query correctness. To be safe, make sure mutable queries
1381    /// have unique access to the components they query.
1382    #[inline]
1383    pub unsafe fn iter_unchecked<'w, 's>(
1384        &'s mut self,
1385        world: UnsafeWorldCell<'w>,
1386    ) -> QueryIter<'w, 's, D, F> {
1387        // SAFETY: Upheld by caller
1388        unsafe { self.query_unchecked(world) }.iter_inner()
1389    }
1390
1391    /// Returns an [`Iterator`] over all possible combinations of `K` query results for the
1392    /// given [`World`] without repetition.
1393    /// This can only be called for read-only queries.
1394    ///
1395    /// This iterator is always guaranteed to return results from each unique pair of matching entities.
1396    /// Iteration order is not guaranteed.
1397    ///
1398    /// # Safety
1399    ///
1400    /// This does not check for mutable query correctness. To be safe, make sure mutable queries
1401    /// have unique access to the components they query.
1402    #[inline]
1403    pub unsafe fn iter_combinations_unchecked<'w, 's, const K: usize>(
1404        &'s mut self,
1405        world: UnsafeWorldCell<'w>,
1406    ) -> QueryCombinationIter<'w, 's, D, F, K>
1407    where
1408        D: IterQueryData,
1409    {
1410        // SAFETY: Upheld by caller
1411        unsafe { self.query_unchecked(world) }.iter_combinations_inner()
1412    }
1413
1414    /// Returns a parallel iterator over the query results for the given [`World`].
1415    ///
1416    /// This can only be called for read-only queries, see [`par_iter_mut`] for write-queries.
1417    ///
1418    /// Note that you must use the `for_each` method to iterate over the
1419    /// results, see [`par_iter_mut`] for an example.
1420    ///
1421    /// [`par_iter_mut`]: Self::par_iter_mut
1422    #[inline]
1423    pub fn par_iter<'w, 's>(
1424        &'s mut self,
1425        world: &'w World,
1426    ) -> QueryParIter<'w, 's, D::ReadOnly, F> {
1427        self.query(world).par_iter_inner()
1428    }
1429
1430    /// Returns a parallel iterator over the query results for the given [`World`].
1431    ///
1432    /// This can only be called for mutable queries, see [`par_iter`] for read-only-queries.
1433    ///
1434    /// # Examples
1435    ///
1436    /// ```
1437    /// use bevy_ecs::prelude::*;
1438    /// use bevy_ecs::query::QueryEntityError;
1439    ///
1440    /// #[derive(Component, PartialEq, Debug)]
1441    /// struct A(usize);
1442    ///
1443    /// # bevy_tasks::ComputeTaskPool::get_or_init(|| bevy_tasks::TaskPool::new());
1444    ///
1445    /// let mut world = World::new();
1446    ///
1447    /// # let entities: Vec<Entity> = (0..3).map(|i| world.spawn(A(i)).id()).collect();
1448    /// # let entities: [Entity; 3] = entities.try_into().unwrap();
1449    ///
1450    /// let mut query_state = world.query::<&mut A>();
1451    ///
1452    /// query_state.par_iter_mut(&mut world).for_each(|mut a| {
1453    ///     a.0 += 5;
1454    /// });
1455    ///
1456    /// # let component_values = query_state.get_many(&world, entities).unwrap();
1457    ///
1458    /// # assert_eq!(component_values, [&A(5), &A(6), &A(7)]);
1459    ///
1460    /// # let wrong_entity = Entity::from_raw_u32(57).unwrap();
1461    /// # let invalid_entity = world.spawn_empty().id();
1462    ///
1463    /// # assert_eq!(match query_state.get_many(&mut world, [wrong_entity]).unwrap_err() {QueryEntityError::NotSpawned(error) => error.entity(), _ => panic!()}, wrong_entity);
1464    /// assert_eq!(match query_state.get_many_mut(&mut world, [invalid_entity]).unwrap_err() {QueryEntityError::QueryDoesNotMatch(entity, _) => entity, _ => panic!()}, invalid_entity);
1465    /// # assert_eq!(query_state.get_many_mut(&mut world, [entities[0], entities[0]]).unwrap_err(), QueryEntityError::AliasedMutability(entities[0]));
1466    /// ```
1467    ///
1468    /// # Panics
1469    /// The [`ComputeTaskPool`] is not initialized. If using this from a query that is being
1470    /// initialized and run from the ECS scheduler, this should never panic.
1471    ///
1472    /// [`par_iter`]: Self::par_iter
1473    /// [`ComputeTaskPool`]: bevy_tasks::ComputeTaskPool
1474    #[inline]
1475    pub fn par_iter_mut<'w, 's>(&'s mut self, world: &'w mut World) -> QueryParIter<'w, 's, D, F>
1476    where
1477        D: IterQueryData,
1478    {
1479        self.query_mut(world).par_iter_inner()
1480    }
1481
1482    /// Returns a contiguous iterator over the query results for the given [`World`] or [`Err`] with [`QueryNotDenseError`] if
1483    /// the query is not dense hence not contiguously iterable.
1484    #[inline]
1485    pub fn contiguous_iter<'w, 's>(
1486        &'s mut self,
1487        world: &'w World,
1488    ) -> Result<QueryContiguousIter<'w, 's, D::ReadOnly, F>, QueryNotDenseError>
1489    where
1490        D::ReadOnly: ContiguousQueryData,
1491        F: ArchetypeFilter,
1492    {
1493        self.query(world).contiguous_iter_inner()
1494    }
1495
1496    /// Returns a contiguous iterator over the query results for the given [`World`] or [`Err`] with [`QueryNotDenseError`] if
1497    /// the query is not dense hence not contiguously iterable.
1498    ///
1499    /// This can only be called for mutable queries, see [`Self::contiguous_iter`] for read-only-queries.
1500    #[inline]
1501    pub fn contiguous_iter_mut<'w, 's>(
1502        &'s mut self,
1503        world: &'w mut World,
1504    ) -> Result<QueryContiguousIter<'w, 's, D, F>, QueryNotDenseError>
1505    where
1506        D: ContiguousQueryData,
1507        F: ArchetypeFilter,
1508    {
1509        self.query_mut(world).contiguous_iter_inner()
1510    }
1511
1512    /// Returns a parallel contiguous iterator over the query results for the
1513    /// given [`World`] or [`Err`] with [`QueryNotDenseError`] if the query is
1514    /// not dense hence not contiguously iterable.
1515    ///
1516    /// This can only be called for read-only queries. See
1517    /// [`Self::contiguous_par_iter_mut`] for queries that may write to the
1518    /// components.
1519    ///
1520    /// Note that you must use the [`QueryContiguousParIter::for_each`] method
1521    /// to iterate over the results. See [`Self::contiguous_par_iter_mut`] for
1522    /// an example.
1523    ///
1524    /// # Panics
1525    /// The [`ComputeTaskPool`] is not initialized. If using this from a query
1526    /// that is being initialized and run from the ECS scheduler, this should
1527    /// never panic.
1528    ///
1529    /// [`ComputeTaskPool`]: bevy_tasks::ComputeTaskPool
1530    #[inline]
1531    pub fn contiguous_par_iter<'w, 's>(
1532        &'s mut self,
1533        world: &'w World,
1534    ) -> Result<QueryContiguousParIter<'w, 's, D::ReadOnly, F>, QueryNotDenseError>
1535    where
1536        D::ReadOnly: ContiguousQueryData,
1537        F: ArchetypeFilter,
1538    {
1539        self.query(world).contiguous_par_iter_inner()
1540    }
1541
1542    /// Returns a parallel contiguous iterator over the query results for the
1543    /// given [`World`] or [`Err`] with [`QueryNotDenseError`] if the query is
1544    /// not dense hence not contiguously iterable.
1545    ///
1546    /// This version of the method is for mutable queries. For read-only
1547    /// queries, see [`Self::contiguous_par_iter`].
1548    ///
1549    /// # Examples
1550    ///
1551    /// ```
1552    /// use bevy_ecs::prelude::*;
1553    /// use bevy_ecs::query::QueryEntityError;
1554    ///
1555    /// #[derive(Component, PartialEq, Debug)]
1556    /// struct A(usize);
1557    ///
1558    /// # bevy_tasks::ComputeTaskPool::get_or_init(|| bevy_tasks::TaskPool::new());
1559    ///
1560    /// let mut world = World::new();
1561    ///
1562    /// # let entities: Vec<Entity> = (0..3).map(|i| world.spawn(A(i)).id()).collect();
1563    /// # let entities: [Entity; 3] = entities.try_into().unwrap();
1564    ///
1565    /// let mut query_state = world.query::<&mut A>();
1566    ///
1567    /// query_state.contiguous_par_iter_mut(&mut world).unwrap().for_each(|mut batch| {
1568    ///     for a in batch {
1569    ///         a.0 += 5;
1570    ///     }
1571    /// });
1572    ///
1573    /// # let component_values = query_state.get_many(&world, entities).unwrap();
1574    ///
1575    /// # assert_eq!(component_values, [&A(5), &A(6), &A(7)]);
1576    ///
1577    /// # let wrong_entity = Entity::from_raw_u32(57).unwrap();
1578    /// # let invalid_entity = world.spawn_empty().id();
1579    ///
1580    /// # assert_eq!(match query_state.get_many(&mut world, [wrong_entity]).unwrap_err() {QueryEntityError::NotSpawned(error) => error.entity(), _ => panic!()}, wrong_entity);
1581    /// assert_eq!(match query_state.get_many_mut(&mut world, [invalid_entity]).unwrap_err() {QueryEntityError::QueryDoesNotMatch(entity, _) => entity, _ => panic!()}, invalid_entity);
1582    /// # assert_eq!(query_state.get_many_mut(&mut world, [entities[0], entities[0]]).unwrap_err(), QueryEntityError::AliasedMutability(entities[0]));
1583    /// ```
1584    ///
1585    /// # Panics
1586    /// The [`ComputeTaskPool`] is not initialized. If using this from a query
1587    /// that is being initialized and run from the ECS scheduler, this should
1588    /// never panic.
1589    ///
1590    /// [`ComputeTaskPool`]: bevy_tasks::ComputeTaskPool
1591    #[inline]
1592    pub fn contiguous_par_iter_mut<'w, 's>(
1593        &'s mut self,
1594        world: &'w mut World,
1595    ) -> Result<QueryContiguousParIter<'w, 's, D, F>, QueryNotDenseError>
1596    where
1597        D: ContiguousQueryData,
1598        F: ArchetypeFilter,
1599    {
1600        self.query_mut(world).contiguous_par_iter_inner()
1601    }
1602
1603    /// Runs `func` on each query result in parallel for the given [`World`], where the last change and
1604    /// the current change tick are given. This is faster than the equivalent
1605    /// `iter()` method, but cannot be chained like a normal [`Iterator`].
1606    ///
1607    /// # Panics
1608    /// The [`ComputeTaskPool`] is not initialized. If using this from a query that is being
1609    /// initialized and run from the ECS scheduler, this should never panic.
1610    ///
1611    /// # Safety
1612    ///
1613    /// This does not check for mutable query correctness. To be safe, make sure mutable queries
1614    /// have unique access to the components they query.
1615    /// This does not validate that `world.id()` matches `self.world_id`. Calling this on a `world`
1616    /// with a mismatched [`WorldId`] is unsound.
1617    ///
1618    /// [`ComputeTaskPool`]: bevy_tasks::ComputeTaskPool
1619    #[cfg(all(not(target_arch = "wasm32"), feature = "multi_threaded"))]
1620    pub(crate) unsafe fn par_fold_init_unchecked_manual<'w, 's, T, FN, INIT>(
1621        &'s self,
1622        init_accum: INIT,
1623        world: UnsafeWorldCell<'w>,
1624        batch_size: u32,
1625        func: FN,
1626        last_run: Tick,
1627        this_run: Tick,
1628    ) where
1629        FN: Fn(T, D::Item<'w, 's>) -> T + Send + Sync + Clone,
1630        INIT: Fn() -> T + Sync + Send + Clone,
1631        D: IterQueryData,
1632    {
1633        // NOTE: If you are changing query iteration code, remember to update the following places, where relevant:
1634        // QueryIter, QueryIterationCursor, QueryManyIter, QueryCombinationIter,QueryState::par_fold_init_unchecked_manual,
1635        // QueryState::par_many_fold_init_unchecked_manual, QueryState::par_many_unique_fold_init_unchecked_manual, QueryContiguousIter::next
1636        use arrayvec::ArrayVec;
1637
1638        bevy_tasks::ComputeTaskPool::get().scope(|scope| {
1639            // SAFETY: We only access table data that has been registered in `self.component_access`.
1640            let tables = unsafe { &world.storages().tables };
1641            let archetypes = world.archetypes();
1642            let mut batch_queue = ArrayVec::new();
1643            let mut queue_entity_count = 0;
1644
1645            // submit a list of storages which smaller than batch_size as single task
1646            let submit_batch_queue = |queue: &mut ArrayVec<StorageId, 128>| {
1647                if queue.is_empty() {
1648                    return;
1649                }
1650                let queue = core::mem::take(queue);
1651                let mut func = func.clone();
1652                let init_accum = init_accum.clone();
1653                scope.spawn(async move {
1654                    #[cfg(feature = "trace")]
1655                    let _span = self.par_iter_span.enter();
1656                    let mut iter = self
1657                        .query_unchecked_manual_with_ticks(world, last_run, this_run)
1658                        .into_iter();
1659                    let mut accum = init_accum();
1660                    for storage_id in queue {
1661                        accum = iter.fold_over_storage_range(accum, &mut func, storage_id, None);
1662                    }
1663                });
1664            };
1665
1666            // submit single storage larger than batch_size
1667            let submit_single = |count, storage_id: StorageId| {
1668                for offset in (0..count).step_by(batch_size as usize) {
1669                    let mut func = func.clone();
1670                    let init_accum = init_accum.clone();
1671                    let len = batch_size.min(count - offset);
1672                    let batch = offset..offset + len;
1673                    scope.spawn(async move {
1674                        #[cfg(feature = "trace")]
1675                        let _span = self.par_iter_span.enter();
1676                        let accum = init_accum();
1677                        self.query_unchecked_manual_with_ticks(world, last_run, this_run)
1678                            .into_iter()
1679                            .fold_over_storage_range(accum, &mut func, storage_id, Some(batch));
1680                    });
1681                }
1682            };
1683
1684            let storage_entity_count = |storage_id: StorageId| -> u32 {
1685                if self.is_dense {
1686                    tables[storage_id.table_id].entity_count()
1687                } else {
1688                    archetypes[storage_id.archetype_id].len()
1689                }
1690            };
1691
1692            for storage_id in &self.matched_storage_ids {
1693                let count = storage_entity_count(*storage_id);
1694
1695                // skip empty storage
1696                if count == 0 {
1697                    continue;
1698                }
1699                // immediately submit large storage
1700                if count >= batch_size {
1701                    submit_single(count, *storage_id);
1702                    continue;
1703                }
1704                // merge small storage
1705                batch_queue.push(*storage_id);
1706                queue_entity_count += count;
1707
1708                // submit batch_queue
1709                if queue_entity_count >= batch_size || batch_queue.is_full() {
1710                    submit_batch_queue(&mut batch_queue);
1711                    queue_entity_count = 0;
1712                }
1713            }
1714            submit_batch_queue(&mut batch_queue);
1715        });
1716    }
1717
1718    /// Runs `func` on each query result in parallel for the given [`EntitySet`],
1719    /// where the last change and the current change tick are given. This is faster than the
1720    /// equivalent `iter_many_unique()` method, but cannot be chained like a normal [`Iterator`].
1721    ///
1722    /// # Panics
1723    /// The [`ComputeTaskPool`] is not initialized. If using this from a query that is being
1724    /// initialized and run from the ECS scheduler, this should never panic.
1725    ///
1726    /// # Safety
1727    ///
1728    /// This does not check for mutable query correctness. To be safe, make sure mutable queries
1729    /// have unique access to the components they query.
1730    /// This does not validate that `world.id()` matches `self.world_id`. Calling this on a `world`
1731    /// with a mismatched [`WorldId`] is unsound.
1732    ///
1733    /// [`ComputeTaskPool`]: bevy_tasks::ComputeTaskPool
1734    #[cfg(all(not(target_arch = "wasm32"), feature = "multi_threaded"))]
1735    pub(crate) unsafe fn par_many_unique_fold_init_unchecked_manual<'w, 's, T, FN, INIT, E>(
1736        &'s self,
1737        init_accum: INIT,
1738        world: UnsafeWorldCell<'w>,
1739        entity_list: &UniqueEntityEquivalentSlice<E>,
1740        batch_size: u32,
1741        mut func: FN,
1742        last_run: Tick,
1743        this_run: Tick,
1744    ) where
1745        FN: Fn(T, Result<D::Item<'w, 's>, QueryEntityError>) -> T + Send + Sync + Clone,
1746        INIT: Fn() -> T + Sync + Send + Clone,
1747        E: EntityEquivalent + Sync,
1748        D: IterQueryData,
1749    {
1750        // NOTE: If you are changing query iteration code, remember to update the following places, where relevant:
1751        // QueryIter, QueryIterationCursor, QueryManyIter, QueryCombinationIter,QueryState::par_fold_init_unchecked_manual
1752        // QueryState::par_many_fold_init_unchecked_manual, QueryState::par_many_unique_fold_init_unchecked_manual, QueryContiguousIter::next
1753
1754        bevy_tasks::ComputeTaskPool::get().scope(|scope| {
1755            let chunks = entity_list.chunks_exact(batch_size as usize);
1756            let remainder = chunks.remainder();
1757
1758            for batch in chunks {
1759                let mut func = func.clone();
1760                let init_accum = init_accum.clone();
1761                scope.spawn(async move {
1762                    #[cfg(feature = "trace")]
1763                    let _span = self.par_iter_span.enter();
1764                    let accum = init_accum();
1765                    self.query_unchecked_manual_with_ticks(world, last_run, this_run)
1766                        .iter_many_unique_inner(batch)
1767                        .fold(accum, &mut func);
1768                });
1769            }
1770
1771            #[cfg(feature = "trace")]
1772            let _span = self.par_iter_span.enter();
1773            let accum = init_accum();
1774            self.query_unchecked_manual_with_ticks(world, last_run, this_run)
1775                .iter_many_unique_inner(remainder)
1776                .fold(accum, &mut func);
1777        });
1778    }
1779
1780    #[cfg(all(not(target_arch = "wasm32"), feature = "multi_threaded"))]
1781    pub(crate) unsafe fn contiguous_par_fold_init_unchecked_manual<'w, 's, T>(
1782        &'s self,
1783        init_accum: impl Fn() -> T + Send + Sync + Clone,
1784        world: UnsafeWorldCell<'w>,
1785        batch_size: u32,
1786        func: impl Fn(T, D::Contiguous<'w, 's>) -> T + Send + Sync + Clone,
1787        last_run: Tick,
1788        this_run: Tick,
1789    ) where
1790        D: ContiguousQueryData,
1791        F: ArchetypeFilter,
1792    {
1793        debug_assert!(self.is_dense);
1794
1795        // The maximum number of tables we can accumulate before we must flush
1796        // them into a batch.
1797        const MAX_TABLES_PER_BATCH: usize = 32;
1798
1799        bevy_tasks::ComputeTaskPool::get().scope(|scope| {
1800            use core::ops::Range;
1801
1802            use smallvec::SmallVec;
1803
1804            // SAFETY: We only access table data that has been registered in
1805            // `self.component_access`.
1806            let tables = unsafe { &world.storages().tables };
1807
1808            // Unlike ordinary parallel iteration, contiguous iteration uses a
1809            // unified queuing system that accumulates row *ranges* from
1810            // multiple tables, not tables as a whole. This allows individual
1811            // jobs to include any combination of entire tables and portions of
1812            // tables.
1813            let mut batch_queue: SmallVec<[(TableId, Range<u32>); 4]> = SmallVec::new();
1814            let mut queue_entity_count = 0;
1815
1816            // Submits a full batch.
1817            let submit_batch_queue = |queue: SmallVec<[(TableId, Range<u32>); 4]>| {
1818                let (func, init_accum) = (func.clone(), init_accum.clone());
1819                scope.spawn(async move {
1820                    #[cfg(feature = "trace")]
1821                    let _span = self.par_iter_span.enter();
1822                    // SAFETY: Contiguous iteration can only process tables, so
1823                    // we must have a table here.
1824                    let tables = unsafe { &world.storages().tables };
1825                    let mut fetch = D::init_fetch(world, &self.fetch_state, last_run, this_run);
1826                    let mut accum = init_accum();
1827                    for (table_id, range) in queue {
1828                        let table = &tables[table_id];
1829                        D::set_table(&mut fetch, &self.fetch_state, table);
1830                        let item = D::fetch_contiguous(
1831                            &self.fetch_state,
1832                            &mut fetch,
1833                            table.entities(),
1834                            range,
1835                        );
1836                        accum = func(accum, item);
1837                    }
1838                });
1839            };
1840
1841            // Go over all the tables.
1842            for storage_id in &self.matched_storage_ids {
1843                let table_id = storage_id.table_id;
1844                let row_count = tables[table_id].entity_count();
1845
1846                // Accumulate rows until we either hit the `batch_size` or hit
1847                // the maximum number of tables.
1848                let mut row_start_offset = 0;
1849                while row_start_offset < row_count {
1850                    // If we hit the maximum number of tables, force a submit.
1851                    if batch_queue.len() == MAX_TABLES_PER_BATCH {
1852                        submit_batch_queue(core::mem::take(&mut batch_queue));
1853                        queue_entity_count = 0;
1854                    }
1855
1856                    // Can we include the entire remainder of the table, or do
1857                    // we need to split it?
1858                    if queue_entity_count + row_count - row_start_offset > batch_size {
1859                        // We need to split the table. Push the portion that fits.
1860                        let row_end_offset = row_start_offset + (batch_size - queue_entity_count);
1861                        batch_queue.push((table_id, row_start_offset..row_end_offset));
1862                        row_start_offset = row_end_offset;
1863
1864                        // And submit it.
1865                        submit_batch_queue(core::mem::take(&mut batch_queue));
1866                        queue_entity_count = 0;
1867                    } else {
1868                        // We can fit the entire remainder of the table.
1869                        batch_queue.push((table_id, row_start_offset..row_count));
1870                        queue_entity_count += row_count - row_start_offset;
1871                        break;
1872                    }
1873                }
1874            }
1875
1876            // If we have any rows left over, submit them now.
1877            if !batch_queue.is_empty() {
1878                submit_batch_queue(batch_queue);
1879            }
1880        });
1881    }
1882}
1883
1884impl<D: ReadOnlyQueryData, F: QueryFilter> QueryState<D, F> {
1885    /// Runs `func` on each read-only query result in parallel for the given [`Entity`] list,
1886    /// where the last change and the current change tick are given. This is faster than the equivalent
1887    /// `iter_many()` method, but cannot be chained like a normal [`Iterator`].
1888    ///
1889    /// # Panics
1890    /// The [`ComputeTaskPool`] is not initialized. If using this from a query that is being
1891    /// initialized and run from the ECS scheduler, this should never panic.
1892    ///
1893    /// # Safety
1894    ///
1895    /// This does not check for mutable query correctness. To be safe, make sure mutable queries
1896    /// have unique access to the components they query.
1897    /// This does not validate that `world.id()` matches `self.world_id`. Calling this on a `world`
1898    /// with a mismatched [`WorldId`] is unsound.
1899    ///
1900    /// [`ComputeTaskPool`]: bevy_tasks::ComputeTaskPool
1901    #[cfg(all(not(target_arch = "wasm32"), feature = "multi_threaded"))]
1902    pub(crate) unsafe fn par_many_fold_init_unchecked_manual<'w, 's, T, FN, INIT, E>(
1903        &'s self,
1904        init_accum: INIT,
1905        world: UnsafeWorldCell<'w>,
1906        entity_list: &[E],
1907        batch_size: u32,
1908        mut func: FN,
1909        last_run: Tick,
1910        this_run: Tick,
1911    ) where
1912        FN: Fn(T, Result<D::Item<'w, 's>, QueryEntityError>) -> T + Send + Sync + Clone,
1913        INIT: Fn() -> T + Sync + Send + Clone,
1914        E: EntityEquivalent + Sync,
1915    {
1916        // NOTE: If you are changing query iteration code, remember to update the following places, where relevant:
1917        // QueryIter, QueryIterationCursor, QueryManyIter, QueryCombinationIter, QueryState::par_fold_init_unchecked_manual
1918        // QueryState::par_many_fold_init_unchecked_manual, QueryState::par_many_unique_fold_init_unchecked_manual, QueryContiguousIter::next
1919
1920        bevy_tasks::ComputeTaskPool::get().scope(|scope| {
1921            let chunks = entity_list.chunks_exact(batch_size as usize);
1922            let remainder = chunks.remainder();
1923
1924            for batch in chunks {
1925                let mut func = func.clone();
1926                let init_accum = init_accum.clone();
1927                scope.spawn(async move {
1928                    #[cfg(feature = "trace")]
1929                    let _span = self.par_iter_span.enter();
1930                    let accum = init_accum();
1931                    self.query_unchecked_manual_with_ticks(world, last_run, this_run)
1932                        .iter_many_inner(batch)
1933                        .fold(accum, &mut func);
1934                });
1935            }
1936
1937            #[cfg(feature = "trace")]
1938            let _span = self.par_iter_span.enter();
1939            let accum = init_accum();
1940            self.query_unchecked_manual_with_ticks(world, last_run, this_run)
1941                .iter_many_inner(remainder)
1942                .fold(accum, &mut func);
1943        });
1944    }
1945}
1946
1947impl<D: QueryData, F: QueryFilter> QueryState<D, F> {
1948    /// Returns a single immutable query result when there is exactly one entity matching
1949    /// the query.
1950    ///
1951    /// This can only be called for read-only queries,
1952    /// see [`single_mut`](Self::single_mut) for write-queries.
1953    ///
1954    /// If the number of query results is not exactly one, a [`QuerySingleError`] is returned
1955    /// instead.
1956    ///
1957    /// # Example
1958    ///
1959    /// Sometimes, you might want to handle the error in a specific way,
1960    /// generally by spawning the missing entity.
1961    ///
1962    /// ```rust
1963    /// use bevy_ecs::prelude::*;
1964    /// use bevy_ecs::query::QuerySingleError;
1965    ///
1966    /// #[derive(Component)]
1967    /// struct A(usize);
1968    ///
1969    /// fn my_system(query: Query<&A>, mut commands: Commands) {
1970    ///     match query.single() {
1971    ///         Ok(a) => (), // Do something with `a`
1972    ///         Err(err) => match err {
1973    ///             QuerySingleError::NoEntities(_) => {
1974    ///                 commands.spawn(A(0));
1975    ///             }
1976    ///             QuerySingleError::MultipleEntities(_) => panic!("Multiple entities found!"),
1977    ///         },
1978    ///     }
1979    /// }
1980    /// ```
1981    ///
1982    /// However in most cases, this error can simply be handled with a graceful early return.
1983    /// If this is an expected failure mode, you can do this using the `let else` pattern like so:
1984    /// ```rust
1985    /// use bevy_ecs::prelude::*;
1986    ///
1987    /// #[derive(Component)]
1988    /// struct A(usize);
1989    ///
1990    /// fn my_system(query: Query<&A>) {
1991    ///   let Ok(a) = query.single() else {
1992    ///     return;
1993    ///   };
1994    ///
1995    ///   // Do something with `a`
1996    /// }
1997    /// ```
1998    ///
1999    /// If this is unexpected though, you should probably use the `?` operator
2000    /// in combination with Bevy's error handling apparatus.
2001    ///
2002    /// ```rust
2003    /// use bevy_ecs::prelude::*;
2004    ///
2005    /// #[derive(Component)]
2006    /// struct A(usize);
2007    ///
2008    /// fn my_system(query: Query<&A>) -> Result {
2009    ///  let a = query.single()?;
2010    ///
2011    ///  // Do something with `a`
2012    ///  Ok(())
2013    /// }
2014    /// ```
2015    ///
2016    /// This allows you to globally control how errors are handled in your application,
2017    /// by setting up a custom error handler.
2018    /// See the [`bevy_ecs::error`] module docs for more information!
2019    /// Commonly, you might want to panic on an error during development, but log the error and continue
2020    /// execution in production.
2021    ///
2022    /// Simply unwrapping the [`Result`] also works, but should generally be reserved for tests.
2023    #[inline]
2024    pub fn single<'w>(
2025        &mut self,
2026        world: &'w World,
2027    ) -> Result<ROQueryItem<'w, '_, D>, QuerySingleError> {
2028        self.query(world).single_inner()
2029    }
2030
2031    /// Returns a single mutable query result when there is exactly one entity matching
2032    /// the query.
2033    ///
2034    /// If the number of query results is not exactly one, a [`QuerySingleError`] is returned
2035    /// instead.
2036    ///
2037    /// # Examples
2038    ///
2039    /// Please see [`Query::single`] for advice on handling the error.
2040    #[inline]
2041    pub fn single_mut<'w>(
2042        &mut self,
2043        world: &'w mut World,
2044    ) -> Result<D::Item<'w, '_>, QuerySingleError>
2045    where
2046        D: IterQueryData,
2047    {
2048        self.query_mut(world).single_inner()
2049    }
2050
2051    /// Returns a query result when there is exactly one entity matching the query.
2052    ///
2053    /// If the number of query results is not exactly one, a [`QuerySingleError`] is returned
2054    /// instead.
2055    ///
2056    /// # Safety
2057    ///
2058    /// This does not check for mutable query correctness. To be safe, make sure mutable queries
2059    /// have unique access to the components they query.
2060    #[inline]
2061    pub unsafe fn single_unchecked<'w>(
2062        &mut self,
2063        world: UnsafeWorldCell<'w>,
2064    ) -> Result<D::Item<'w, '_>, QuerySingleError>
2065    where
2066        D: IterQueryData,
2067    {
2068        // SAFETY: Upheld by caller
2069        unsafe { self.query_unchecked(world) }.single_inner()
2070    }
2071
2072    /// Returns a query result when there is exactly one entity matching the query,
2073    /// where the last change and the current change tick are given.
2074    ///
2075    /// If the number of query results is not exactly one, a [`QuerySingleError`] is returned
2076    /// instead.
2077    ///
2078    /// # Safety
2079    ///
2080    /// This does not check for mutable query correctness. To be safe, make sure mutable queries
2081    /// have unique access to the components they query.
2082    /// This does not validate that `world.id()` matches `self.world_id`. Calling this on a `world`
2083    /// with a mismatched [`WorldId`] is unsound.
2084    #[inline]
2085    pub unsafe fn single_unchecked_manual<'w>(
2086        &self,
2087        world: UnsafeWorldCell<'w>,
2088        last_run: Tick,
2089        this_run: Tick,
2090    ) -> Result<D::Item<'w, '_>, QuerySingleError>
2091    where
2092        D: IterQueryData,
2093    {
2094        // SAFETY:
2095        // - The caller ensured we have the correct access to the world.
2096        // - The caller ensured that the world matches.
2097        unsafe { self.query_unchecked_manual_with_ticks(world, last_run, this_run) }.single_inner()
2098    }
2099}
2100
2101impl<D: QueryData, F: QueryFilter> From<QueryBuilder<'_, D, F>> for QueryState<D, F> {
2102    fn from(mut value: QueryBuilder<D, F>) -> Self {
2103        QueryState::from_builder(&mut value)
2104    }
2105}
2106
2107#[cfg(test)]
2108mod tests {
2109    use crate::{
2110        component::Component,
2111        entity_disabling::DefaultQueryFilters,
2112        prelude::*,
2113        system::{QueryLens, RunSystemOnce},
2114        world::{EntityRef, FilteredEntityMut, FilteredEntityRef},
2115    };
2116
2117    #[test]
2118    #[should_panic]
2119    fn right_world_get() {
2120        let mut world_1 = World::new();
2121        let world_2 = World::new();
2122
2123        let mut query_state = world_1.query::<Entity>();
2124        let _panics = query_state.get(&world_2, Entity::from_raw_u32(0).unwrap());
2125    }
2126
2127    #[test]
2128    #[should_panic]
2129    fn right_world_get_many() {
2130        let mut world_1 = World::new();
2131        let world_2 = World::new();
2132
2133        let mut query_state = world_1.query::<Entity>();
2134        let _panics = query_state.get_many(&world_2, []);
2135    }
2136
2137    #[test]
2138    #[should_panic]
2139    fn right_world_get_many_mut() {
2140        let mut world_1 = World::new();
2141        let mut world_2 = World::new();
2142
2143        let mut query_state = world_1.query::<Entity>();
2144        let _panics = query_state.get_many_mut(&mut world_2, []);
2145    }
2146
2147    #[derive(Component, PartialEq, Debug)]
2148    struct A(usize);
2149
2150    #[derive(Component, PartialEq, Debug)]
2151    struct B(usize);
2152
2153    #[derive(Component, PartialEq, Debug)]
2154    struct C(usize);
2155
2156    #[derive(Component)]
2157    struct D;
2158
2159    #[test]
2160    fn can_transmute_to_more_general() {
2161        let mut world = World::new();
2162        world.spawn((A(1), B(0)));
2163
2164        let query_state = world.query::<(&A, &B)>();
2165        let mut new_query_state = query_state.transmute::<&A>(&world);
2166        assert_eq!(new_query_state.iter(&world).len(), 1);
2167        let a = new_query_state.single(&world).unwrap();
2168
2169        assert_eq!(a.0, 1);
2170    }
2171
2172    #[test]
2173    fn cannot_get_data_not_in_original_query() {
2174        let mut world = World::new();
2175        world.spawn((A(0), B(0)));
2176        world.spawn((A(1), B(0), C(0)));
2177
2178        let query_state = world.query_filtered::<(&A, &B), Without<C>>();
2179        let mut new_query_state = query_state.transmute::<&A>(&world);
2180        // even though we change the query to not have Without<C>, we do not get the component with C.
2181        let a = new_query_state.single(&world).unwrap();
2182
2183        assert_eq!(a.0, 0);
2184    }
2185
2186    #[test]
2187    fn can_transmute_empty_tuple() {
2188        let mut world = World::new();
2189        world.register_component::<A>();
2190        let entity = world.spawn(A(10)).id();
2191
2192        let q = world.query_filtered::<(), With<A>>();
2193        let mut q = q.transmute::<Entity>(&world);
2194        assert_eq!(q.single(&world).unwrap(), entity);
2195    }
2196
2197    #[test]
2198    fn can_transmute_immut_fetch() {
2199        let mut world = World::new();
2200        world.spawn(A(10));
2201
2202        let q = world.query::<&A>();
2203        let mut new_q = q.transmute::<Ref<A>>(&world);
2204        assert!(new_q.single(&world).unwrap().is_added());
2205
2206        let q = world.query::<Ref<A>>();
2207        let _ = q.transmute::<&A>(&world);
2208    }
2209
2210    #[test]
2211    fn can_transmute_mut_fetch() {
2212        let mut world = World::new();
2213        world.spawn(A(0));
2214
2215        let q = world.query::<&mut A>();
2216        let _ = q.transmute::<Ref<A>>(&world);
2217        let _ = q.transmute::<&A>(&world);
2218    }
2219
2220    #[test]
2221    fn can_transmute_entity_mut() {
2222        let mut world = World::new();
2223        world.spawn(A(0));
2224
2225        let q: QueryState<EntityMut<'_>> = world.query::<EntityMut>();
2226        let _ = q.transmute::<EntityRef>(&world);
2227    }
2228
2229    #[test]
2230    fn can_generalize_with_option() {
2231        let mut world = World::new();
2232        world.spawn((A(0), B(0)));
2233
2234        let query_state = world.query::<(Option<&A>, &B)>();
2235        let _ = query_state.transmute::<Option<&A>>(&world);
2236        let _ = query_state.transmute::<&B>(&world);
2237    }
2238
2239    #[test]
2240    #[should_panic]
2241    fn cannot_transmute_to_include_data_not_in_original_query() {
2242        let mut world = World::new();
2243        world.register_component::<A>();
2244        world.register_component::<B>();
2245        world.spawn(A(0));
2246
2247        let query_state = world.query::<&A>();
2248        let mut _new_query_state = query_state.transmute::<(&A, &B)>(&world);
2249    }
2250
2251    #[test]
2252    #[should_panic]
2253    fn cannot_transmute_immut_to_mut() {
2254        let mut world = World::new();
2255        world.spawn(A(0));
2256
2257        let query_state = world.query::<&A>();
2258        let mut _new_query_state = query_state.transmute::<&mut A>(&world);
2259    }
2260
2261    #[test]
2262    #[should_panic]
2263    fn cannot_transmute_option_to_immut() {
2264        let mut world = World::new();
2265        world.spawn(C(0));
2266
2267        let query_state = world.query::<Option<&A>>();
2268        let mut new_query_state = query_state.transmute::<&A>(&world);
2269        let x = new_query_state.single(&world).unwrap();
2270        assert_eq!(x.0, 1234);
2271    }
2272
2273    #[test]
2274    #[should_panic]
2275    fn cannot_transmute_entity_ref() {
2276        let mut world = World::new();
2277        world.register_component::<A>();
2278
2279        let q = world.query::<EntityRef>();
2280        let _ = q.transmute::<&A>(&world);
2281    }
2282
2283    #[test]
2284    fn can_transmute_filtered_entity() {
2285        let mut world = World::new();
2286        let entity = world.spawn((A(0), B(1))).id();
2287        let query = QueryState::<(Entity, &A, &B)>::new(&mut world)
2288            .transmute::<(Entity, FilteredEntityRef)>(&world);
2289
2290        let mut query = query;
2291        // Our result is completely untyped
2292        let (_entity, entity_ref) = query.single(&world).unwrap();
2293
2294        assert_eq!(entity, entity_ref.id());
2295        assert_eq!(0, entity_ref.get::<A>().unwrap().0);
2296        assert_eq!(1, entity_ref.get::<B>().unwrap().0);
2297    }
2298
2299    #[test]
2300    fn can_transmute_added() {
2301        let mut world = World::new();
2302        let entity_a = world.spawn(A(0)).id();
2303
2304        let mut query = QueryState::<(Entity, &A, Has<B>)>::new(&mut world)
2305            .transmute_filtered::<(Entity, Has<B>), Added<A>>(&world);
2306
2307        assert_eq!((entity_a, false), query.single(&world).unwrap());
2308
2309        world.clear_trackers();
2310
2311        let entity_b = world.spawn((A(0), B(0))).id();
2312        assert_eq!((entity_b, true), query.single(&world).unwrap());
2313
2314        world.clear_trackers();
2315
2316        assert!(query.single(&world).is_err());
2317    }
2318
2319    #[test]
2320    fn can_transmute_changed() {
2321        let mut world = World::new();
2322        let entity_a = world.spawn(A(0)).id();
2323
2324        let mut detection_query = QueryState::<(Entity, &A)>::new(&mut world)
2325            .transmute_filtered::<Entity, Changed<A>>(&world);
2326
2327        let mut change_query = QueryState::<&mut A>::new(&mut world);
2328        assert_eq!(entity_a, detection_query.single(&world).unwrap());
2329
2330        world.clear_trackers();
2331
2332        assert!(detection_query.single(&world).is_err());
2333
2334        change_query.single_mut(&mut world).unwrap().0 = 1;
2335
2336        assert_eq!(entity_a, detection_query.single(&world).unwrap());
2337    }
2338
2339    #[test]
2340    #[should_panic]
2341    fn cannot_transmute_changed_without_access() {
2342        let mut world = World::new();
2343        world.register_component::<A>();
2344        world.register_component::<B>();
2345        let query = QueryState::<&A>::new(&mut world);
2346        let _new_query = query.transmute_filtered::<Entity, Changed<B>>(&world);
2347    }
2348
2349    #[test]
2350    #[should_panic]
2351    fn cannot_transmute_mutable_after_readonly() {
2352        let mut world = World::new();
2353        // Calling this method would mean we had aliasing queries.
2354        fn bad(_: Query<&mut A>, _: Query<&A>) {}
2355        world
2356            .run_system_once(|query: Query<&mut A>| {
2357                let mut readonly = query.as_readonly();
2358                let mut lens: QueryLens<&mut A> = readonly.transmute_lens();
2359                bad(lens.query(), query.as_readonly());
2360            })
2361            .unwrap();
2362    }
2363
2364    // Regression test for #14629
2365    #[test]
2366    #[should_panic]
2367    fn transmute_with_different_world() {
2368        let mut world = World::new();
2369        world.spawn((A(1), B(2)));
2370
2371        let mut world2 = World::new();
2372        world2.register_component::<B>();
2373
2374        world.query::<(&A, &B)>().transmute::<&B>(&world2);
2375    }
2376
2377    /// Regression test for issue #14528
2378    #[test]
2379    fn transmute_from_sparse_to_dense() {
2380        #[derive(Component)]
2381        struct Dense;
2382
2383        #[derive(Component)]
2384        #[component(storage = "SparseSet")]
2385        struct Sparse;
2386
2387        let mut world = World::new();
2388
2389        world.spawn(Dense);
2390        world.spawn((Dense, Sparse));
2391
2392        let mut query = world
2393            .query_filtered::<&Dense, With<Sparse>>()
2394            .transmute::<&Dense>(&world);
2395
2396        let matched = query.iter(&world).count();
2397        assert_eq!(matched, 1);
2398    }
2399    #[test]
2400    fn transmute_from_dense_to_sparse() {
2401        #[derive(Component)]
2402        struct Dense;
2403
2404        #[derive(Component)]
2405        #[component(storage = "SparseSet")]
2406        struct Sparse;
2407
2408        let mut world = World::new();
2409
2410        world.spawn(Dense);
2411        world.spawn((Dense, Sparse));
2412
2413        let mut query = world
2414            .query::<&Dense>()
2415            .transmute_filtered::<&Dense, With<Sparse>>(&world);
2416
2417        // Note: `transmute_filtered` is supposed to keep the same matched tables/archetypes,
2418        // so it doesn't actually filter out those entities without `Sparse` and the iteration
2419        // remains dense.
2420        let matched = query.iter(&world).count();
2421        assert_eq!(matched, 2);
2422    }
2423
2424    #[test]
2425    fn transmute_to_or_filter() {
2426        let mut world = World::new();
2427        world.spawn(D);
2428        world.spawn((A(0), D));
2429
2430        let mut query = world
2431            .query::<(&D, Option<&A>)>()
2432            .transmute_filtered::<Entity, Or<(With<A>,)>>(&world);
2433        let iter = query.iter(&world);
2434        let len = iter.len();
2435        let count = iter.count();
2436        // `transmute_filtered` keeps the same matched tables, so it should match both entities
2437        // More importantly, `count()` and `len()` should return the same result!
2438        assert_eq!(len, 2);
2439        assert_eq!(count, len);
2440
2441        let mut query = world
2442            .query::<(&D, Option<&A>)>()
2443            .transmute_filtered::<Entity, Or<(Changed<A>,)>>(&world);
2444        let iter = query.iter(&world);
2445        let count = iter.count();
2446        // The behavior of a non-archetypal filter like `Changed` should be the same as an archetypal one like `With`.
2447        assert_eq!(count, 2);
2448    }
2449
2450    #[test]
2451    fn dense_query_over_option_is_buggy() {
2452        #[derive(Component)]
2453        #[component(storage = "SparseSet")]
2454        struct Sparse;
2455
2456        let mut world = World::new();
2457        world.spawn(Sparse);
2458
2459        let mut query =
2460            QueryState::<EntityRef>::new(&mut world).transmute::<Option<&Sparse>>(&world);
2461        // EntityRef always performs dense iteration
2462        // But `Option<&Sparse>` will incorrectly report a component as never being present when doing dense iteration
2463        // See https://github.com/bevyengine/bevy/issues/16397
2464        assert!(query.is_dense);
2465        let matched = query.iter(&world).filter(Option::is_some).count();
2466        assert_eq!(matched, 0);
2467
2468        let mut query = QueryState::<EntityRef>::new(&mut world).transmute::<Has<Sparse>>(&world);
2469        // EntityRef always performs dense iteration
2470        // But `Has<Sparse>` will incorrectly report a component as never being present when doing dense iteration
2471        // See https://github.com/bevyengine/bevy/issues/16397
2472        assert!(query.is_dense);
2473        let matched = query.iter(&world).filter(|&has| has).count();
2474        assert_eq!(matched, 0);
2475    }
2476
2477    #[test]
2478    fn join() {
2479        let mut world = World::new();
2480        world.spawn(A(0));
2481        world.spawn(B(1));
2482        let entity_ab = world.spawn((A(2), B(3))).id();
2483        world.spawn((A(4), B(5), C(6)));
2484
2485        let query_1 = QueryState::<&A, Without<C>>::new(&mut world);
2486        let query_2 = QueryState::<&B, Without<C>>::new(&mut world);
2487        let mut new_query: QueryState<Entity, ()> = query_1.join_filtered(&world, &query_2);
2488
2489        assert_eq!(new_query.single(&world).unwrap(), entity_ab);
2490    }
2491
2492    #[test]
2493    fn join_with_get() {
2494        let mut world = World::new();
2495        world.spawn(A(0));
2496        world.spawn(B(1));
2497        let entity_ab = world.spawn((A(2), B(3))).id();
2498        let entity_abc = world.spawn((A(4), B(5), C(6))).id();
2499
2500        let query_1 = QueryState::<&A>::new(&mut world);
2501        let query_2 = QueryState::<&B, Without<C>>::new(&mut world);
2502        let mut new_query: QueryState<Entity, ()> = query_1.join_filtered(&world, &query_2);
2503
2504        assert!(new_query.get(&world, entity_ab).is_ok());
2505        // should not be able to get entity with c.
2506        assert!(new_query.get(&world, entity_abc).is_err());
2507    }
2508
2509    #[test]
2510    #[should_panic]
2511    fn cannot_join_wrong_fetch() {
2512        let mut world = World::new();
2513        world.register_component::<C>();
2514        let query_1 = QueryState::<&A>::new(&mut world);
2515        let query_2 = QueryState::<&B>::new(&mut world);
2516        let _query: QueryState<&C> = query_1.join(&world, &query_2);
2517    }
2518
2519    #[test]
2520    #[should_panic]
2521    fn cannot_join_wrong_filter() {
2522        let mut world = World::new();
2523        let query_1 = QueryState::<&A, Without<C>>::new(&mut world);
2524        let query_2 = QueryState::<&B, Without<C>>::new(&mut world);
2525        let _: QueryState<Entity, Changed<C>> = query_1.join_filtered(&world, &query_2);
2526    }
2527
2528    #[test]
2529    #[should_panic]
2530    fn cannot_join_mutable_after_readonly() {
2531        let mut world = World::new();
2532        // Calling this method would mean we had aliasing queries.
2533        fn bad(_: Query<(&mut A, &mut B)>, _: Query<&A>) {}
2534        world
2535            .run_system_once(|query_a: Query<&mut A>, mut query_b: Query<&mut B>| {
2536                let mut readonly = query_a.as_readonly();
2537                let mut lens: QueryLens<(&mut A, &mut B)> = readonly.join(&mut query_b);
2538                bad(lens.query(), query_a.as_readonly());
2539            })
2540            .unwrap();
2541    }
2542
2543    #[test]
2544    fn join_to_filtered_entity_mut() {
2545        let mut world = World::new();
2546        world.spawn((A(2), B(3)));
2547
2548        let query_1 = QueryState::<&mut A>::new(&mut world);
2549        let query_2 = QueryState::<&mut B>::new(&mut world);
2550        let mut new_query: QueryState<(Entity, FilteredEntityMut)> = query_1.join(&world, &query_2);
2551
2552        let (_entity, mut entity_mut) = new_query.single_mut(&mut world).unwrap();
2553        assert!(entity_mut.get_mut::<A>().is_some());
2554        assert!(entity_mut.get_mut::<B>().is_some());
2555    }
2556
2557    #[test]
2558    fn query_respects_default_filters() {
2559        let mut world = World::new();
2560        world.spawn((A(0), B(0), D));
2561        world.spawn((B(0), C(0), D));
2562        world.spawn((C(0), D));
2563
2564        world.register_disabling_component::<C>();
2565
2566        // Without<C> only matches the first entity
2567        let mut query = QueryState::<&D>::new(&mut world);
2568        assert_eq!(1, query.iter(&world).count());
2569
2570        // With<C> matches the last two entities
2571        let mut query = QueryState::<&D, With<C>>::new(&mut world);
2572        assert_eq!(2, query.iter(&world).count());
2573
2574        // Has should bypass the filter entirely
2575        let mut query = QueryState::<(&D, Has<C>)>::new(&mut world);
2576        assert_eq!(3, query.iter(&world).count());
2577
2578        // Allow should bypass the filter entirely
2579        let mut query = QueryState::<&D, Allow<C>>::new(&mut world);
2580        assert_eq!(3, query.iter(&world).count());
2581
2582        // Other filters should still be respected
2583        let mut query = QueryState::<(&D, Has<C>), Without<B>>::new(&mut world);
2584        assert_eq!(1, query.iter(&world).count());
2585    }
2586
2587    #[derive(Component)]
2588    struct Table;
2589
2590    #[derive(Component)]
2591    #[component(storage = "SparseSet")]
2592    struct Sparse;
2593
2594    #[derive(Component)]
2595    struct Dummy;
2596
2597    #[test]
2598    fn query_default_filters_updates_is_dense() {
2599        let mut world = World::new();
2600        world.spawn((Dummy, Table, Sparse));
2601        world.spawn((Dummy, Table));
2602        world.spawn((Dummy, Sparse));
2603
2604        let mut query = QueryState::<&Dummy>::new(&mut world);
2605        // There are no sparse components involved thus the query is dense
2606        assert!(query.is_dense);
2607        assert_eq!(3, query.query(&world).count());
2608
2609        world.register_disabling_component::<Sparse>();
2610
2611        let mut query = QueryState::<&Dummy>::new(&mut world);
2612        // The query doesn't ask for sparse components, but the default filters adds
2613        // a sparse component thus it is NOT dense
2614        assert!(!query.is_dense);
2615        assert_eq!(1, query.query(&world).count());
2616
2617        let mut df = DefaultQueryFilters::from_world(&mut world);
2618        df.register_disabling_component(world.register_component::<Table>());
2619        world.insert_resource(df);
2620
2621        let mut query = QueryState::<&Dummy>::new(&mut world);
2622        // If the filter is instead a table components, the query can still be dense
2623        assert!(query.is_dense);
2624        assert_eq!(1, query.query(&world).count());
2625
2626        let mut query = QueryState::<&Sparse>::new(&mut world);
2627        // But only if the original query was dense
2628        assert!(!query.is_dense);
2629        assert_eq!(1, query.query(&world).count());
2630    }
2631}