use crate::{1archetype::{Archetype, ArchetypeGeneration, ArchetypeId},2component::{ComponentId, Tick},3entity::{Entity, EntityEquivalent, EntitySet, UniqueEntityArray},4entity_disabling::DefaultQueryFilters,5prelude::FromWorld,6query::{FilteredAccess, QueryCombinationIter, QueryIter, QueryParIter, WorldQuery},7storage::{SparseSetIndex, TableId},8system::Query,9world::{unsafe_world_cell::UnsafeWorldCell, World, WorldId},10};1112#[cfg(all(not(target_arch = "wasm32"), feature = "multi_threaded"))]13use crate::entity::UniqueEntityEquivalentSlice;1415use alloc::vec::Vec;16use bevy_utils::prelude::DebugName;17use core::{fmt, ptr};18use fixedbitset::FixedBitSet;19use log::warn;20#[cfg(feature = "trace")]21use tracing::Span;2223use super::{24NopWorldQuery, QueryBuilder, QueryData, QueryEntityError, QueryFilter, QueryManyIter,25QueryManyUniqueIter, QuerySingleError, ROQueryItem, ReadOnlyQueryData,26};2728/// An ID for either a table or an archetype. Used for Query iteration.29///30/// Query iteration is exclusively dense (over tables) or archetypal (over archetypes) based on whether31/// the query filters are dense or not. This is represented by the [`QueryState::is_dense`] field.32///33/// Note that `D::IS_DENSE` and `F::IS_DENSE` have no relationship with `QueryState::is_dense` and34/// any combination of their values can happen.35///36/// This is a union instead of an enum as the usage is determined at compile time, as all [`StorageId`]s for37/// a [`QueryState`] will be all [`TableId`]s or all [`ArchetypeId`]s, and not a mixture of both. This38/// removes the need for discriminator to minimize memory usage and branching during iteration, but requires39/// a safety invariant be verified when disambiguating them.40///41/// # Safety42/// Must be initialized and accessed as a [`TableId`], if both generic parameters to the query are dense.43/// Must be initialized and accessed as an [`ArchetypeId`] otherwise.44#[derive(Clone, Copy)]45pub(super) union StorageId {46pub(super) table_id: TableId,47pub(super) archetype_id: ArchetypeId,48}4950/// Provides scoped access to a [`World`] state according to a given [`QueryData`] and [`QueryFilter`].51///52/// This data is cached between system runs, and is used to:53/// - store metadata about which [`Table`] or [`Archetype`] are matched by the query. "Matched" means54/// that the query will iterate over the data in the matched table/archetype.55/// - cache the [`State`] needed to compute the [`Fetch`] struct used to retrieve data56/// from a specific [`Table`] or [`Archetype`]57/// - build iterators that can iterate over the query results58///59/// [`State`]: crate::query::world_query::WorldQuery::State60/// [`Fetch`]: crate::query::world_query::WorldQuery::Fetch61/// [`Table`]: crate::storage::Table62#[repr(C)]63// SAFETY NOTE:64// Do not add any new fields that use the `D` or `F` generic parameters as this may65// make `QueryState::as_transmuted_state` unsound if not done with care.66pub struct QueryState<D: QueryData, F: QueryFilter = ()> {67world_id: WorldId,68pub(crate) archetype_generation: ArchetypeGeneration,69/// Metadata about the [`Table`](crate::storage::Table)s matched by this query.70pub(crate) matched_tables: FixedBitSet,71/// Metadata about the [`Archetype`]s matched by this query.72pub(crate) matched_archetypes: FixedBitSet,73/// [`FilteredAccess`] computed by combining the `D` and `F` access. Used to check which other queries74/// this query can run in parallel with.75/// Note that because we do a zero-cost reference conversion in `Query::as_readonly`,76/// the access for a read-only query may include accesses for the original mutable version,77/// but the `Query` does not have exclusive access to those components.78pub(crate) component_access: FilteredAccess,79// NOTE: we maintain both a bitset and a vec because iterating the vec is faster80pub(super) matched_storage_ids: Vec<StorageId>,81// Represents whether this query iteration is dense or not. When this is true82// `matched_storage_ids` stores `TableId`s, otherwise it stores `ArchetypeId`s.83pub(super) is_dense: bool,84pub(crate) fetch_state: D::State,85pub(crate) filter_state: F::State,86#[cfg(feature = "trace")]87par_iter_span: Span,88}8990impl<D: QueryData, F: QueryFilter> fmt::Debug for QueryState<D, F> {91fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {92f.debug_struct("QueryState")93.field("world_id", &self.world_id)94.field("matched_table_count", &self.matched_tables.count_ones(..))95.field(96"matched_archetype_count",97&self.matched_archetypes.count_ones(..),98)99.finish_non_exhaustive()100}101}102103impl<D: QueryData, F: QueryFilter> FromWorld for QueryState<D, F> {104fn from_world(world: &mut World) -> Self {105world.query_filtered()106}107}108109impl<D: QueryData, F: QueryFilter> QueryState<D, F> {110/// Converts this `QueryState` reference to a `QueryState` that does not access anything mutably.111pub fn as_readonly(&self) -> &QueryState<D::ReadOnly, F> {112// SAFETY: invariant on `WorldQuery` trait upholds that `D::ReadOnly` and `F::ReadOnly`113// have a subset of the access, and match the exact same archetypes/tables as `D`/`F` respectively.114unsafe { self.as_transmuted_state::<D::ReadOnly, F>() }115}116117/// Converts this `QueryState` reference to a `QueryState` that does not return any data118/// which can be faster.119///120/// This doesn't use `NopWorldQuery` as it loses filter functionality, for example121/// `NopWorldQuery<Changed<T>>` is functionally equivalent to `With<T>`.122pub(crate) fn as_nop(&self) -> &QueryState<NopWorldQuery<D>, F> {123// SAFETY: `NopWorldQuery` doesn't have any accesses and defers to124// `D` for table/archetype matching125unsafe { self.as_transmuted_state::<NopWorldQuery<D>, F>() }126}127128/// Converts this `QueryState` reference to any other `QueryState` with129/// the same `WorldQuery::State` associated types.130///131/// Consider using `as_readonly` or `as_nop` instead which are safe functions.132///133/// # Safety134///135/// `NewD` must have a subset of the access that `D` does and match the exact same archetypes/tables136/// `NewF` must have a subset of the access that `F` does and match the exact same archetypes/tables137pub(crate) unsafe fn as_transmuted_state<138NewD: ReadOnlyQueryData<State = D::State>,139NewF: QueryFilter<State = F::State>,140>(141&self,142) -> &QueryState<NewD, NewF> {143&*ptr::from_ref(self).cast::<QueryState<NewD, NewF>>()144}145146/// Returns the components accessed by this query.147pub fn component_access(&self) -> &FilteredAccess {148&self.component_access149}150151/// Returns the tables matched by this query.152pub fn matched_tables(&self) -> impl Iterator<Item = TableId> + '_ {153self.matched_tables.ones().map(TableId::from_usize)154}155156/// Returns the archetypes matched by this query.157pub fn matched_archetypes(&self) -> impl Iterator<Item = ArchetypeId> + '_ {158self.matched_archetypes.ones().map(ArchetypeId::new)159}160161/// Creates a new [`QueryState`] from a given [`World`] and inherits the result of `world.id()`.162pub fn new(world: &mut World) -> Self {163let mut state = Self::new_uninitialized(world);164state.update_archetypes(world);165state166}167168/// Creates a new [`QueryState`] from an immutable [`World`] reference and inherits the result of `world.id()`.169///170/// This function may fail if, for example,171/// the components that make up this query have not been registered into the world.172pub fn try_new(world: &World) -> Option<Self> {173let mut state = Self::try_new_uninitialized(world)?;174state.update_archetypes(world);175Some(state)176}177178/// Creates a new [`QueryState`] but does not populate it with the matched results from the World yet179///180/// `new_archetype` and its variants must be called on all of the World's archetypes before the181/// state can return valid query results.182fn new_uninitialized(world: &mut World) -> Self {183let fetch_state = D::init_state(world);184let filter_state = F::init_state(world);185Self::from_states_uninitialized(world, fetch_state, filter_state)186}187188/// Creates a new [`QueryState`] but does not populate it with the matched results from the World yet189///190/// `new_archetype` and its variants must be called on all of the World's archetypes before the191/// state can return valid query results.192fn try_new_uninitialized(world: &World) -> Option<Self> {193let fetch_state = D::get_state(world.components())?;194let filter_state = F::get_state(world.components())?;195Some(Self::from_states_uninitialized(196world,197fetch_state,198filter_state,199))200}201202/// Creates a new [`QueryState`] but does not populate it with the matched results from the World yet203///204/// `new_archetype` and its variants must be called on all of the World's archetypes before the205/// state can return valid query results.206fn from_states_uninitialized(207world: &World,208fetch_state: <D as WorldQuery>::State,209filter_state: <F as WorldQuery>::State,210) -> Self {211let mut component_access = FilteredAccess::default();212D::update_component_access(&fetch_state, &mut component_access);213214// Use a temporary empty FilteredAccess for filters. This prevents them from conflicting with the215// main Query's `fetch_state` access. Filters are allowed to conflict with the main query fetch216// because they are evaluated *before* a specific reference is constructed.217let mut filter_component_access = FilteredAccess::default();218F::update_component_access(&filter_state, &mut filter_component_access);219220// Merge the temporary filter access with the main access. This ensures that filter access is221// properly considered in a global "cross-query" context (both within systems and across systems).222component_access.extend(&filter_component_access);223224// For queries without dynamic filters the dense-ness of the query is equal to the dense-ness225// of its static type parameters.226let mut is_dense = D::IS_DENSE && F::IS_DENSE;227228if let Some(default_filters) = world.get_resource::<DefaultQueryFilters>() {229default_filters.modify_access(&mut component_access);230is_dense &= default_filters.is_dense(world.components());231}232233Self {234world_id: world.id(),235archetype_generation: ArchetypeGeneration::initial(),236matched_storage_ids: Vec::new(),237is_dense,238fetch_state,239filter_state,240component_access,241matched_tables: Default::default(),242matched_archetypes: Default::default(),243#[cfg(feature = "trace")]244par_iter_span: tracing::info_span!(245"par_for_each",246query = core::any::type_name::<D>(),247filter = core::any::type_name::<F>(),248),249}250}251252/// Creates a new [`QueryState`] from a given [`QueryBuilder`] and inherits its [`FilteredAccess`].253pub fn from_builder(builder: &mut QueryBuilder<D, F>) -> Self {254let mut fetch_state = D::init_state(builder.world_mut());255let filter_state = F::init_state(builder.world_mut());256257let mut component_access = FilteredAccess::default();258D::update_component_access(&fetch_state, &mut component_access);259D::provide_extra_access(260&mut fetch_state,261component_access.access_mut(),262builder.access().access(),263);264265let mut component_access = builder.access().clone();266267// For dynamic queries the dense-ness is given by the query builder.268let mut is_dense = builder.is_dense();269270if let Some(default_filters) = builder.world().get_resource::<DefaultQueryFilters>() {271default_filters.modify_access(&mut component_access);272is_dense &= default_filters.is_dense(builder.world().components());273}274275let mut state = Self {276world_id: builder.world().id(),277archetype_generation: ArchetypeGeneration::initial(),278matched_storage_ids: Vec::new(),279is_dense,280fetch_state,281filter_state,282component_access,283matched_tables: Default::default(),284matched_archetypes: Default::default(),285#[cfg(feature = "trace")]286par_iter_span: tracing::info_span!(287"par_for_each",288data = core::any::type_name::<D>(),289filter = core::any::type_name::<F>(),290),291};292state.update_archetypes(builder.world());293state294}295296/// Creates a [`Query`] from the given [`QueryState`] and [`World`].297///298/// This will create read-only queries, see [`Self::query_mut`] for mutable queries.299pub fn query<'w, 's>(&'s mut self, world: &'w World) -> Query<'w, 's, D::ReadOnly, F> {300self.update_archetypes(world);301self.query_manual(world)302}303304/// Creates a [`Query`] from the given [`QueryState`] and [`World`].305///306/// This method is slightly more efficient than [`QueryState::query`] in some situations, since307/// it does not update this instance's internal cache. The resulting query may skip an entity that308/// belongs to an archetype that has not been cached.309///310/// To ensure that the cache is up to date, call [`QueryState::update_archetypes`] before this method.311/// The cache is also updated in [`QueryState::new`], [`QueryState::get`], or any method with mutable312/// access to `self`.313///314/// This will create read-only queries, see [`Self::query_mut`] for mutable queries.315pub fn query_manual<'w, 's>(&'s self, world: &'w World) -> Query<'w, 's, D::ReadOnly, F> {316self.validate_world(world.id());317// SAFETY:318// - We have read access to the entire world, and we call `as_readonly()` so the query only performs read access.319// - We called `validate_world`.320unsafe {321self.as_readonly()322.query_unchecked_manual(world.as_unsafe_world_cell_readonly())323}324}325326/// Creates a [`Query`] from the given [`QueryState`] and [`World`].327pub fn query_mut<'w, 's>(&'s mut self, world: &'w mut World) -> Query<'w, 's, D, F> {328let last_run = world.last_change_tick();329let this_run = world.change_tick();330// SAFETY: We have exclusive access to the entire world.331unsafe { self.query_unchecked_with_ticks(world.as_unsafe_world_cell(), last_run, this_run) }332}333334/// Creates a [`Query`] from the given [`QueryState`] and [`World`].335///336/// # Safety337///338/// This does not check for mutable query correctness. To be safe, make sure mutable queries339/// have unique access to the components they query.340pub unsafe fn query_unchecked<'w, 's>(341&'s mut self,342world: UnsafeWorldCell<'w>,343) -> Query<'w, 's, D, F> {344self.update_archetypes_unsafe_world_cell(world);345// SAFETY: Caller ensures we have the required access346unsafe { self.query_unchecked_manual(world) }347}348349/// Creates a [`Query`] from the given [`QueryState`] and [`World`].350///351/// This method is slightly more efficient than [`QueryState::query_unchecked`] in some situations, since352/// it does not update this instance's internal cache. The resulting query may skip an entity that353/// belongs to an archetype that has not been cached.354///355/// To ensure that the cache is up to date, call [`QueryState::update_archetypes`] before this method.356/// The cache is also updated in [`QueryState::new`], [`QueryState::get`], or any method with mutable357/// access to `self`.358///359/// # Safety360///361/// This does not check for mutable query correctness. To be safe, make sure mutable queries362/// have unique access to the components they query.363/// This does not validate that `world.id()` matches `self.world_id`. Calling this on a `world`364/// with a mismatched [`WorldId`] is unsound.365pub unsafe fn query_unchecked_manual<'w, 's>(366&'s self,367world: UnsafeWorldCell<'w>,368) -> Query<'w, 's, D, F> {369let last_run = world.last_change_tick();370let this_run = world.change_tick();371// SAFETY:372// - The caller ensured we have the correct access to the world.373// - The caller ensured that the world matches.374unsafe { self.query_unchecked_manual_with_ticks(world, last_run, this_run) }375}376377/// Creates a [`Query`] from the given [`QueryState`] and [`World`].378///379/// # Safety380///381/// This does not check for mutable query correctness. To be safe, make sure mutable queries382/// have unique access to the components they query.383pub unsafe fn query_unchecked_with_ticks<'w, 's>(384&'s mut self,385world: UnsafeWorldCell<'w>,386last_run: Tick,387this_run: Tick,388) -> Query<'w, 's, D, F> {389self.update_archetypes_unsafe_world_cell(world);390// SAFETY:391// - The caller ensured we have the correct access to the world.392// - We called `update_archetypes_unsafe_world_cell`, which calls `validate_world`.393unsafe { self.query_unchecked_manual_with_ticks(world, last_run, this_run) }394}395396/// Creates a [`Query`] from the given [`QueryState`] and [`World`].397///398/// This method is slightly more efficient than [`QueryState::query_unchecked_with_ticks`] in some situations, since399/// it does not update this instance's internal cache. The resulting query may skip an entity that400/// belongs to an archetype that has not been cached.401///402/// To ensure that the cache is up to date, call [`QueryState::update_archetypes`] before this method.403/// The cache is also updated in [`QueryState::new`], [`QueryState::get`], or any method with mutable404/// access to `self`.405///406/// # Safety407///408/// This does not check for mutable query correctness. To be safe, make sure mutable queries409/// have unique access to the components they query.410/// This does not validate that `world.id()` matches `self.world_id`. Calling this on a `world`411/// with a mismatched [`WorldId`] is unsound.412pub unsafe fn query_unchecked_manual_with_ticks<'w, 's>(413&'s self,414world: UnsafeWorldCell<'w>,415last_run: Tick,416this_run: Tick,417) -> Query<'w, 's, D, F> {418// SAFETY:419// - The caller ensured we have the correct access to the world.420// - The caller ensured that the world matches.421unsafe { Query::new(world, self, last_run, this_run) }422}423424/// Checks if the query is empty for the given [`World`], where the last change and current tick are given.425///426/// This is equivalent to `self.iter().next().is_none()`, and thus the worst case runtime will be `O(n)`427/// where `n` is the number of *potential* matches. This can be notably expensive for queries that rely428/// on non-archetypal filters such as [`Added`], [`Changed`] or [`Spawned`] which must individually check429/// each query result for a match.430///431/// # Panics432///433/// If `world` does not match the one used to call `QueryState::new` for this instance.434///435/// [`Added`]: crate::query::Added436/// [`Changed`]: crate::query::Changed437/// [`Spawned`]: crate::query::Spawned438#[inline]439pub fn is_empty(&self, world: &World, last_run: Tick, this_run: Tick) -> bool {440self.validate_world(world.id());441// SAFETY:442// - We have read access to the entire world, and `is_empty()` only performs read access.443// - We called `validate_world`.444unsafe {445self.query_unchecked_manual_with_ticks(446world.as_unsafe_world_cell_readonly(),447last_run,448this_run,449)450}451.is_empty()452}453454/// Returns `true` if the given [`Entity`] matches the query.455///456/// This is always guaranteed to run in `O(1)` time.457#[inline]458pub fn contains(&self, entity: Entity, world: &World, last_run: Tick, this_run: Tick) -> bool {459self.validate_world(world.id());460// SAFETY:461// - We have read access to the entire world, and `is_empty()` only performs read access.462// - We called `validate_world`.463unsafe {464self.query_unchecked_manual_with_ticks(465world.as_unsafe_world_cell_readonly(),466last_run,467this_run,468)469}470.contains(entity)471}472473/// Updates the state's internal view of the [`World`]'s archetypes. If this is not called before querying data,474/// the results may not accurately reflect what is in the `world`.475///476/// This is only required if a `manual` method (such as [`Self::get_manual`]) is being called, and it only needs to477/// be called if the `world` has been structurally mutated (i.e. added/removed a component or resource). Users using478/// non-`manual` methods such as [`QueryState::get`] do not need to call this as it will be automatically called for them.479///480/// If you have an [`UnsafeWorldCell`] instead of `&World`, consider using [`QueryState::update_archetypes_unsafe_world_cell`].481///482/// # Panics483///484/// If `world` does not match the one used to call `QueryState::new` for this instance.485#[inline]486pub fn update_archetypes(&mut self, world: &World) {487self.update_archetypes_unsafe_world_cell(world.as_unsafe_world_cell_readonly());488}489490/// Updates the state's internal view of the `world`'s archetypes. If this is not called before querying data,491/// the results may not accurately reflect what is in the `world`.492///493/// This is only required if a `manual` method (such as [`Self::get_manual`]) is being called, and it only needs to494/// be called if the `world` has been structurally mutated (i.e. added/removed a component or resource). Users using495/// non-`manual` methods such as [`QueryState::get`] do not need to call this as it will be automatically called for them.496///497/// # Note498///499/// This method only accesses world metadata.500///501/// # Panics502///503/// If `world` does not match the one used to call `QueryState::new` for this instance.504pub fn update_archetypes_unsafe_world_cell(&mut self, world: UnsafeWorldCell) {505self.validate_world(world.id());506if self.component_access.required.is_empty() {507let archetypes = world.archetypes();508let old_generation =509core::mem::replace(&mut self.archetype_generation, archetypes.generation());510511for archetype in &archetypes[old_generation..] {512// SAFETY: The validate_world call ensures that the world is the same the QueryState513// was initialized from.514unsafe {515self.new_archetype(archetype);516}517}518} else {519// skip if we are already up to date520if self.archetype_generation == world.archetypes().generation() {521return;522}523// if there are required components, we can optimize by only iterating through archetypes524// that contain at least one of the required components525let potential_archetypes = self526.component_access527.required528.ones()529.filter_map(|idx| {530let component_id = ComponentId::get_sparse_set_index(idx);531world532.archetypes()533.component_index()534.get(&component_id)535.map(|index| index.keys())536})537// select the component with the fewest archetypes538.min_by_key(ExactSizeIterator::len);539if let Some(archetypes) = potential_archetypes {540for archetype_id in archetypes {541// exclude archetypes that have already been processed542if archetype_id < &self.archetype_generation.0 {543continue;544}545// SAFETY: get_potential_archetypes only returns archetype ids that are valid for the world546let archetype = &world.archetypes()[*archetype_id];547// SAFETY: The validate_world call ensures that the world is the same the QueryState548// was initialized from.549unsafe {550self.new_archetype(archetype);551}552}553}554self.archetype_generation = world.archetypes().generation();555}556}557558/// # Panics559///560/// If `world_id` does not match the [`World`] used to call `QueryState::new` for this instance.561///562/// Many unsafe query methods require the world to match for soundness. This function is the easiest563/// way of ensuring that it matches.564#[inline]565#[track_caller]566pub fn validate_world(&self, world_id: WorldId) {567#[inline(never)]568#[track_caller]569#[cold]570fn panic_mismatched(this: WorldId, other: WorldId) -> ! {571panic!("Encountered a mismatched World. This QueryState was created from {this:?}, but a method was called using {other:?}.");572}573574if self.world_id != world_id {575panic_mismatched(self.world_id, world_id);576}577}578579/// Update the current [`QueryState`] with information from the provided [`Archetype`]580/// (if applicable, i.e. if the archetype has any intersecting [`ComponentId`] with the current [`QueryState`]).581///582/// # Safety583/// `archetype` must be from the `World` this state was initialized from.584pub unsafe fn new_archetype(&mut self, archetype: &Archetype) {585if D::matches_component_set(&self.fetch_state, &|id| archetype.contains(id))586&& F::matches_component_set(&self.filter_state, &|id| archetype.contains(id))587&& self.matches_component_set(&|id| archetype.contains(id))588{589let archetype_index = archetype.id().index();590if !self.matched_archetypes.contains(archetype_index) {591self.matched_archetypes.grow_and_insert(archetype_index);592if !self.is_dense {593self.matched_storage_ids.push(StorageId {594archetype_id: archetype.id(),595});596}597}598let table_index = archetype.table_id().as_usize();599if !self.matched_tables.contains(table_index) {600self.matched_tables.grow_and_insert(table_index);601if self.is_dense {602self.matched_storage_ids.push(StorageId {603table_id: archetype.table_id(),604});605}606}607}608}609610/// Returns `true` if this query matches a set of components. Otherwise, returns `false`.611pub fn matches_component_set(&self, set_contains_id: &impl Fn(ComponentId) -> bool) -> bool {612self.component_access.filter_sets.iter().any(|set| {613set.with614.ones()615.all(|index| set_contains_id(ComponentId::get_sparse_set_index(index)))616&& set617.without618.ones()619.all(|index| !set_contains_id(ComponentId::get_sparse_set_index(index)))620})621}622623/// Use this to transform a [`QueryState`] into a more generic [`QueryState`].624/// This can be useful for passing to another function that might take the more general form.625/// See [`Query::transmute_lens`](crate::system::Query::transmute_lens) for more details.626///627/// You should not call [`update_archetypes`](Self::update_archetypes) on the returned [`QueryState`] as the result will be unpredictable.628/// You might end up with a mix of archetypes that only matched the original query + archetypes that only match629/// the new [`QueryState`]. Most of the safe methods on [`QueryState`] call [`QueryState::update_archetypes`] internally, so this630/// best used through a [`Query`]631pub fn transmute<'a, NewD: QueryData>(632&self,633world: impl Into<UnsafeWorldCell<'a>>,634) -> QueryState<NewD> {635self.transmute_filtered::<NewD, ()>(world.into())636}637638/// Creates a new [`QueryState`] with the same underlying [`FilteredAccess`], matched tables and archetypes639/// as self but with a new type signature.640///641/// Panics if `NewD` or `NewF` require accesses that this query does not have.642pub fn transmute_filtered<'a, NewD: QueryData, NewF: QueryFilter>(643&self,644world: impl Into<UnsafeWorldCell<'a>>,645) -> QueryState<NewD, NewF> {646let world = world.into();647self.validate_world(world.id());648649let mut component_access = FilteredAccess::default();650let mut fetch_state = NewD::get_state(world.components()).expect("Could not create fetch_state, Please initialize all referenced components before transmuting.");651let filter_state = NewF::get_state(world.components()).expect("Could not create filter_state, Please initialize all referenced components before transmuting.");652653let mut self_access = self.component_access.clone();654if D::IS_READ_ONLY {655// The current state was transmuted from a mutable656// `QueryData` to a read-only one.657// Ignore any write access in the current state.658self_access.access_mut().clear_writes();659}660661NewD::update_component_access(&fetch_state, &mut component_access);662NewD::provide_extra_access(663&mut fetch_state,664component_access.access_mut(),665self_access.access(),666);667668let mut filter_component_access = FilteredAccess::default();669NewF::update_component_access(&filter_state, &mut filter_component_access);670671component_access.extend(&filter_component_access);672assert!(673component_access.is_subset(&self_access),674"Transmuted state for {} attempts to access terms that are not allowed by original state {}.",675DebugName::type_name::<(NewD, NewF)>(), DebugName::type_name::<(D, F)>()676);677678QueryState {679world_id: self.world_id,680archetype_generation: self.archetype_generation,681matched_storage_ids: self.matched_storage_ids.clone(),682is_dense: self.is_dense,683fetch_state,684filter_state,685component_access: self_access,686matched_tables: self.matched_tables.clone(),687matched_archetypes: self.matched_archetypes.clone(),688#[cfg(feature = "trace")]689par_iter_span: tracing::info_span!(690"par_for_each",691query = core::any::type_name::<NewD>(),692filter = core::any::type_name::<NewF>(),693),694}695}696697/// Use this to combine two queries. The data accessed will be the intersection698/// of archetypes included in both queries. This can be useful for accessing a699/// subset of the entities between two queries.700///701/// You should not call `update_archetypes` on the returned `QueryState` as the result702/// could be unpredictable. You might end up with a mix of archetypes that only matched703/// the original query + archetypes that only match the new `QueryState`. Most of the704/// safe methods on `QueryState` call [`QueryState::update_archetypes`] internally, so705/// this is best used through a `Query`.706///707/// ## Performance708///709/// This will have similar performance as constructing a new `QueryState` since much of internal state710/// needs to be reconstructed. But it will be a little faster as it only needs to compare the intersection711/// of matching archetypes rather than iterating over all archetypes.712///713/// ## Panics714///715/// Will panic if `NewD` contains accesses not in `Q` or `OtherQ`.716pub fn join<'a, OtherD: QueryData, NewD: QueryData>(717&self,718world: impl Into<UnsafeWorldCell<'a>>,719other: &QueryState<OtherD>,720) -> QueryState<NewD, ()> {721self.join_filtered::<_, (), NewD, ()>(world, other)722}723724/// Use this to combine two queries. The data accessed will be the intersection725/// of archetypes included in both queries.726///727/// ## Panics728///729/// Will panic if `NewD` or `NewF` requires accesses not in `Q` or `OtherQ`.730pub fn join_filtered<731'a,732OtherD: QueryData,733OtherF: QueryFilter,734NewD: QueryData,735NewF: QueryFilter,736>(737&self,738world: impl Into<UnsafeWorldCell<'a>>,739other: &QueryState<OtherD, OtherF>,740) -> QueryState<NewD, NewF> {741if self.world_id != other.world_id {742panic!("Joining queries initialized on different worlds is not allowed.");743}744745let world = world.into();746747self.validate_world(world.id());748749let mut component_access = FilteredAccess::default();750let mut new_fetch_state = NewD::get_state(world.components())751.expect("Could not create fetch_state, Please initialize all referenced components before transmuting.");752let new_filter_state = NewF::get_state(world.components())753.expect("Could not create filter_state, Please initialize all referenced components before transmuting.");754755let mut joined_component_access = self.component_access.clone();756joined_component_access.extend(&other.component_access);757758if D::IS_READ_ONLY && self.component_access.access().has_any_write()759|| OtherD::IS_READ_ONLY && other.component_access.access().has_any_write()760{761// One of the input states was transmuted from a mutable762// `QueryData` to a read-only one.763// Ignore any write access in that current state.764// The simplest way to do this is to clear *all* writes765// and then add back in any writes that are valid766joined_component_access.access_mut().clear_writes();767if !D::IS_READ_ONLY {768joined_component_access769.access_mut()770.extend(self.component_access.access());771}772if !OtherD::IS_READ_ONLY {773joined_component_access774.access_mut()775.extend(other.component_access.access());776}777}778779NewD::update_component_access(&new_fetch_state, &mut component_access);780NewD::provide_extra_access(781&mut new_fetch_state,782component_access.access_mut(),783joined_component_access.access(),784);785786let mut new_filter_component_access = FilteredAccess::default();787NewF::update_component_access(&new_filter_state, &mut new_filter_component_access);788789component_access.extend(&new_filter_component_access);790791assert!(792component_access.is_subset(&joined_component_access),793"Joined state for {} attempts to access terms that are not allowed by state {} joined with {}.",794DebugName::type_name::<(NewD, NewF)>(), DebugName::type_name::<(D, F)>(), DebugName::type_name::<(OtherD, OtherF)>()795);796797if self.archetype_generation != other.archetype_generation {798warn!("You have tried to join queries with different archetype_generations. This could lead to unpredictable results.");799}800801// the join is dense of both the queries were dense.802let is_dense = self.is_dense && other.is_dense;803804// take the intersection of the matched ids805let mut matched_tables = self.matched_tables.clone();806let mut matched_archetypes = self.matched_archetypes.clone();807matched_tables.intersect_with(&other.matched_tables);808matched_archetypes.intersect_with(&other.matched_archetypes);809let matched_storage_ids = if is_dense {810matched_tables811.ones()812.map(|id| StorageId {813table_id: TableId::from_usize(id),814})815.collect()816} else {817matched_archetypes818.ones()819.map(|id| StorageId {820archetype_id: ArchetypeId::new(id),821})822.collect()823};824825QueryState {826world_id: self.world_id,827archetype_generation: self.archetype_generation,828matched_storage_ids,829is_dense,830fetch_state: new_fetch_state,831filter_state: new_filter_state,832component_access: joined_component_access,833matched_tables,834matched_archetypes,835#[cfg(feature = "trace")]836par_iter_span: tracing::info_span!(837"par_for_each",838query = core::any::type_name::<NewD>(),839filter = core::any::type_name::<NewF>(),840),841}842}843844/// Gets the query result for the given [`World`] and [`Entity`].845///846/// This can only be called for read-only queries, see [`Self::get_mut`] for write-queries.847///848/// If you need to get multiple items at once but get borrowing errors,849/// consider using [`Self::update_archetypes`] followed by multiple [`Self::get_manual`] calls,850/// or making a single call with [`Self::get_many`] or [`Self::iter_many`].851///852/// This is always guaranteed to run in `O(1)` time.853#[inline]854pub fn get<'w>(855&mut self,856world: &'w World,857entity: Entity,858) -> Result<ROQueryItem<'w, '_, D>, QueryEntityError> {859self.query(world).get_inner(entity)860}861862/// Returns the read-only query results for the given array of [`Entity`].863///864/// In case of a nonexisting entity or mismatched component, a [`QueryEntityError`] is865/// returned instead.866///867/// Note that the unlike [`QueryState::get_many_mut`], the entities passed in do not need to be unique.868///869/// # Examples870///871/// ```872/// use bevy_ecs::prelude::*;873/// use bevy_ecs::query::QueryEntityError;874///875/// #[derive(Component, PartialEq, Debug)]876/// struct A(usize);877///878/// let mut world = World::new();879/// let entity_vec: Vec<Entity> = (0..3).map(|i|world.spawn(A(i)).id()).collect();880/// let entities: [Entity; 3] = entity_vec.try_into().unwrap();881///882/// world.spawn(A(73));883///884/// let mut query_state = world.query::<&A>();885///886/// let component_values = query_state.get_many(&world, entities).unwrap();887///888/// assert_eq!(component_values, [&A(0), &A(1), &A(2)]);889///890/// let wrong_entity = Entity::from_raw_u32(365).unwrap();891///892/// assert_eq!(match query_state.get_many(&mut world, [wrong_entity]).unwrap_err() {QueryEntityError::EntityDoesNotExist(error) => error.entity, _ => panic!()}, wrong_entity);893/// ```894#[inline]895pub fn get_many<'w, const N: usize>(896&mut self,897world: &'w World,898entities: [Entity; N],899) -> Result<[ROQueryItem<'w, '_, D>; N], QueryEntityError> {900self.query(world).get_many_inner(entities)901}902903/// Returns the read-only query results for the given [`UniqueEntityArray`].904///905/// In case of a nonexisting entity or mismatched component, a [`QueryEntityError`] is906/// returned instead.907///908/// # Examples909///910/// ```911/// use bevy_ecs::{prelude::*, query::QueryEntityError, entity::{EntitySetIterator, UniqueEntityArray, UniqueEntityVec}};912///913/// #[derive(Component, PartialEq, Debug)]914/// struct A(usize);915///916/// let mut world = World::new();917/// let entity_set: UniqueEntityVec = world.spawn_batch((0..3).map(A)).collect_set();918/// let entity_set: UniqueEntityArray<3> = entity_set.try_into().unwrap();919///920/// world.spawn(A(73));921///922/// let mut query_state = world.query::<&A>();923///924/// let component_values = query_state.get_many_unique(&world, entity_set).unwrap();925///926/// assert_eq!(component_values, [&A(0), &A(1), &A(2)]);927///928/// let wrong_entity = Entity::from_raw_u32(365).unwrap();929///930/// assert_eq!(match query_state.get_many_unique(&mut world, UniqueEntityArray::from([wrong_entity])).unwrap_err() {QueryEntityError::EntityDoesNotExist(error) => error.entity, _ => panic!()}, wrong_entity);931/// ```932#[inline]933pub fn get_many_unique<'w, const N: usize>(934&mut self,935world: &'w World,936entities: UniqueEntityArray<N>,937) -> Result<[ROQueryItem<'w, '_, D>; N], QueryEntityError> {938self.query(world).get_many_unique_inner(entities)939}940941/// Gets the query result for the given [`World`] and [`Entity`].942///943/// This is always guaranteed to run in `O(1)` time.944#[inline]945pub fn get_mut<'w>(946&mut self,947world: &'w mut World,948entity: Entity,949) -> Result<D::Item<'w, '_>, QueryEntityError> {950self.query_mut(world).get_inner(entity)951}952953/// Returns the query results for the given array of [`Entity`].954///955/// In case of a nonexisting entity or mismatched component, a [`QueryEntityError`] is956/// returned instead.957///958/// ```959/// use bevy_ecs::prelude::*;960/// use bevy_ecs::query::QueryEntityError;961///962/// #[derive(Component, PartialEq, Debug)]963/// struct A(usize);964///965/// let mut world = World::new();966///967/// let entities: Vec<Entity> = (0..3).map(|i|world.spawn(A(i)).id()).collect();968/// let entities: [Entity; 3] = entities.try_into().unwrap();969///970/// world.spawn(A(73));971///972/// let mut query_state = world.query::<&mut A>();973///974/// let mut mutable_component_values = query_state.get_many_mut(&mut world, entities).unwrap();975///976/// for mut a in &mut mutable_component_values {977/// a.0 += 5;978/// }979///980/// let component_values = query_state.get_many(&world, entities).unwrap();981///982/// assert_eq!(component_values, [&A(5), &A(6), &A(7)]);983///984/// let wrong_entity = Entity::from_raw_u32(57).unwrap();985/// let invalid_entity = world.spawn_empty().id();986///987/// assert_eq!(match query_state.get_many(&mut world, [wrong_entity]).unwrap_err() {QueryEntityError::EntityDoesNotExist(error) => error.entity, _ => panic!()}, wrong_entity);988/// assert_eq!(match query_state.get_many_mut(&mut world, [invalid_entity]).unwrap_err() {QueryEntityError::QueryDoesNotMatch(entity, _) => entity, _ => panic!()}, invalid_entity);989/// assert_eq!(query_state.get_many_mut(&mut world, [entities[0], entities[0]]).unwrap_err(), QueryEntityError::AliasedMutability(entities[0]));990/// ```991#[inline]992pub fn get_many_mut<'w, const N: usize>(993&mut self,994world: &'w mut World,995entities: [Entity; N],996) -> Result<[D::Item<'w, '_>; N], QueryEntityError> {997self.query_mut(world).get_many_mut_inner(entities)998}9991000/// Returns the query results for the given [`UniqueEntityArray`].1001///1002/// In case of a nonexisting entity or mismatched component, a [`QueryEntityError`] is1003/// returned instead.1004///1005/// ```1006/// use bevy_ecs::{prelude::*, query::QueryEntityError, entity::{EntitySetIterator, UniqueEntityArray, UniqueEntityVec}};1007///1008/// #[derive(Component, PartialEq, Debug)]1009/// struct A(usize);1010///1011/// let mut world = World::new();1012///1013/// let entity_set: UniqueEntityVec = world.spawn_batch((0..3).map(A)).collect_set();1014/// let entity_set: UniqueEntityArray<3> = entity_set.try_into().unwrap();1015///1016/// world.spawn(A(73));1017///1018/// let mut query_state = world.query::<&mut A>();1019///1020/// let mut mutable_component_values = query_state.get_many_unique_mut(&mut world, entity_set).unwrap();1021///1022/// for mut a in &mut mutable_component_values {1023/// a.0 += 5;1024/// }1025///1026/// let component_values = query_state.get_many_unique(&world, entity_set).unwrap();1027///1028/// assert_eq!(component_values, [&A(5), &A(6), &A(7)]);1029///1030/// let wrong_entity = Entity::from_raw_u32(57).unwrap();1031/// let invalid_entity = world.spawn_empty().id();1032///1033/// assert_eq!(match query_state.get_many_unique(&mut world, UniqueEntityArray::from([wrong_entity])).unwrap_err() {QueryEntityError::EntityDoesNotExist(error) => error.entity, _ => panic!()}, wrong_entity);1034/// assert_eq!(match query_state.get_many_unique_mut(&mut world, UniqueEntityArray::from([invalid_entity])).unwrap_err() {QueryEntityError::QueryDoesNotMatch(entity, _) => entity, _ => panic!()}, invalid_entity);1035/// ```1036#[inline]1037pub fn get_many_unique_mut<'w, const N: usize>(1038&mut self,1039world: &'w mut World,1040entities: UniqueEntityArray<N>,1041) -> Result<[D::Item<'w, '_>; N], QueryEntityError> {1042self.query_mut(world).get_many_unique_inner(entities)1043}10441045/// Gets the query result for the given [`World`] and [`Entity`].1046///1047/// This method is slightly more efficient than [`QueryState::get`] in some situations, since1048/// it does not update this instance's internal cache. This method will return an error if `entity`1049/// belongs to an archetype that has not been cached.1050///1051/// To ensure that the cache is up to date, call [`QueryState::update_archetypes`] before this method.1052/// The cache is also updated in [`QueryState::new`], `QueryState::get`, or any method with mutable1053/// access to `self`.1054///1055/// This can only be called for read-only queries, see [`Self::get_mut`] for mutable queries.1056///1057/// This is always guaranteed to run in `O(1)` time.1058#[inline]1059pub fn get_manual<'w>(1060&self,1061world: &'w World,1062entity: Entity,1063) -> Result<ROQueryItem<'w, '_, D>, QueryEntityError> {1064self.query_manual(world).get_inner(entity)1065}10661067/// Gets the query result for the given [`World`] and [`Entity`].1068///1069/// This is always guaranteed to run in `O(1)` time.1070///1071/// # Safety1072///1073/// This does not check for mutable query correctness. To be safe, make sure mutable queries1074/// have unique access to the components they query.1075#[inline]1076pub unsafe fn get_unchecked<'w>(1077&mut self,1078world: UnsafeWorldCell<'w>,1079entity: Entity,1080) -> Result<D::Item<'w, '_>, QueryEntityError> {1081self.query_unchecked(world).get_inner(entity)1082}10831084/// Returns an [`Iterator`] over the query results for the given [`World`].1085///1086/// This can only be called for read-only queries, see [`Self::iter_mut`] for write-queries.1087///1088/// If you need to iterate multiple times at once but get borrowing errors,1089/// consider using [`Self::update_archetypes`] followed by multiple [`Self::iter_manual`] calls.1090#[inline]1091pub fn iter<'w, 's>(&'s mut self, world: &'w World) -> QueryIter<'w, 's, D::ReadOnly, F> {1092self.query(world).into_iter()1093}10941095/// Returns an [`Iterator`] over the query results for the given [`World`].1096///1097/// This iterator is always guaranteed to return results from each matching entity once and only once.1098/// Iteration order is not guaranteed.1099#[inline]1100pub fn iter_mut<'w, 's>(&'s mut self, world: &'w mut World) -> QueryIter<'w, 's, D, F> {1101self.query_mut(world).into_iter()1102}11031104/// Returns an [`Iterator`] over the query results for the given [`World`] without updating the query's archetypes.1105/// Archetypes must be manually updated before by using [`Self::update_archetypes`].1106///1107/// This iterator is always guaranteed to return results from each matching entity once and only once.1108/// Iteration order is not guaranteed.1109///1110/// This can only be called for read-only queries.1111#[inline]1112pub fn iter_manual<'w, 's>(&'s self, world: &'w World) -> QueryIter<'w, 's, D::ReadOnly, F> {1113self.query_manual(world).into_iter()1114}11151116/// Returns an [`Iterator`] over all possible combinations of `K` query results without repetition.1117/// This can only be called for read-only queries.1118///1119/// A combination is an arrangement of a collection of items where order does not matter.1120///1121/// `K` is the number of items that make up each subset, and the number of items returned by the iterator.1122/// `N` is the number of total entities output by query.1123///1124/// For example, given the list [1, 2, 3, 4], where `K` is 2, the combinations without repeats are1125/// [1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4].1126/// And in this case, `N` would be defined as 4 since the size of the input list is 4.1127///1128/// For combinations of size `K` of query taking `N` inputs, you will get:1129/// - if `K == N`: one combination of all query results1130/// - if `K < N`: all possible `K`-sized combinations of query results, without repetition1131/// - if `K > N`: empty set (no `K`-sized combinations exist)1132///1133/// The `iter_combinations` method does not guarantee order of iteration.1134///1135/// This iterator is always guaranteed to return results from each unique pair of matching entities.1136/// Iteration order is not guaranteed.1137///1138/// This can only be called for read-only queries, see [`Self::iter_combinations_mut`] for1139/// write-queries.1140#[inline]1141pub fn iter_combinations<'w, 's, const K: usize>(1142&'s mut self,1143world: &'w World,1144) -> QueryCombinationIter<'w, 's, D::ReadOnly, F, K> {1145self.query(world).iter_combinations_inner()1146}11471148/// Returns an [`Iterator`] over all possible combinations of `K` query results without repetition.1149///1150/// A combination is an arrangement of a collection of items where order does not matter.1151///1152/// `K` is the number of items that make up each subset, and the number of items returned by the iterator.1153/// `N` is the number of total entities output by query.1154///1155/// For example, given the list [1, 2, 3, 4], where `K` is 2, the combinations without repeats are1156/// [1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4].1157/// And in this case, `N` would be defined as 4 since the size of the input list is 4.1158///1159/// For combinations of size `K` of query taking `N` inputs, you will get:1160/// - if `K == N`: one combination of all query results1161/// - if `K < N`: all possible `K`-sized combinations of query results, without repetition1162/// - if `K > N`: empty set (no `K`-sized combinations exist)1163///1164/// The `iter_combinations_mut` method does not guarantee order of iteration.1165#[inline]1166pub fn iter_combinations_mut<'w, 's, const K: usize>(1167&'s mut self,1168world: &'w mut World,1169) -> QueryCombinationIter<'w, 's, D, F, K> {1170self.query_mut(world).iter_combinations_inner()1171}11721173/// Returns an [`Iterator`] over the read-only query items generated from an [`Entity`] list.1174///1175/// Items are returned in the order of the list of entities.1176/// Entities that don't match the query are skipped.1177///1178/// If you need to iterate multiple times at once but get borrowing errors,1179/// consider using [`Self::update_archetypes`] followed by multiple [`Self::iter_many_manual`] calls.1180///1181/// # See also1182///1183/// - [`iter_many_mut`](Self::iter_many_mut) to get mutable query items.1184#[inline]1185pub fn iter_many<'w, 's, EntityList: IntoIterator<Item: EntityEquivalent>>(1186&'s mut self,1187world: &'w World,1188entities: EntityList,1189) -> QueryManyIter<'w, 's, D::ReadOnly, F, EntityList::IntoIter> {1190self.query(world).iter_many_inner(entities)1191}11921193/// Returns an [`Iterator`] over the read-only query items generated from an [`Entity`] list.1194///1195/// Items are returned in the order of the list of entities.1196/// Entities that don't match the query are skipped.1197///1198/// If `world` archetypes changed since [`Self::update_archetypes`] was last called,1199/// this will skip entities contained in new archetypes.1200///1201/// This can only be called for read-only queries.1202///1203/// # See also1204///1205/// - [`iter_many`](Self::iter_many) to update archetypes.1206/// - [`iter_manual`](Self::iter_manual) to iterate over all query items.1207#[inline]1208pub fn iter_many_manual<'w, 's, EntityList: IntoIterator<Item: EntityEquivalent>>(1209&'s self,1210world: &'w World,1211entities: EntityList,1212) -> QueryManyIter<'w, 's, D::ReadOnly, F, EntityList::IntoIter> {1213self.query_manual(world).iter_many_inner(entities)1214}12151216/// Returns an iterator over the query items generated from an [`Entity`] list.1217///1218/// Items are returned in the order of the list of entities.1219/// Entities that don't match the query are skipped.1220#[inline]1221pub fn iter_many_mut<'w, 's, EntityList: IntoIterator<Item: EntityEquivalent>>(1222&'s mut self,1223world: &'w mut World,1224entities: EntityList,1225) -> QueryManyIter<'w, 's, D, F, EntityList::IntoIter> {1226self.query_mut(world).iter_many_inner(entities)1227}12281229/// Returns an [`Iterator`] over the unique read-only query items generated from an [`EntitySet`].1230///1231/// Items are returned in the order of the list of entities.1232/// Entities that don't match the query are skipped.1233///1234/// # See also1235///1236/// - [`iter_many_unique_mut`](Self::iter_many_unique_mut) to get mutable query items.1237#[inline]1238pub fn iter_many_unique<'w, 's, EntityList: EntitySet>(1239&'s mut self,1240world: &'w World,1241entities: EntityList,1242) -> QueryManyUniqueIter<'w, 's, D::ReadOnly, F, EntityList::IntoIter> {1243self.query(world).iter_many_unique_inner(entities)1244}12451246/// Returns an [`Iterator`] over the unique read-only query items generated from an [`EntitySet`].1247///1248/// Items are returned in the order of the list of entities.1249/// Entities that don't match the query are skipped.1250///1251/// If `world` archetypes changed since [`Self::update_archetypes`] was last called,1252/// this will skip entities contained in new archetypes.1253///1254/// This can only be called for read-only queries.1255///1256/// # See also1257///1258/// - [`iter_many_unique`](Self::iter_many) to update archetypes.1259/// - [`iter_many`](Self::iter_many) to iterate over a non-unique entity list.1260/// - [`iter_manual`](Self::iter_manual) to iterate over all query items.1261#[inline]1262pub fn iter_many_unique_manual<'w, 's, EntityList: EntitySet>(1263&'s self,1264world: &'w World,1265entities: EntityList,1266) -> QueryManyUniqueIter<'w, 's, D::ReadOnly, F, EntityList::IntoIter> {1267self.query_manual(world).iter_many_unique_inner(entities)1268}12691270/// Returns an iterator over the unique query items generated from an [`EntitySet`].1271///1272/// Items are returned in the order of the list of entities.1273/// Entities that don't match the query are skipped.1274#[inline]1275pub fn iter_many_unique_mut<'w, 's, EntityList: EntitySet>(1276&'s mut self,1277world: &'w mut World,1278entities: EntityList,1279) -> QueryManyUniqueIter<'w, 's, D, F, EntityList::IntoIter> {1280self.query_mut(world).iter_many_unique_inner(entities)1281}1282/// Returns an [`Iterator`] over the query results for the given [`World`].1283///1284/// This iterator is always guaranteed to return results from each matching entity once and only once.1285/// Iteration order is not guaranteed.1286///1287/// # Safety1288///1289/// This does not check for mutable query correctness. To be safe, make sure mutable queries1290/// have unique access to the components they query.1291#[inline]1292pub unsafe fn iter_unchecked<'w, 's>(1293&'s mut self,1294world: UnsafeWorldCell<'w>,1295) -> QueryIter<'w, 's, D, F> {1296self.query_unchecked(world).into_iter()1297}12981299/// Returns an [`Iterator`] over all possible combinations of `K` query results for the1300/// given [`World`] without repetition.1301/// This can only be called for read-only queries.1302///1303/// This iterator is always guaranteed to return results from each unique pair of matching entities.1304/// Iteration order is not guaranteed.1305///1306/// # Safety1307///1308/// This does not check for mutable query correctness. To be safe, make sure mutable queries1309/// have unique access to the components they query.1310#[inline]1311pub unsafe fn iter_combinations_unchecked<'w, 's, const K: usize>(1312&'s mut self,1313world: UnsafeWorldCell<'w>,1314) -> QueryCombinationIter<'w, 's, D, F, K> {1315self.query_unchecked(world).iter_combinations_inner()1316}13171318/// Returns a parallel iterator over the query results for the given [`World`].1319///1320/// This can only be called for read-only queries, see [`par_iter_mut`] for write-queries.1321///1322/// Note that you must use the `for_each` method to iterate over the1323/// results, see [`par_iter_mut`] for an example.1324///1325/// [`par_iter_mut`]: Self::par_iter_mut1326#[inline]1327pub fn par_iter<'w, 's>(1328&'s mut self,1329world: &'w World,1330) -> QueryParIter<'w, 's, D::ReadOnly, F> {1331self.query(world).par_iter_inner()1332}13331334/// Returns a parallel iterator over the query results for the given [`World`].1335///1336/// This can only be called for mutable queries, see [`par_iter`] for read-only-queries.1337///1338/// # Examples1339///1340/// ```1341/// use bevy_ecs::prelude::*;1342/// use bevy_ecs::query::QueryEntityError;1343///1344/// #[derive(Component, PartialEq, Debug)]1345/// struct A(usize);1346///1347/// # bevy_tasks::ComputeTaskPool::get_or_init(|| bevy_tasks::TaskPool::new());1348///1349/// let mut world = World::new();1350///1351/// # let entities: Vec<Entity> = (0..3).map(|i| world.spawn(A(i)).id()).collect();1352/// # let entities: [Entity; 3] = entities.try_into().unwrap();1353///1354/// let mut query_state = world.query::<&mut A>();1355///1356/// query_state.par_iter_mut(&mut world).for_each(|mut a| {1357/// a.0 += 5;1358/// });1359///1360/// # let component_values = query_state.get_many(&world, entities).unwrap();1361///1362/// # assert_eq!(component_values, [&A(5), &A(6), &A(7)]);1363///1364/// # let wrong_entity = Entity::from_raw_u32(57).unwrap();1365/// # let invalid_entity = world.spawn_empty().id();1366///1367/// # assert_eq!(match query_state.get_many(&mut world, [wrong_entity]).unwrap_err() {QueryEntityError::EntityDoesNotExist(error) => error.entity, _ => panic!()}, wrong_entity);1368/// assert_eq!(match query_state.get_many_mut(&mut world, [invalid_entity]).unwrap_err() {QueryEntityError::QueryDoesNotMatch(entity, _) => entity, _ => panic!()}, invalid_entity);1369/// # assert_eq!(query_state.get_many_mut(&mut world, [entities[0], entities[0]]).unwrap_err(), QueryEntityError::AliasedMutability(entities[0]));1370/// ```1371///1372/// # Panics1373/// The [`ComputeTaskPool`] is not initialized. If using this from a query that is being1374/// initialized and run from the ECS scheduler, this should never panic.1375///1376/// [`par_iter`]: Self::par_iter1377/// [`ComputeTaskPool`]: bevy_tasks::ComputeTaskPool1378#[inline]1379pub fn par_iter_mut<'w, 's>(&'s mut self, world: &'w mut World) -> QueryParIter<'w, 's, D, F> {1380self.query_mut(world).par_iter_inner()1381}13821383/// Runs `func` on each query result in parallel for the given [`World`], where the last change and1384/// the current change tick are given. This is faster than the equivalent1385/// `iter()` method, but cannot be chained like a normal [`Iterator`].1386///1387/// # Panics1388/// The [`ComputeTaskPool`] is not initialized. If using this from a query that is being1389/// initialized and run from the ECS scheduler, this should never panic.1390///1391/// # Safety1392///1393/// This does not check for mutable query correctness. To be safe, make sure mutable queries1394/// have unique access to the components they query.1395/// This does not validate that `world.id()` matches `self.world_id`. Calling this on a `world`1396/// with a mismatched [`WorldId`] is unsound.1397///1398/// [`ComputeTaskPool`]: bevy_tasks::ComputeTaskPool1399#[cfg(all(not(target_arch = "wasm32"), feature = "multi_threaded"))]1400pub(crate) unsafe fn par_fold_init_unchecked_manual<'w, 's, T, FN, INIT>(1401&'s self,1402init_accum: INIT,1403world: UnsafeWorldCell<'w>,1404batch_size: u32,1405func: FN,1406last_run: Tick,1407this_run: Tick,1408) where1409FN: Fn(T, D::Item<'w, 's>) -> T + Send + Sync + Clone,1410INIT: Fn() -> T + Sync + Send + Clone,1411{1412// NOTE: If you are changing query iteration code, remember to update the following places, where relevant:1413// QueryIter, QueryIterationCursor, QueryManyIter, QueryCombinationIter,QueryState::par_fold_init_unchecked_manual,1414// QueryState::par_many_fold_init_unchecked_manual, QueryState::par_many_unique_fold_init_unchecked_manual1415use arrayvec::ArrayVec;14161417bevy_tasks::ComputeTaskPool::get().scope(|scope| {1418// SAFETY: We only access table data that has been registered in `self.component_access`.1419let tables = unsafe { &world.storages().tables };1420let archetypes = world.archetypes();1421let mut batch_queue = ArrayVec::new();1422let mut queue_entity_count = 0;14231424// submit a list of storages which smaller than batch_size as single task1425let submit_batch_queue = |queue: &mut ArrayVec<StorageId, 128>| {1426if queue.is_empty() {1427return;1428}1429let queue = core::mem::take(queue);1430let mut func = func.clone();1431let init_accum = init_accum.clone();1432scope.spawn(async move {1433#[cfg(feature = "trace")]1434let _span = self.par_iter_span.enter();1435let mut iter = self1436.query_unchecked_manual_with_ticks(world, last_run, this_run)1437.into_iter();1438let mut accum = init_accum();1439for storage_id in queue {1440accum = iter.fold_over_storage_range(accum, &mut func, storage_id, None);1441}1442});1443};14441445// submit single storage larger than batch_size1446let submit_single = |count, storage_id: StorageId| {1447for offset in (0..count).step_by(batch_size as usize) {1448let mut func = func.clone();1449let init_accum = init_accum.clone();1450let len = batch_size.min(count - offset);1451let batch = offset..offset + len;1452scope.spawn(async move {1453#[cfg(feature = "trace")]1454let _span = self.par_iter_span.enter();1455let accum = init_accum();1456self.query_unchecked_manual_with_ticks(world, last_run, this_run)1457.into_iter()1458.fold_over_storage_range(accum, &mut func, storage_id, Some(batch));1459});1460}1461};14621463let storage_entity_count = |storage_id: StorageId| -> u32 {1464if self.is_dense {1465tables[storage_id.table_id].entity_count()1466} else {1467archetypes[storage_id.archetype_id].len()1468}1469};14701471for storage_id in &self.matched_storage_ids {1472let count = storage_entity_count(*storage_id);14731474// skip empty storage1475if count == 0 {1476continue;1477}1478// immediately submit large storage1479if count >= batch_size {1480submit_single(count, *storage_id);1481continue;1482}1483// merge small storage1484batch_queue.push(*storage_id);1485queue_entity_count += count;14861487// submit batch_queue1488if queue_entity_count >= batch_size || batch_queue.is_full() {1489submit_batch_queue(&mut batch_queue);1490queue_entity_count = 0;1491}1492}1493submit_batch_queue(&mut batch_queue);1494});1495}14961497/// Runs `func` on each query result in parallel for the given [`EntitySet`],1498/// where the last change and the current change tick are given. This is faster than the1499/// equivalent `iter_many_unique()` method, but cannot be chained like a normal [`Iterator`].1500///1501/// # Panics1502/// The [`ComputeTaskPool`] is not initialized. If using this from a query that is being1503/// initialized and run from the ECS scheduler, this should never panic.1504///1505/// # Safety1506///1507/// This does not check for mutable query correctness. To be safe, make sure mutable queries1508/// have unique access to the components they query.1509/// This does not validate that `world.id()` matches `self.world_id`. Calling this on a `world`1510/// with a mismatched [`WorldId`] is unsound.1511///1512/// [`ComputeTaskPool`]: bevy_tasks::ComputeTaskPool1513#[cfg(all(not(target_arch = "wasm32"), feature = "multi_threaded"))]1514pub(crate) unsafe fn par_many_unique_fold_init_unchecked_manual<'w, 's, T, FN, INIT, E>(1515&'s self,1516init_accum: INIT,1517world: UnsafeWorldCell<'w>,1518entity_list: &UniqueEntityEquivalentSlice<E>,1519batch_size: u32,1520mut func: FN,1521last_run: Tick,1522this_run: Tick,1523) where1524FN: Fn(T, D::Item<'w, 's>) -> T + Send + Sync + Clone,1525INIT: Fn() -> T + Sync + Send + Clone,1526E: EntityEquivalent + Sync,1527{1528// NOTE: If you are changing query iteration code, remember to update the following places, where relevant:1529// QueryIter, QueryIterationCursor, QueryManyIter, QueryCombinationIter,QueryState::par_fold_init_unchecked_manual1530// QueryState::par_many_fold_init_unchecked_manual, QueryState::par_many_unique_fold_init_unchecked_manual15311532bevy_tasks::ComputeTaskPool::get().scope(|scope| {1533let chunks = entity_list.chunks_exact(batch_size as usize);1534let remainder = chunks.remainder();15351536for batch in chunks {1537let mut func = func.clone();1538let init_accum = init_accum.clone();1539scope.spawn(async move {1540#[cfg(feature = "trace")]1541let _span = self.par_iter_span.enter();1542let accum = init_accum();1543self.query_unchecked_manual_with_ticks(world, last_run, this_run)1544.iter_many_unique_inner(batch)1545.fold(accum, &mut func);1546});1547}15481549#[cfg(feature = "trace")]1550let _span = self.par_iter_span.enter();1551let accum = init_accum();1552self.query_unchecked_manual_with_ticks(world, last_run, this_run)1553.iter_many_unique_inner(remainder)1554.fold(accum, &mut func);1555});1556}1557}15581559impl<D: ReadOnlyQueryData, F: QueryFilter> QueryState<D, F> {1560/// Runs `func` on each read-only query result in parallel for the given [`Entity`] list,1561/// where the last change and the current change tick are given. This is faster than the equivalent1562/// `iter_many()` method, but cannot be chained like a normal [`Iterator`].1563///1564/// # Panics1565/// The [`ComputeTaskPool`] is not initialized. If using this from a query that is being1566/// initialized and run from the ECS scheduler, this should never panic.1567///1568/// # Safety1569///1570/// This does not check for mutable query correctness. To be safe, make sure mutable queries1571/// have unique access to the components they query.1572/// This does not validate that `world.id()` matches `self.world_id`. Calling this on a `world`1573/// with a mismatched [`WorldId`] is unsound.1574///1575/// [`ComputeTaskPool`]: bevy_tasks::ComputeTaskPool1576#[cfg(all(not(target_arch = "wasm32"), feature = "multi_threaded"))]1577pub(crate) unsafe fn par_many_fold_init_unchecked_manual<'w, 's, T, FN, INIT, E>(1578&'s self,1579init_accum: INIT,1580world: UnsafeWorldCell<'w>,1581entity_list: &[E],1582batch_size: u32,1583mut func: FN,1584last_run: Tick,1585this_run: Tick,1586) where1587FN: Fn(T, D::Item<'w, 's>) -> T + Send + Sync + Clone,1588INIT: Fn() -> T + Sync + Send + Clone,1589E: EntityEquivalent + Sync,1590{1591// NOTE: If you are changing query iteration code, remember to update the following places, where relevant:1592// QueryIter, QueryIterationCursor, QueryManyIter, QueryCombinationIter, QueryState::par_fold_init_unchecked_manual1593// QueryState::par_many_fold_init_unchecked_manual, QueryState::par_many_unique_fold_init_unchecked_manual15941595bevy_tasks::ComputeTaskPool::get().scope(|scope| {1596let chunks = entity_list.chunks_exact(batch_size as usize);1597let remainder = chunks.remainder();15981599for batch in chunks {1600let mut func = func.clone();1601let init_accum = init_accum.clone();1602scope.spawn(async move {1603#[cfg(feature = "trace")]1604let _span = self.par_iter_span.enter();1605let accum = init_accum();1606self.query_unchecked_manual_with_ticks(world, last_run, this_run)1607.iter_many_inner(batch)1608.fold(accum, &mut func);1609});1610}16111612#[cfg(feature = "trace")]1613let _span = self.par_iter_span.enter();1614let accum = init_accum();1615self.query_unchecked_manual_with_ticks(world, last_run, this_run)1616.iter_many_inner(remainder)1617.fold(accum, &mut func);1618});1619}1620}16211622impl<D: QueryData, F: QueryFilter> QueryState<D, F> {1623/// Returns a single immutable query result when there is exactly one entity matching1624/// the query.1625///1626/// This can only be called for read-only queries,1627/// see [`single_mut`](Self::single_mut) for write-queries.1628///1629/// If the number of query results is not exactly one, a [`QuerySingleError`] is returned1630/// instead.1631///1632/// # Example1633///1634/// Sometimes, you might want to handle the error in a specific way,1635/// generally by spawning the missing entity.1636///1637/// ```rust1638/// use bevy_ecs::prelude::*;1639/// use bevy_ecs::query::QuerySingleError;1640///1641/// #[derive(Component)]1642/// struct A(usize);1643///1644/// fn my_system(query: Query<&A>, mut commands: Commands) {1645/// match query.single() {1646/// Ok(a) => (), // Do something with `a`1647/// Err(err) => match err {1648/// QuerySingleError::NoEntities(_) => {1649/// commands.spawn(A(0));1650/// }1651/// QuerySingleError::MultipleEntities(_) => panic!("Multiple entities found!"),1652/// },1653/// }1654/// }1655/// ```1656///1657/// However in most cases, this error can simply be handled with a graceful early return.1658/// If this is an expected failure mode, you can do this using the `let else` pattern like so:1659/// ```rust1660/// use bevy_ecs::prelude::*;1661///1662/// #[derive(Component)]1663/// struct A(usize);1664///1665/// fn my_system(query: Query<&A>) {1666/// let Ok(a) = query.single() else {1667/// return;1668/// };1669///1670/// // Do something with `a`1671/// }1672/// ```1673///1674/// If this is unexpected though, you should probably use the `?` operator1675/// in combination with Bevy's error handling apparatus.1676///1677/// ```rust1678/// use bevy_ecs::prelude::*;1679///1680/// #[derive(Component)]1681/// struct A(usize);1682///1683/// fn my_system(query: Query<&A>) -> Result {1684/// let a = query.single()?;1685///1686/// // Do something with `a`1687/// Ok(())1688/// }1689/// ```1690///1691/// This allows you to globally control how errors are handled in your application,1692/// by setting up a custom error handler.1693/// See the [`bevy_ecs::error`] module docs for more information!1694/// Commonly, you might want to panic on an error during development, but log the error and continue1695/// execution in production.1696///1697/// Simply unwrapping the [`Result`] also works, but should generally be reserved for tests.1698#[inline]1699pub fn single<'w>(1700&mut self,1701world: &'w World,1702) -> Result<ROQueryItem<'w, '_, D>, QuerySingleError> {1703self.query(world).single_inner()1704}17051706/// Returns a single mutable query result when there is exactly one entity matching1707/// the query.1708///1709/// If the number of query results is not exactly one, a [`QuerySingleError`] is returned1710/// instead.1711///1712/// # Examples1713///1714/// Please see [`Query::single`] for advice on handling the error.1715#[inline]1716pub fn single_mut<'w>(1717&mut self,1718world: &'w mut World,1719) -> Result<D::Item<'w, '_>, QuerySingleError> {1720self.query_mut(world).single_inner()1721}17221723/// Returns a query result when there is exactly one entity matching the query.1724///1725/// If the number of query results is not exactly one, a [`QuerySingleError`] is returned1726/// instead.1727///1728/// # Safety1729///1730/// This does not check for mutable query correctness. To be safe, make sure mutable queries1731/// have unique access to the components they query.1732#[inline]1733pub unsafe fn single_unchecked<'w>(1734&mut self,1735world: UnsafeWorldCell<'w>,1736) -> Result<D::Item<'w, '_>, QuerySingleError> {1737self.query_unchecked(world).single_inner()1738}17391740/// Returns a query result when there is exactly one entity matching the query,1741/// where the last change and the current change tick are given.1742///1743/// If the number of query results is not exactly one, a [`QuerySingleError`] is returned1744/// instead.1745///1746/// # Safety1747///1748/// This does not check for mutable query correctness. To be safe, make sure mutable queries1749/// have unique access to the components they query.1750/// This does not validate that `world.id()` matches `self.world_id`. Calling this on a `world`1751/// with a mismatched [`WorldId`] is unsound.1752#[inline]1753pub unsafe fn single_unchecked_manual<'w>(1754&self,1755world: UnsafeWorldCell<'w>,1756last_run: Tick,1757this_run: Tick,1758) -> Result<D::Item<'w, '_>, QuerySingleError> {1759// SAFETY:1760// - The caller ensured we have the correct access to the world.1761// - The caller ensured that the world matches.1762self.query_unchecked_manual_with_ticks(world, last_run, this_run)1763.single_inner()1764}1765}17661767impl<D: QueryData, F: QueryFilter> From<QueryBuilder<'_, D, F>> for QueryState<D, F> {1768fn from(mut value: QueryBuilder<D, F>) -> Self {1769QueryState::from_builder(&mut value)1770}1771}17721773#[cfg(test)]1774mod tests {1775use crate::{1776component::Component,1777entity_disabling::DefaultQueryFilters,1778prelude::*,1779system::{QueryLens, RunSystemOnce},1780world::{FilteredEntityMut, FilteredEntityRef},1781};17821783#[test]1784#[should_panic]1785fn right_world_get() {1786let mut world_1 = World::new();1787let world_2 = World::new();17881789let mut query_state = world_1.query::<Entity>();1790let _panics = query_state.get(&world_2, Entity::from_raw_u32(0).unwrap());1791}17921793#[test]1794#[should_panic]1795fn right_world_get_many() {1796let mut world_1 = World::new();1797let world_2 = World::new();17981799let mut query_state = world_1.query::<Entity>();1800let _panics = query_state.get_many(&world_2, []);1801}18021803#[test]1804#[should_panic]1805fn right_world_get_many_mut() {1806let mut world_1 = World::new();1807let mut world_2 = World::new();18081809let mut query_state = world_1.query::<Entity>();1810let _panics = query_state.get_many_mut(&mut world_2, []);1811}18121813#[derive(Component, PartialEq, Debug)]1814struct A(usize);18151816#[derive(Component, PartialEq, Debug)]1817struct B(usize);18181819#[derive(Component, PartialEq, Debug)]1820struct C(usize);18211822#[test]1823fn can_transmute_to_more_general() {1824let mut world = World::new();1825world.spawn((A(1), B(0)));18261827let query_state = world.query::<(&A, &B)>();1828let mut new_query_state = query_state.transmute::<&A>(&world);1829assert_eq!(new_query_state.iter(&world).len(), 1);1830let a = new_query_state.single(&world).unwrap();18311832assert_eq!(a.0, 1);1833}18341835#[test]1836fn cannot_get_data_not_in_original_query() {1837let mut world = World::new();1838world.spawn((A(0), B(0)));1839world.spawn((A(1), B(0), C(0)));18401841let query_state = world.query_filtered::<(&A, &B), Without<C>>();1842let mut new_query_state = query_state.transmute::<&A>(&world);1843// even though we change the query to not have Without<C>, we do not get the component with C.1844let a = new_query_state.single(&world).unwrap();18451846assert_eq!(a.0, 0);1847}18481849#[test]1850fn can_transmute_empty_tuple() {1851let mut world = World::new();1852world.register_component::<A>();1853let entity = world.spawn(A(10)).id();18541855let q = world.query::<()>();1856let mut q = q.transmute::<Entity>(&world);1857assert_eq!(q.single(&world).unwrap(), entity);1858}18591860#[test]1861fn can_transmute_immut_fetch() {1862let mut world = World::new();1863world.spawn(A(10));18641865let q = world.query::<&A>();1866let mut new_q = q.transmute::<Ref<A>>(&world);1867assert!(new_q.single(&world).unwrap().is_added());18681869let q = world.query::<Ref<A>>();1870let _ = q.transmute::<&A>(&world);1871}18721873#[test]1874fn can_transmute_mut_fetch() {1875let mut world = World::new();1876world.spawn(A(0));18771878let q = world.query::<&mut A>();1879let _ = q.transmute::<Ref<A>>(&world);1880let _ = q.transmute::<&A>(&world);1881}18821883#[test]1884fn can_transmute_entity_mut() {1885let mut world = World::new();1886world.spawn(A(0));18871888let q: QueryState<EntityMut<'_>> = world.query::<EntityMut>();1889let _ = q.transmute::<EntityRef>(&world);1890}18911892#[test]1893fn can_generalize_with_option() {1894let mut world = World::new();1895world.spawn((A(0), B(0)));18961897let query_state = world.query::<(Option<&A>, &B)>();1898let _ = query_state.transmute::<Option<&A>>(&world);1899let _ = query_state.transmute::<&B>(&world);1900}19011902#[test]1903#[should_panic]1904fn cannot_transmute_to_include_data_not_in_original_query() {1905let mut world = World::new();1906world.register_component::<A>();1907world.register_component::<B>();1908world.spawn(A(0));19091910let query_state = world.query::<&A>();1911let mut _new_query_state = query_state.transmute::<(&A, &B)>(&world);1912}19131914#[test]1915#[should_panic]1916fn cannot_transmute_immut_to_mut() {1917let mut world = World::new();1918world.spawn(A(0));19191920let query_state = world.query::<&A>();1921let mut _new_query_state = query_state.transmute::<&mut A>(&world);1922}19231924#[test]1925#[should_panic]1926fn cannot_transmute_option_to_immut() {1927let mut world = World::new();1928world.spawn(C(0));19291930let query_state = world.query::<Option<&A>>();1931let mut new_query_state = query_state.transmute::<&A>(&world);1932let x = new_query_state.single(&world).unwrap();1933assert_eq!(x.0, 1234);1934}19351936#[test]1937#[should_panic]1938fn cannot_transmute_entity_ref() {1939let mut world = World::new();1940world.register_component::<A>();19411942let q = world.query::<EntityRef>();1943let _ = q.transmute::<&A>(&world);1944}19451946#[test]1947fn can_transmute_filtered_entity() {1948let mut world = World::new();1949let entity = world.spawn((A(0), B(1))).id();1950let query = QueryState::<(Entity, &A, &B)>::new(&mut world)1951.transmute::<(Entity, FilteredEntityRef)>(&world);19521953let mut query = query;1954// Our result is completely untyped1955let (_entity, entity_ref) = query.single(&world).unwrap();19561957assert_eq!(entity, entity_ref.id());1958assert_eq!(0, entity_ref.get::<A>().unwrap().0);1959assert_eq!(1, entity_ref.get::<B>().unwrap().0);1960}19611962#[test]1963fn can_transmute_added() {1964let mut world = World::new();1965let entity_a = world.spawn(A(0)).id();19661967let mut query = QueryState::<(Entity, &A, Has<B>)>::new(&mut world)1968.transmute_filtered::<(Entity, Has<B>), Added<A>>(&world);19691970assert_eq!((entity_a, false), query.single(&world).unwrap());19711972world.clear_trackers();19731974let entity_b = world.spawn((A(0), B(0))).id();1975assert_eq!((entity_b, true), query.single(&world).unwrap());19761977world.clear_trackers();19781979assert!(query.single(&world).is_err());1980}19811982#[test]1983fn can_transmute_changed() {1984let mut world = World::new();1985let entity_a = world.spawn(A(0)).id();19861987let mut detection_query = QueryState::<(Entity, &A)>::new(&mut world)1988.transmute_filtered::<Entity, Changed<A>>(&world);19891990let mut change_query = QueryState::<&mut A>::new(&mut world);1991assert_eq!(entity_a, detection_query.single(&world).unwrap());19921993world.clear_trackers();19941995assert!(detection_query.single(&world).is_err());19961997change_query.single_mut(&mut world).unwrap().0 = 1;19981999assert_eq!(entity_a, detection_query.single(&world).unwrap());2000}20012002#[test]2003#[should_panic]2004fn cannot_transmute_changed_without_access() {2005let mut world = World::new();2006world.register_component::<A>();2007world.register_component::<B>();2008let query = QueryState::<&A>::new(&mut world);2009let _new_query = query.transmute_filtered::<Entity, Changed<B>>(&world);2010}20112012#[test]2013#[should_panic]2014fn cannot_transmute_mutable_after_readonly() {2015let mut world = World::new();2016// Calling this method would mean we had aliasing queries.2017fn bad(_: Query<&mut A>, _: Query<&A>) {}2018world2019.run_system_once(|query: Query<&mut A>| {2020let mut readonly = query.as_readonly();2021let mut lens: QueryLens<&mut A> = readonly.transmute_lens();2022bad(lens.query(), query.as_readonly());2023})2024.unwrap();2025}20262027// Regression test for #146292028#[test]2029#[should_panic]2030fn transmute_with_different_world() {2031let mut world = World::new();2032world.spawn((A(1), B(2)));20332034let mut world2 = World::new();2035world2.register_component::<B>();20362037world.query::<(&A, &B)>().transmute::<&B>(&world2);2038}20392040/// Regression test for issue #145282041#[test]2042fn transmute_from_sparse_to_dense() {2043#[derive(Component)]2044struct Dense;20452046#[derive(Component)]2047#[component(storage = "SparseSet")]2048struct Sparse;20492050let mut world = World::new();20512052world.spawn(Dense);2053world.spawn((Dense, Sparse));20542055let mut query = world2056.query_filtered::<&Dense, With<Sparse>>()2057.transmute::<&Dense>(&world);20582059let matched = query.iter(&world).count();2060assert_eq!(matched, 1);2061}2062#[test]2063fn transmute_from_dense_to_sparse() {2064#[derive(Component)]2065struct Dense;20662067#[derive(Component)]2068#[component(storage = "SparseSet")]2069struct Sparse;20702071let mut world = World::new();20722073world.spawn(Dense);2074world.spawn((Dense, Sparse));20752076let mut query = world2077.query::<&Dense>()2078.transmute_filtered::<&Dense, With<Sparse>>(&world);20792080// Note: `transmute_filtered` is supposed to keep the same matched tables/archetypes,2081// so it doesn't actually filter out those entities without `Sparse` and the iteration2082// remains dense.2083let matched = query.iter(&world).count();2084assert_eq!(matched, 2);2085}20862087#[test]2088fn join() {2089let mut world = World::new();2090world.spawn(A(0));2091world.spawn(B(1));2092let entity_ab = world.spawn((A(2), B(3))).id();2093world.spawn((A(4), B(5), C(6)));20942095let query_1 = QueryState::<&A, Without<C>>::new(&mut world);2096let query_2 = QueryState::<&B, Without<C>>::new(&mut world);2097let mut new_query: QueryState<Entity, ()> = query_1.join_filtered(&world, &query_2);20982099assert_eq!(new_query.single(&world).unwrap(), entity_ab);2100}21012102#[test]2103fn join_with_get() {2104let mut world = World::new();2105world.spawn(A(0));2106world.spawn(B(1));2107let entity_ab = world.spawn((A(2), B(3))).id();2108let entity_abc = world.spawn((A(4), B(5), C(6))).id();21092110let query_1 = QueryState::<&A>::new(&mut world);2111let query_2 = QueryState::<&B, Without<C>>::new(&mut world);2112let mut new_query: QueryState<Entity, ()> = query_1.join_filtered(&world, &query_2);21132114assert!(new_query.get(&world, entity_ab).is_ok());2115// should not be able to get entity with c.2116assert!(new_query.get(&world, entity_abc).is_err());2117}21182119#[test]2120#[should_panic]2121fn cannot_join_wrong_fetch() {2122let mut world = World::new();2123world.register_component::<C>();2124let query_1 = QueryState::<&A>::new(&mut world);2125let query_2 = QueryState::<&B>::new(&mut world);2126let _query: QueryState<&C> = query_1.join(&world, &query_2);2127}21282129#[test]2130#[should_panic]2131fn cannot_join_wrong_filter() {2132let mut world = World::new();2133let query_1 = QueryState::<&A, Without<C>>::new(&mut world);2134let query_2 = QueryState::<&B, Without<C>>::new(&mut world);2135let _: QueryState<Entity, Changed<C>> = query_1.join_filtered(&world, &query_2);2136}21372138#[test]2139#[should_panic]2140fn cannot_join_mutable_after_readonly() {2141let mut world = World::new();2142// Calling this method would mean we had aliasing queries.2143fn bad(_: Query<(&mut A, &mut B)>, _: Query<&A>) {}2144world2145.run_system_once(|query_a: Query<&mut A>, mut query_b: Query<&mut B>| {2146let mut readonly = query_a.as_readonly();2147let mut lens: QueryLens<(&mut A, &mut B)> = readonly.join(&mut query_b);2148bad(lens.query(), query_a.as_readonly());2149})2150.unwrap();2151}21522153#[test]2154fn join_to_filtered_entity_mut() {2155let mut world = World::new();2156world.spawn((A(2), B(3)));21572158let query_1 = QueryState::<&mut A>::new(&mut world);2159let query_2 = QueryState::<&mut B>::new(&mut world);2160let mut new_query: QueryState<(Entity, FilteredEntityMut)> = query_1.join(&world, &query_2);21612162let (_entity, mut entity_mut) = new_query.single_mut(&mut world).unwrap();2163assert!(entity_mut.get_mut::<A>().is_some());2164assert!(entity_mut.get_mut::<B>().is_some());2165}21662167#[test]2168fn query_respects_default_filters() {2169let mut world = World::new();2170world.spawn((A(0), B(0)));2171world.spawn((B(0), C(0)));2172world.spawn(C(0));21732174world.register_disabling_component::<C>();21752176// Without<C> only matches the first entity2177let mut query = QueryState::<()>::new(&mut world);2178assert_eq!(1, query.iter(&world).count());21792180// With<C> matches the last two entities2181let mut query = QueryState::<(), With<C>>::new(&mut world);2182assert_eq!(2, query.iter(&world).count());21832184// Has should bypass the filter entirely2185let mut query = QueryState::<Has<C>>::new(&mut world);2186assert_eq!(3, query.iter(&world).count());21872188// Allow should bypass the filter entirely2189let mut query = QueryState::<(), Allow<C>>::new(&mut world);2190assert_eq!(3, query.iter(&world).count());21912192// Other filters should still be respected2193let mut query = QueryState::<Has<C>, Without<B>>::new(&mut world);2194assert_eq!(1, query.iter(&world).count());2195}21962197#[derive(Component)]2198struct Table;21992200#[derive(Component)]2201#[component(storage = "SparseSet")]2202struct Sparse;22032204#[test]2205fn query_default_filters_updates_is_dense() {2206let mut world = World::new();2207world.spawn((Table, Sparse));2208world.spawn(Table);2209world.spawn(Sparse);22102211let mut query = QueryState::<()>::new(&mut world);2212// There are no sparse components involved thus the query is dense2213assert!(query.is_dense);2214assert_eq!(3, query.query(&world).count());22152216world.register_disabling_component::<Sparse>();22172218let mut query = QueryState::<()>::new(&mut world);2219// The query doesn't ask for sparse components, but the default filters adds2220// a sparse components thus it is NOT dense2221assert!(!query.is_dense);2222assert_eq!(1, query.query(&world).count());22232224let mut df = DefaultQueryFilters::from_world(&mut world);2225df.register_disabling_component(world.register_component::<Table>());2226world.insert_resource(df);22272228let mut query = QueryState::<()>::new(&mut world);2229// If the filter is instead a table components, the query can still be dense2230assert!(query.is_dense);2231assert_eq!(1, query.query(&world).count());22322233let mut query = QueryState::<&Sparse>::new(&mut world);2234// But only if the original query was dense2235assert!(!query.is_dense);2236assert_eq!(1, query.query(&world).count());2237}2238}223922402241