bevy_ecs/query/
state.rs

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