bevy_ecs/query/
state.rs

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