use crate::{1archetype::{Archetype, ArchetypeGeneration, ArchetypeId},2change_detection::Tick,3component::ComponentId,4entity::{Entity, EntityEquivalent, EntitySet, UniqueEntityArray},5entity_disabling::DefaultQueryFilters,6prelude::FromWorld,7query::{8ArchetypeFilter, ContiguousQueryData, FilteredAccess, QueryCombinationIter,9QueryContiguousIter, QueryIter, QueryParIter, WorldQuery,10},11storage::{SparseSetIndex, TableId},12system::Query,13world::{unsafe_world_cell::UnsafeWorldCell, World, WorldId},14};1516#[cfg(all(not(target_arch = "wasm32"), feature = "multi_threaded"))]17use crate::entity::UniqueEntityEquivalentSlice;1819use alloc::vec::Vec;20use bevy_utils::prelude::DebugName;21use core::{fmt, ptr};22use fixedbitset::FixedBitSet;23use log::warn;24#[cfg(feature = "trace")]25use tracing::Span;2627use super::{28NopWorldQuery, QueryBuilder, QueryData, QueryEntityError, QueryFilter, QueryManyIter,29QueryManyUniqueIter, QuerySingleError, ROQueryItem, ReadOnlyQueryData,30};3132/// An ID for either a table or an archetype. Used for Query iteration.33///34/// Query iteration is exclusively dense (over tables) or archetypal (over archetypes) based on whether35/// the query filters are dense or not. This is represented by the [`QueryState::is_dense`] field.36///37/// Note that `D::IS_DENSE` and `F::IS_DENSE` have no relationship with `QueryState::is_dense` and38/// any combination of their values can happen.39///40/// This is a union instead of an enum as the usage is determined at compile time, as all [`StorageId`]s for41/// a [`QueryState`] will be all [`TableId`]s or all [`ArchetypeId`]s, and not a mixture of both. This42/// removes the need for discriminator to minimize memory usage and branching during iteration, but requires43/// a safety invariant be verified when disambiguating them.44///45/// # Safety46/// Must be initialized and accessed as a [`TableId`], if both generic parameters to the query are dense.47/// Must be initialized and accessed as an [`ArchetypeId`] otherwise.48#[derive(Clone, Copy)]49pub(super) union StorageId {50pub(super) table_id: TableId,51pub(super) archetype_id: ArchetypeId,52}5354/// Provides scoped access to a [`World`] state according to a given [`QueryData`] and [`QueryFilter`].55///56/// This data is cached between system runs, and is used to:57/// - store metadata about which [`Table`] or [`Archetype`] are matched by the query. "Matched" means58/// that the query will iterate over the data in the matched table/archetype.59/// - cache the [`State`] needed to compute the [`Fetch`] struct used to retrieve data60/// from a specific [`Table`] or [`Archetype`]61/// - build iterators that can iterate over the query results62///63/// [`State`]: crate::query::world_query::WorldQuery::State64/// [`Fetch`]: crate::query::world_query::WorldQuery::Fetch65/// [`Table`]: crate::storage::Table66#[repr(C)]67// SAFETY NOTE:68// Do not add any new fields that use the `D` or `F` generic parameters as this may69// make `QueryState::as_transmuted_state` unsound if not done with care.70pub struct QueryState<D: QueryData, F: QueryFilter = ()> {71world_id: WorldId,72pub(crate) archetype_generation: ArchetypeGeneration,73/// Metadata about the [`Table`](crate::storage::Table)s matched by this query.74pub(crate) matched_tables: FixedBitSet,75/// Metadata about the [`Archetype`]s matched by this query.76pub(crate) matched_archetypes: FixedBitSet,77/// [`FilteredAccess`] computed by combining the `D` and `F` access. Used to check which other queries78/// this query can run in parallel with.79/// Note that because we do a zero-cost reference conversion in `Query::as_readonly`,80/// the access for a read-only query may include accesses for the original mutable version,81/// but the `Query` does not have exclusive access to those components.82pub(crate) component_access: FilteredAccess,83// NOTE: we maintain both a bitset and a vec because iterating the vec is faster84pub(super) matched_storage_ids: Vec<StorageId>,85// Represents whether this query iteration is dense or not. When this is true86// `matched_storage_ids` stores `TableId`s, otherwise it stores `ArchetypeId`s.87pub(super) is_dense: bool,88pub(crate) fetch_state: D::State,89pub(crate) filter_state: F::State,90#[cfg(feature = "trace")]91par_iter_span: Span,92}9394impl<D: QueryData, F: QueryFilter> fmt::Debug for QueryState<D, F> {95fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {96f.debug_struct("QueryState")97.field("world_id", &self.world_id)98.field("matched_table_count", &self.matched_tables.count_ones(..))99.field(100"matched_archetype_count",101&self.matched_archetypes.count_ones(..),102)103.finish_non_exhaustive()104}105}106107impl<D: QueryData, F: QueryFilter> FromWorld for QueryState<D, F> {108fn from_world(world: &mut World) -> Self {109world.query_filtered()110}111}112113impl<D: QueryData, F: QueryFilter> QueryState<D, F> {114/// Converts this `QueryState` reference to a `QueryState` that does not access anything mutably.115pub fn as_readonly(&self) -> &QueryState<D::ReadOnly, F> {116// SAFETY: invariant on `WorldQuery` trait upholds that `D::ReadOnly` and `F::ReadOnly`117// have a subset of the access, and match the exact same archetypes/tables as `D`/`F` respectively.118unsafe { self.as_transmuted_state::<D::ReadOnly, F>() }119}120121/// Converts this `QueryState` reference to a `QueryState` that does not return any data122/// which can be faster.123///124/// This doesn't use `NopWorldQuery` as it loses filter functionality, for example125/// `NopWorldQuery<Changed<T>>` is functionally equivalent to `With<T>`.126pub(crate) fn as_nop(&self) -> &QueryState<NopWorldQuery<D>, F> {127// SAFETY: `NopWorldQuery` doesn't have any accesses and defers to128// `D` for table/archetype matching129unsafe { self.as_transmuted_state::<NopWorldQuery<D>, F>() }130}131132/// Converts this `QueryState` reference to any other `QueryState` with133/// the same `WorldQuery::State` associated types.134///135/// Consider using `as_readonly` or `as_nop` instead which are safe functions.136///137/// # Safety138///139/// `NewD` must have a subset of the access that `D` does and match the exact same archetypes/tables140/// `NewF` must have a subset of the access that `F` does and match the exact same archetypes/tables141pub(crate) unsafe fn as_transmuted_state<142NewD: ReadOnlyQueryData<State = D::State>,143NewF: QueryFilter<State = F::State>,144>(145&self,146) -> &QueryState<NewD, NewF> {147&*ptr::from_ref(self).cast::<QueryState<NewD, NewF>>()148}149150/// Returns the components accessed by this query.151pub fn component_access(&self) -> &FilteredAccess {152&self.component_access153}154155/// Returns the tables matched by this query.156pub fn matched_tables(&self) -> impl Iterator<Item = TableId> + '_ {157self.matched_tables.ones().map(TableId::from_usize)158}159160/// Returns the archetypes matched by this query.161pub fn matched_archetypes(&self) -> impl Iterator<Item = ArchetypeId> + '_ {162self.matched_archetypes.ones().map(ArchetypeId::new)163}164165/// Creates a new [`QueryState`] from a given [`World`] and inherits the result of `world.id()`.166pub fn new(world: &mut World) -> Self {167let mut state = Self::new_uninitialized(world);168state.update_archetypes(world);169state170}171172/// Creates a new [`QueryState`] from an immutable [`World`] reference and inherits the result of `world.id()`.173///174/// This function may fail if, for example,175/// the components that make up this query have not been registered into the world.176pub fn try_new(world: &World) -> Option<Self> {177let mut state = Self::try_new_uninitialized(world)?;178state.update_archetypes(world);179Some(state)180}181182/// Creates a new [`QueryState`] but does not populate it with the matched results from the World yet183///184/// `new_archetype` and its variants must be called on all of the World's archetypes before the185/// state can return valid query results.186fn new_uninitialized(world: &mut World) -> Self {187let fetch_state = D::init_state(world);188let filter_state = F::init_state(world);189Self::from_states_uninitialized(world, fetch_state, filter_state)190}191192/// Creates a new [`QueryState`] but does not populate it with the matched results from the World yet193///194/// `new_archetype` and its variants must be called on all of the World's archetypes before the195/// state can return valid query results.196fn try_new_uninitialized(world: &World) -> Option<Self> {197let fetch_state = D::get_state(world.components())?;198let filter_state = F::get_state(world.components())?;199Some(Self::from_states_uninitialized(200world,201fetch_state,202filter_state,203))204}205206/// Creates a new [`QueryState`] but does not populate it with the matched results from the World yet207///208/// `new_archetype` and its variants must be called on all of the World's archetypes before the209/// state can return valid query results.210fn from_states_uninitialized(211world: &World,212fetch_state: <D as WorldQuery>::State,213filter_state: <F as WorldQuery>::State,214) -> Self {215let mut component_access = FilteredAccess::default();216D::update_component_access(&fetch_state, &mut component_access);217218// Use a temporary empty FilteredAccess for filters. This prevents them from conflicting with the219// main Query's `fetch_state` access. Filters are allowed to conflict with the main query fetch220// because they are evaluated *before* a specific reference is constructed.221let mut filter_component_access = FilteredAccess::default();222F::update_component_access(&filter_state, &mut filter_component_access);223224// Merge the temporary filter access with the main access. This ensures that filter access is225// properly considered in a global "cross-query" context (both within systems and across systems).226component_access.extend(&filter_component_access);227228// For queries without dynamic filters the dense-ness of the query is equal to the dense-ness229// of its static type parameters.230let mut is_dense = D::IS_DENSE && F::IS_DENSE;231232if let Some(default_filters) = world.get_resource::<DefaultQueryFilters>() {233default_filters.modify_access(&mut component_access);234is_dense &= default_filters.is_dense(world.components());235}236237Self {238world_id: world.id(),239archetype_generation: ArchetypeGeneration::initial(),240matched_storage_ids: Vec::new(),241is_dense,242fetch_state,243filter_state,244component_access,245matched_tables: Default::default(),246matched_archetypes: Default::default(),247#[cfg(feature = "trace")]248par_iter_span: tracing::info_span!(249"par_for_each",250query = core::any::type_name::<D>(),251filter = core::any::type_name::<F>(),252),253}254}255256/// Creates a new [`QueryState`] from a given [`QueryBuilder`] and inherits its [`FilteredAccess`].257pub fn from_builder(builder: &mut QueryBuilder<D, F>) -> Self {258let mut fetch_state = D::init_state(builder.world_mut());259let filter_state = F::init_state(builder.world_mut());260261let mut component_access = FilteredAccess::default();262D::update_component_access(&fetch_state, &mut component_access);263D::provide_extra_access(264&mut fetch_state,265component_access.access_mut(),266builder.access().access(),267);268269let mut component_access = builder.access().clone();270271// For dynamic queries the dense-ness is given by the query builder.272let mut is_dense = builder.is_dense();273274if let Some(default_filters) = builder.world().get_resource::<DefaultQueryFilters>() {275default_filters.modify_access(&mut component_access);276is_dense &= default_filters.is_dense(builder.world().components());277}278279let mut state = Self {280world_id: builder.world().id(),281archetype_generation: ArchetypeGeneration::initial(),282matched_storage_ids: Vec::new(),283is_dense,284fetch_state,285filter_state,286component_access,287matched_tables: Default::default(),288matched_archetypes: Default::default(),289#[cfg(feature = "trace")]290par_iter_span: tracing::info_span!(291"par_for_each",292data = core::any::type_name::<D>(),293filter = core::any::type_name::<F>(),294),295};296state.update_archetypes(builder.world());297state298}299300/// Creates a [`Query`] from the given [`QueryState`] and [`World`].301///302/// This will create read-only queries, see [`Self::query_mut`] for mutable queries.303pub fn query<'w, 's>(&'s mut self, world: &'w World) -> Query<'w, 's, D::ReadOnly, F> {304self.update_archetypes(world);305self.query_manual(world)306}307308/// Creates a [`Query`] from the given [`QueryState`] and [`World`].309///310/// This method is slightly more efficient than [`QueryState::query`] in some situations, since311/// it does not update this instance's internal cache. The resulting query may skip an entity that312/// belongs to an archetype that has not been cached.313///314/// To ensure that the cache is up to date, call [`QueryState::update_archetypes`] before this method.315/// The cache is also updated in [`QueryState::new`], [`QueryState::get`], or any method with mutable316/// access to `self`.317///318/// This will create read-only queries, see [`Self::query_mut`] for mutable queries.319pub fn query_manual<'w, 's>(&'s self, world: &'w World) -> Query<'w, 's, D::ReadOnly, F> {320self.validate_world(world.id());321// SAFETY:322// - We have read access to the entire world, and we call `as_readonly()` so the query only performs read access.323// - We called `validate_world`.324unsafe {325self.as_readonly()326.query_unchecked_manual(world.as_unsafe_world_cell_readonly())327}328}329330/// Creates a [`Query`] from the given [`QueryState`] and [`World`].331pub fn query_mut<'w, 's>(&'s mut self, world: &'w mut World) -> Query<'w, 's, D, F> {332let last_run = world.last_change_tick();333let this_run = world.change_tick();334// SAFETY: We have exclusive access to the entire world.335unsafe { self.query_unchecked_with_ticks(world.as_unsafe_world_cell(), last_run, this_run) }336}337338/// Creates a [`Query`] from the given [`QueryState`] and [`World`].339///340/// # Safety341///342/// This does not check for mutable query correctness. To be safe, make sure mutable queries343/// have unique access to the components they query.344pub unsafe fn query_unchecked<'w, 's>(345&'s mut self,346world: UnsafeWorldCell<'w>,347) -> Query<'w, 's, D, F> {348self.update_archetypes_unsafe_world_cell(world);349// SAFETY: Caller ensures we have the required access350unsafe { self.query_unchecked_manual(world) }351}352353/// Creates a [`Query`] from the given [`QueryState`] and [`World`].354///355/// This method is slightly more efficient than [`QueryState::query_unchecked`] in some situations, since356/// it does not update this instance's internal cache. The resulting query may skip an entity that357/// belongs to an archetype that has not been cached.358///359/// To ensure that the cache is up to date, call [`QueryState::update_archetypes`] before this method.360/// The cache is also updated in [`QueryState::new`], [`QueryState::get`], or any method with mutable361/// access to `self`.362///363/// # Safety364///365/// This does not check for mutable query correctness. To be safe, make sure mutable queries366/// have unique access to the components they query.367/// This does not validate that `world.id()` matches `self.world_id`. Calling this on a `world`368/// with a mismatched [`WorldId`] is unsound.369pub unsafe fn query_unchecked_manual<'w, 's>(370&'s self,371world: UnsafeWorldCell<'w>,372) -> Query<'w, 's, D, F> {373let last_run = world.last_change_tick();374let this_run = world.change_tick();375// SAFETY:376// - The caller ensured we have the correct access to the world.377// - The caller ensured that the world matches.378unsafe { self.query_unchecked_manual_with_ticks(world, last_run, this_run) }379}380381/// Creates a [`Query`] from the given [`QueryState`] and [`World`].382///383/// # Safety384///385/// This does not check for mutable query correctness. To be safe, make sure mutable queries386/// have unique access to the components they query.387pub unsafe fn query_unchecked_with_ticks<'w, 's>(388&'s mut self,389world: UnsafeWorldCell<'w>,390last_run: Tick,391this_run: Tick,392) -> Query<'w, 's, D, F> {393self.update_archetypes_unsafe_world_cell(world);394// SAFETY:395// - The caller ensured we have the correct access to the world.396// - We called `update_archetypes_unsafe_world_cell`, which calls `validate_world`.397unsafe { self.query_unchecked_manual_with_ticks(world, last_run, this_run) }398}399400/// Creates a [`Query`] from the given [`QueryState`] and [`World`].401///402/// This method is slightly more efficient than [`QueryState::query_unchecked_with_ticks`] in some situations, since403/// it does not update this instance's internal cache. The resulting query may skip an entity that404/// belongs to an archetype that has not been cached.405///406/// To ensure that the cache is up to date, call [`QueryState::update_archetypes`] before this method.407/// The cache is also updated in [`QueryState::new`], [`QueryState::get`], or any method with mutable408/// access to `self`.409///410/// # Safety411///412/// This does not check for mutable query correctness. To be safe, make sure mutable queries413/// have unique access to the components they query.414/// This does not validate that `world.id()` matches `self.world_id`. Calling this on a `world`415/// with a mismatched [`WorldId`] is unsound.416pub unsafe fn query_unchecked_manual_with_ticks<'w, 's>(417&'s self,418world: UnsafeWorldCell<'w>,419last_run: Tick,420this_run: Tick,421) -> Query<'w, 's, D, F> {422// SAFETY:423// - The caller ensured we have the correct access to the world.424// - The caller ensured that the world matches.425unsafe { Query::new(world, self, last_run, this_run) }426}427428/// Checks if the query is empty for the given [`World`], where the last change and current tick are given.429///430/// This is equivalent to `self.iter().next().is_none()`, and thus the worst case runtime will be `O(n)`431/// where `n` is the number of *potential* matches. This can be notably expensive for queries that rely432/// on non-archetypal filters such as [`Added`], [`Changed`] or [`Spawned`] which must individually check433/// each query result for a match.434///435/// # Panics436///437/// If `world` does not match the one used to call `QueryState::new` for this instance.438///439/// [`Added`]: crate::query::Added440/// [`Changed`]: crate::query::Changed441/// [`Spawned`]: crate::query::Spawned442#[inline]443pub fn is_empty(&self, world: &World, last_run: Tick, this_run: Tick) -> bool {444self.validate_world(world.id());445// SAFETY:446// - We have read access to the entire world, and `is_empty()` only performs read access.447// - We called `validate_world`.448unsafe {449self.query_unchecked_manual_with_ticks(450world.as_unsafe_world_cell_readonly(),451last_run,452this_run,453)454}455.is_empty()456}457458/// Returns `true` if the given [`Entity`] matches the query.459///460/// This is always guaranteed to run in `O(1)` time.461#[inline]462pub fn contains(&self, entity: Entity, world: &World, last_run: Tick, this_run: Tick) -> bool {463self.validate_world(world.id());464// SAFETY:465// - We have read access to the entire world, and `is_empty()` only performs read access.466// - We called `validate_world`.467unsafe {468self.query_unchecked_manual_with_ticks(469world.as_unsafe_world_cell_readonly(),470last_run,471this_run,472)473}474.contains(entity)475}476477/// Updates the state's internal view of the [`World`]'s archetypes. If this is not called before querying data,478/// the results may not accurately reflect what is in the `world`.479///480/// This is only required if a `manual` method (such as [`Self::get_manual`]) is being called, and it only needs to481/// be called if the `world` has been structurally mutated (i.e. added/removed a component or resource). Users using482/// non-`manual` methods such as [`QueryState::get`] do not need to call this as it will be automatically called for them.483///484/// If you have an [`UnsafeWorldCell`] instead of `&World`, consider using [`QueryState::update_archetypes_unsafe_world_cell`].485///486/// # Panics487///488/// If `world` does not match the one used to call `QueryState::new` for this instance.489#[inline]490pub fn update_archetypes(&mut self, world: &World) {491self.update_archetypes_unsafe_world_cell(world.as_unsafe_world_cell_readonly());492}493494/// Updates the state's internal view of the `world`'s archetypes. If this is not called before querying data,495/// the results may not accurately reflect what is in the `world`.496///497/// This is only required if a `manual` method (such as [`Self::get_manual`]) is being called, and it only needs to498/// be called if the `world` has been structurally mutated (i.e. added/removed a component or resource). Users using499/// non-`manual` methods such as [`QueryState::get`] do not need to call this as it will be automatically called for them.500///501/// # Note502///503/// This method only accesses world metadata.504///505/// # Panics506///507/// If `world` does not match the one used to call `QueryState::new` for this instance.508pub fn update_archetypes_unsafe_world_cell(&mut self, world: UnsafeWorldCell) {509self.validate_world(world.id());510if self.component_access.required.is_empty() {511let archetypes = world.archetypes();512let old_generation =513core::mem::replace(&mut self.archetype_generation, archetypes.generation());514515for archetype in &archetypes[old_generation..] {516// SAFETY: The validate_world call ensures that the world is the same the QueryState517// was initialized from.518unsafe {519self.new_archetype(archetype);520}521}522} else {523// skip if we are already up to date524if self.archetype_generation == world.archetypes().generation() {525return;526}527// if there are required components, we can optimize by only iterating through archetypes528// that contain at least one of the required components529let potential_archetypes = self530.component_access531.required532.ones()533.filter_map(|idx| {534let component_id = ComponentId::get_sparse_set_index(idx);535world536.archetypes()537.component_index()538.get(&component_id)539.map(|index| index.keys())540})541// select the component with the fewest archetypes542.min_by_key(ExactSizeIterator::len);543if let Some(archetypes) = potential_archetypes {544for archetype_id in archetypes {545// exclude archetypes that have already been processed546if archetype_id < &self.archetype_generation.0 {547continue;548}549// SAFETY: get_potential_archetypes only returns archetype ids that are valid for the world550let archetype = &world.archetypes()[*archetype_id];551// SAFETY: The validate_world call ensures that the world is the same the QueryState552// was initialized from.553unsafe {554self.new_archetype(archetype);555}556}557}558self.archetype_generation = world.archetypes().generation();559}560}561562/// # Panics563///564/// If `world_id` does not match the [`World`] used to call `QueryState::new` for this instance.565///566/// Many unsafe query methods require the world to match for soundness. This function is the easiest567/// way of ensuring that it matches.568#[inline]569#[track_caller]570pub fn validate_world(&self, world_id: WorldId) {571#[inline(never)]572#[track_caller]573#[cold]574fn panic_mismatched(this: WorldId, other: WorldId) -> ! {575panic!("Encountered a mismatched World. This QueryState was created from {this:?}, but a method was called using {other:?}.");576}577578if self.world_id != world_id {579panic_mismatched(self.world_id, world_id);580}581}582583/// Update the current [`QueryState`] with information from the provided [`Archetype`]584/// (if applicable, i.e. if the archetype has any intersecting [`ComponentId`] with the current [`QueryState`]).585///586/// # Safety587/// `archetype` must be from the `World` this state was initialized from.588pub unsafe fn new_archetype(&mut self, archetype: &Archetype) {589if D::matches_component_set(&self.fetch_state, &|id| archetype.contains(id))590&& F::matches_component_set(&self.filter_state, &|id| archetype.contains(id))591&& self.matches_component_set(&|id| archetype.contains(id))592{593let archetype_index = archetype.id().index();594if !self.matched_archetypes.contains(archetype_index) {595self.matched_archetypes.grow_and_insert(archetype_index);596if !self.is_dense {597self.matched_storage_ids.push(StorageId {598archetype_id: archetype.id(),599});600}601}602let table_index = archetype.table_id().as_usize();603if !self.matched_tables.contains(table_index) {604self.matched_tables.grow_and_insert(table_index);605if self.is_dense {606self.matched_storage_ids.push(StorageId {607table_id: archetype.table_id(),608});609}610}611}612}613614/// Returns `true` if this query matches a set of components. Otherwise, returns `false`.615pub fn matches_component_set(&self, set_contains_id: &impl Fn(ComponentId) -> bool) -> bool {616self.component_access.filter_sets.iter().any(|set| {617set.with618.ones()619.all(|index| set_contains_id(ComponentId::get_sparse_set_index(index)))620&& set621.without622.ones()623.all(|index| !set_contains_id(ComponentId::get_sparse_set_index(index)))624})625}626627/// Use this to transform a [`QueryState`] into a more generic [`QueryState`].628/// This can be useful for passing to another function that might take the more general form.629/// See [`Query::transmute_lens`](crate::system::Query::transmute_lens) for more details.630///631/// You should not call [`update_archetypes`](Self::update_archetypes) on the returned [`QueryState`] as the result will be unpredictable.632/// You might end up with a mix of archetypes that only matched the original query + archetypes that only match633/// the new [`QueryState`]. Most of the safe methods on [`QueryState`] call [`QueryState::update_archetypes`] internally, so this634/// best used through a [`Query`]635pub fn transmute<'a, NewD: QueryData>(636&self,637world: impl Into<UnsafeWorldCell<'a>>,638) -> QueryState<NewD> {639self.transmute_filtered::<NewD, ()>(world.into())640}641642/// Creates a new [`QueryState`] with the same underlying [`FilteredAccess`], matched tables and archetypes643/// as self but with a new type signature.644///645/// Panics if `NewD` or `NewF` require accesses that this query does not have.646pub fn transmute_filtered<'a, NewD: QueryData, NewF: QueryFilter>(647&self,648world: impl Into<UnsafeWorldCell<'a>>,649) -> QueryState<NewD, NewF> {650let world = world.into();651self.validate_world(world.id());652653let mut component_access = FilteredAccess::default();654let mut fetch_state = NewD::get_state(world.components()).expect("Could not create fetch_state, Please initialize all referenced components before transmuting.");655let filter_state = NewF::get_state(world.components()).expect("Could not create filter_state, Please initialize all referenced components before transmuting.");656657let mut self_access = self.component_access.clone();658if D::IS_READ_ONLY {659// The current state was transmuted from a mutable660// `QueryData` to a read-only one.661// Ignore any write access in the current state.662self_access.access_mut().clear_writes();663}664665NewD::update_component_access(&fetch_state, &mut component_access);666NewD::provide_extra_access(667&mut fetch_state,668component_access.access_mut(),669self_access.access(),670);671672let mut filter_component_access = FilteredAccess::default();673NewF::update_component_access(&filter_state, &mut filter_component_access);674675component_access.extend(&filter_component_access);676assert!(677component_access.is_subset(&self_access),678"Transmuted state for {} attempts to access terms that are not allowed by original state {}.",679DebugName::type_name::<(NewD, NewF)>(), DebugName::type_name::<(D, F)>()680);681682// For transmuted queries, the dense-ness of the query is equal to the dense-ness of the original query.683//684// We ensure soundness using `FilteredAccess::required`.685//686// Any `WorldQuery` implementations that rely on a query being sparse for soundness,687// including `&`, `&mut`, `Ref`, and `Mut`, will add a sparse set component to the `required` set.688// (`Option<&Sparse>` and `Has<Sparse>` will incorrectly report a component as never being present689// when doing dense iteration, but are not unsound. See https://github.com/bevyengine/bevy/issues/16397)690//691// And any query with a sparse set component in the `required` set must have `is_dense = false`.692// For static queries, the `WorldQuery` implementations ensure this.693// For dynamic queries, anything that adds a `required` component also adds a `with` filter.694//695// The `component_access.is_subset()` check ensures that if the new query has a sparse set component in the `required` set,696// then the original query must also have had that component in the `required` set.697// Therefore, if the `WorldQuery` implementations rely on a query being sparse for soundness,698// then there was a sparse set component in the `required` set, and the query has `is_dense = false`.699let is_dense = self.is_dense;700701QueryState {702world_id: self.world_id,703archetype_generation: self.archetype_generation,704matched_storage_ids: self.matched_storage_ids.clone(),705is_dense,706fetch_state,707filter_state,708component_access: self_access,709matched_tables: self.matched_tables.clone(),710matched_archetypes: self.matched_archetypes.clone(),711#[cfg(feature = "trace")]712par_iter_span: tracing::info_span!(713"par_for_each",714query = core::any::type_name::<NewD>(),715filter = core::any::type_name::<NewF>(),716),717}718}719720/// Use this to combine two queries. The data accessed will be the intersection721/// of archetypes included in both queries. This can be useful for accessing a722/// subset of the entities between two queries.723///724/// You should not call `update_archetypes` on the returned `QueryState` as the result725/// could be unpredictable. You might end up with a mix of archetypes that only matched726/// the original query + archetypes that only match the new `QueryState`. Most of the727/// safe methods on `QueryState` call [`QueryState::update_archetypes`] internally, so728/// this is best used through a `Query`.729///730/// ## Performance731///732/// This will have similar performance as constructing a new `QueryState` since much of internal state733/// needs to be reconstructed. But it will be a little faster as it only needs to compare the intersection734/// of matching archetypes rather than iterating over all archetypes.735///736/// ## Panics737///738/// Will panic if `NewD` contains accesses not in `Q` or `OtherQ`.739pub fn join<'a, OtherD: QueryData, NewD: QueryData>(740&self,741world: impl Into<UnsafeWorldCell<'a>>,742other: &QueryState<OtherD>,743) -> QueryState<NewD, ()> {744self.join_filtered::<_, (), NewD, ()>(world, other)745}746747/// Use this to combine two queries. The data accessed will be the intersection748/// of archetypes included in both queries.749///750/// ## Panics751///752/// Will panic if `NewD` or `NewF` requires accesses not in `Q` or `OtherQ`.753pub fn join_filtered<754'a,755OtherD: QueryData,756OtherF: QueryFilter,757NewD: QueryData,758NewF: QueryFilter,759>(760&self,761world: impl Into<UnsafeWorldCell<'a>>,762other: &QueryState<OtherD, OtherF>,763) -> QueryState<NewD, NewF> {764if self.world_id != other.world_id {765panic!("Joining queries initialized on different worlds is not allowed.");766}767768let world = world.into();769770self.validate_world(world.id());771772let mut component_access = FilteredAccess::default();773let mut new_fetch_state = NewD::get_state(world.components())774.expect("Could not create fetch_state, Please initialize all referenced components before transmuting.");775let new_filter_state = NewF::get_state(world.components())776.expect("Could not create filter_state, Please initialize all referenced components before transmuting.");777778let mut joined_component_access = self.component_access.clone();779joined_component_access.extend(&other.component_access);780781if D::IS_READ_ONLY && self.component_access.access().has_any_write()782|| OtherD::IS_READ_ONLY && other.component_access.access().has_any_write()783{784// One of the input states was transmuted from a mutable785// `QueryData` to a read-only one.786// Ignore any write access in that current state.787// The simplest way to do this is to clear *all* writes788// and then add back in any writes that are valid789joined_component_access.access_mut().clear_writes();790if !D::IS_READ_ONLY {791joined_component_access792.access_mut()793.extend(self.component_access.access());794}795if !OtherD::IS_READ_ONLY {796joined_component_access797.access_mut()798.extend(other.component_access.access());799}800}801802NewD::update_component_access(&new_fetch_state, &mut component_access);803NewD::provide_extra_access(804&mut new_fetch_state,805component_access.access_mut(),806joined_component_access.access(),807);808809let mut new_filter_component_access = FilteredAccess::default();810NewF::update_component_access(&new_filter_state, &mut new_filter_component_access);811812component_access.extend(&new_filter_component_access);813814assert!(815component_access.is_subset(&joined_component_access),816"Joined state for {} attempts to access terms that are not allowed by state {} joined with {}.",817DebugName::type_name::<(NewD, NewF)>(), DebugName::type_name::<(D, F)>(), DebugName::type_name::<(OtherD, OtherF)>()818);819820if self.archetype_generation != other.archetype_generation {821warn!("You have tried to join queries with different archetype_generations. This could lead to unpredictable results.");822}823824// the join is dense of both the queries were dense.825let is_dense = self.is_dense && other.is_dense;826827// take the intersection of the matched ids828let mut matched_tables = self.matched_tables.clone();829let mut matched_archetypes = self.matched_archetypes.clone();830matched_tables.intersect_with(&other.matched_tables);831matched_archetypes.intersect_with(&other.matched_archetypes);832let matched_storage_ids = if is_dense {833matched_tables834.ones()835.map(|id| StorageId {836table_id: TableId::from_usize(id),837})838.collect()839} else {840matched_archetypes841.ones()842.map(|id| StorageId {843archetype_id: ArchetypeId::new(id),844})845.collect()846};847848QueryState {849world_id: self.world_id,850archetype_generation: self.archetype_generation,851matched_storage_ids,852is_dense,853fetch_state: new_fetch_state,854filter_state: new_filter_state,855component_access: joined_component_access,856matched_tables,857matched_archetypes,858#[cfg(feature = "trace")]859par_iter_span: tracing::info_span!(860"par_for_each",861query = core::any::type_name::<NewD>(),862filter = core::any::type_name::<NewF>(),863),864}865}866867/// Gets the query result for the given [`World`] and [`Entity`].868///869/// This can only be called for read-only queries, see [`Self::get_mut`] for write-queries.870///871/// If you need to get multiple items at once but get borrowing errors,872/// consider using [`Self::update_archetypes`] followed by multiple [`Self::get_manual`] calls,873/// or making a single call with [`Self::get_many`] or [`Self::iter_many`].874///875/// This is always guaranteed to run in `O(1)` time.876#[inline]877pub fn get<'w>(878&mut self,879world: &'w World,880entity: Entity,881) -> Result<ROQueryItem<'w, '_, D>, QueryEntityError> {882self.query(world).get_inner(entity)883}884885/// Returns the read-only query results for the given array of [`Entity`].886///887/// In case of a nonexisting entity or mismatched component, a [`QueryEntityError`] is888/// returned instead.889///890/// Note that the unlike [`QueryState::get_many_mut`], the entities passed in do not need to be unique.891///892/// # Examples893///894/// ```895/// use bevy_ecs::prelude::*;896/// use bevy_ecs::query::QueryEntityError;897///898/// #[derive(Component, PartialEq, Debug)]899/// struct A(usize);900///901/// let mut world = World::new();902/// let entity_vec: Vec<Entity> = (0..3).map(|i|world.spawn(A(i)).id()).collect();903/// let entities: [Entity; 3] = entity_vec.try_into().unwrap();904///905/// world.spawn(A(73));906///907/// let mut query_state = world.query::<&A>();908///909/// let component_values = query_state.get_many(&world, entities).unwrap();910///911/// assert_eq!(component_values, [&A(0), &A(1), &A(2)]);912///913/// let wrong_entity = Entity::from_raw_u32(365).unwrap();914///915/// assert_eq!(match query_state.get_many(&mut world, [wrong_entity]).unwrap_err() {QueryEntityError::NotSpawned(error) => error.entity(), _ => panic!()}, wrong_entity);916/// ```917#[inline]918pub fn get_many<'w, const N: usize>(919&mut self,920world: &'w World,921entities: [Entity; N],922) -> Result<[ROQueryItem<'w, '_, D>; N], QueryEntityError> {923self.query(world).get_many_inner(entities)924}925926/// Returns the read-only query results for the given [`UniqueEntityArray`].927///928/// In case of a nonexisting entity or mismatched component, a [`QueryEntityError`] is929/// returned instead.930///931/// # Examples932///933/// ```934/// use bevy_ecs::{prelude::*, query::QueryEntityError, entity::{EntitySetIterator, UniqueEntityArray, UniqueEntityVec}};935///936/// #[derive(Component, PartialEq, Debug)]937/// struct A(usize);938///939/// let mut world = World::new();940/// let entity_set: UniqueEntityVec = world.spawn_batch((0..3).map(A)).collect_set();941/// let entity_set: UniqueEntityArray<3> = entity_set.try_into().unwrap();942///943/// world.spawn(A(73));944///945/// let mut query_state = world.query::<&A>();946///947/// let component_values = query_state.get_many_unique(&world, entity_set).unwrap();948///949/// assert_eq!(component_values, [&A(0), &A(1), &A(2)]);950///951/// let wrong_entity = Entity::from_raw_u32(365).unwrap();952///953/// assert_eq!(match query_state.get_many_unique(&mut world, UniqueEntityArray::from([wrong_entity])).unwrap_err() {QueryEntityError::NotSpawned(error) => error.entity(), _ => panic!()}, wrong_entity);954/// ```955#[inline]956pub fn get_many_unique<'w, const N: usize>(957&mut self,958world: &'w World,959entities: UniqueEntityArray<N>,960) -> Result<[ROQueryItem<'w, '_, D>; N], QueryEntityError> {961self.query(world).get_many_unique_inner(entities)962}963964/// Gets the query result for the given [`World`] and [`Entity`].965///966/// This is always guaranteed to run in `O(1)` time.967#[inline]968pub fn get_mut<'w>(969&mut self,970world: &'w mut World,971entity: Entity,972) -> Result<D::Item<'w, '_>, QueryEntityError> {973self.query_mut(world).get_inner(entity)974}975976/// Returns the query results for the given array of [`Entity`].977///978/// In case of a nonexisting entity or mismatched component, a [`QueryEntityError`] is979/// returned instead.980///981/// ```982/// use bevy_ecs::prelude::*;983/// use bevy_ecs::query::QueryEntityError;984///985/// #[derive(Component, PartialEq, Debug)]986/// struct A(usize);987///988/// let mut world = World::new();989///990/// let entities: Vec<Entity> = (0..3).map(|i|world.spawn(A(i)).id()).collect();991/// let entities: [Entity; 3] = entities.try_into().unwrap();992///993/// world.spawn(A(73));994///995/// let mut query_state = world.query::<&mut A>();996///997/// let mut mutable_component_values = query_state.get_many_mut(&mut world, entities).unwrap();998///999/// for mut a in &mut mutable_component_values {1000/// a.0 += 5;1001/// }1002///1003/// let component_values = query_state.get_many(&world, entities).unwrap();1004///1005/// assert_eq!(component_values, [&A(5), &A(6), &A(7)]);1006///1007/// let wrong_entity = Entity::from_raw_u32(57).unwrap();1008/// let invalid_entity = world.spawn_empty().id();1009///1010/// assert_eq!(match query_state.get_many(&mut world, [wrong_entity]).unwrap_err() {QueryEntityError::NotSpawned(error) => error.entity(), _ => panic!()}, wrong_entity);1011/// assert_eq!(match query_state.get_many_mut(&mut world, [invalid_entity]).unwrap_err() {QueryEntityError::QueryDoesNotMatch(entity, _) => entity, _ => panic!()}, invalid_entity);1012/// assert_eq!(query_state.get_many_mut(&mut world, [entities[0], entities[0]]).unwrap_err(), QueryEntityError::AliasedMutability(entities[0]));1013/// ```1014#[inline]1015pub fn get_many_mut<'w, const N: usize>(1016&mut self,1017world: &'w mut World,1018entities: [Entity; N],1019) -> Result<[D::Item<'w, '_>; N], QueryEntityError> {1020self.query_mut(world).get_many_mut_inner(entities)1021}10221023/// Returns the query results for the given [`UniqueEntityArray`].1024///1025/// In case of a nonexisting entity or mismatched component, a [`QueryEntityError`] is1026/// returned instead.1027///1028/// ```1029/// use bevy_ecs::{prelude::*, query::QueryEntityError, entity::{EntitySetIterator, UniqueEntityArray, UniqueEntityVec}};1030///1031/// #[derive(Component, PartialEq, Debug)]1032/// struct A(usize);1033///1034/// let mut world = World::new();1035///1036/// let entity_set: UniqueEntityVec = world.spawn_batch((0..3).map(A)).collect_set();1037/// let entity_set: UniqueEntityArray<3> = entity_set.try_into().unwrap();1038///1039/// world.spawn(A(73));1040///1041/// let mut query_state = world.query::<&mut A>();1042///1043/// let mut mutable_component_values = query_state.get_many_unique_mut(&mut world, entity_set).unwrap();1044///1045/// for mut a in &mut mutable_component_values {1046/// a.0 += 5;1047/// }1048///1049/// let component_values = query_state.get_many_unique(&world, entity_set).unwrap();1050///1051/// assert_eq!(component_values, [&A(5), &A(6), &A(7)]);1052///1053/// let wrong_entity = Entity::from_raw_u32(57).unwrap();1054/// let invalid_entity = world.spawn_empty().id();1055///1056/// assert_eq!(match query_state.get_many_unique(&mut world, UniqueEntityArray::from([wrong_entity])).unwrap_err() {QueryEntityError::NotSpawned(error) => error.entity(), _ => panic!()}, wrong_entity);1057/// assert_eq!(match query_state.get_many_unique_mut(&mut world, UniqueEntityArray::from([invalid_entity])).unwrap_err() {QueryEntityError::QueryDoesNotMatch(entity, _) => entity, _ => panic!()}, invalid_entity);1058/// ```1059#[inline]1060pub fn get_many_unique_mut<'w, const N: usize>(1061&mut self,1062world: &'w mut World,1063entities: UniqueEntityArray<N>,1064) -> Result<[D::Item<'w, '_>; N], QueryEntityError> {1065self.query_mut(world).get_many_unique_inner(entities)1066}10671068/// Gets the query result for the given [`World`] and [`Entity`].1069///1070/// This method is slightly more efficient than [`QueryState::get`] in some situations, since1071/// it does not update this instance's internal cache. This method will return an error if `entity`1072/// belongs to an archetype that has not been cached.1073///1074/// To ensure that the cache is up to date, call [`QueryState::update_archetypes`] before this method.1075/// The cache is also updated in [`QueryState::new`], `QueryState::get`, or any method with mutable1076/// access to `self`.1077///1078/// This can only be called for read-only queries, see [`Self::get_mut`] for mutable queries.1079///1080/// This is always guaranteed to run in `O(1)` time.1081#[inline]1082pub fn get_manual<'w>(1083&self,1084world: &'w World,1085entity: Entity,1086) -> Result<ROQueryItem<'w, '_, D>, QueryEntityError> {1087self.query_manual(world).get_inner(entity)1088}10891090/// Gets the query result for the given [`World`] and [`Entity`].1091///1092/// This is always guaranteed to run in `O(1)` time.1093///1094/// # Safety1095///1096/// This does not check for mutable query correctness. To be safe, make sure mutable queries1097/// have unique access to the components they query.1098#[inline]1099pub unsafe fn get_unchecked<'w>(1100&mut self,1101world: UnsafeWorldCell<'w>,1102entity: Entity,1103) -> Result<D::Item<'w, '_>, QueryEntityError> {1104// SAFETY: Upheld by caller1105unsafe { self.query_unchecked(world) }.get_inner(entity)1106}11071108/// Returns an [`Iterator`] over the query results for the given [`World`].1109///1110/// This can only be called for read-only queries, see [`Self::iter_mut`] for write-queries.1111///1112/// If you need to iterate multiple times at once but get borrowing errors,1113/// consider using [`Self::update_archetypes`] followed by multiple [`Self::iter_manual`] calls.1114#[inline]1115pub fn iter<'w, 's>(&'s mut self, world: &'w World) -> QueryIter<'w, 's, D::ReadOnly, F> {1116self.query(world).into_iter()1117}11181119/// Returns an [`Iterator`] over the query results for the given [`World`].1120///1121/// This iterator is always guaranteed to return results from each matching entity once and only once.1122/// Iteration order is not guaranteed.1123#[inline]1124pub fn iter_mut<'w, 's>(&'s mut self, world: &'w mut World) -> QueryIter<'w, 's, D, F> {1125self.query_mut(world).into_iter()1126}11271128/// Returns an [`Iterator`] over the query results for the given [`World`] without updating the query's archetypes.1129/// Archetypes must be manually updated before by using [`Self::update_archetypes`].1130///1131/// This iterator is always guaranteed to return results from each matching entity once and only once.1132/// Iteration order is not guaranteed.1133///1134/// This can only be called for read-only queries.1135#[inline]1136pub fn iter_manual<'w, 's>(&'s self, world: &'w World) -> QueryIter<'w, 's, D::ReadOnly, F> {1137self.query_manual(world).into_iter()1138}11391140/// Returns an [`Iterator`] over all possible combinations of `K` query results without repetition.1141/// This can only be called for read-only queries.1142///1143/// A combination is an arrangement of a collection of items where order does not matter.1144///1145/// `K` is the number of items that make up each subset, and the number of items returned by the iterator.1146/// `N` is the number of total entities output by query.1147///1148/// For example, given the list [1, 2, 3, 4], where `K` is 2, the combinations without repeats are1149/// [1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4].1150/// And in this case, `N` would be defined as 4 since the size of the input list is 4.1151///1152/// For combinations of size `K` of query taking `N` inputs, you will get:1153/// - if `K == N`: one combination of all query results1154/// - if `K < N`: all possible `K`-sized combinations of query results, without repetition1155/// - if `K > N`: empty set (no `K`-sized combinations exist)1156///1157/// The `iter_combinations` method does not guarantee order of iteration.1158///1159/// This iterator is always guaranteed to return results from each unique pair of matching entities.1160/// Iteration order is not guaranteed.1161///1162/// This can only be called for read-only queries, see [`Self::iter_combinations_mut`] for1163/// write-queries.1164#[inline]1165pub fn iter_combinations<'w, 's, const K: usize>(1166&'s mut self,1167world: &'w World,1168) -> QueryCombinationIter<'w, 's, D::ReadOnly, F, K> {1169self.query(world).iter_combinations_inner()1170}11711172/// Returns an [`Iterator`] over all possible combinations of `K` query results without repetition.1173///1174/// A combination is an arrangement of a collection of items where order does not matter.1175///1176/// `K` is the number of items that make up each subset, and the number of items returned by the iterator.1177/// `N` is the number of total entities output by query.1178///1179/// For example, given the list [1, 2, 3, 4], where `K` is 2, the combinations without repeats are1180/// [1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4].1181/// And in this case, `N` would be defined as 4 since the size of the input list is 4.1182///1183/// For combinations of size `K` of query taking `N` inputs, you will get:1184/// - if `K == N`: one combination of all query results1185/// - if `K < N`: all possible `K`-sized combinations of query results, without repetition1186/// - if `K > N`: empty set (no `K`-sized combinations exist)1187///1188/// The `iter_combinations_mut` method does not guarantee order of iteration.1189#[inline]1190pub fn iter_combinations_mut<'w, 's, const K: usize>(1191&'s mut self,1192world: &'w mut World,1193) -> QueryCombinationIter<'w, 's, D, F, K> {1194self.query_mut(world).iter_combinations_inner()1195}11961197/// Returns an [`Iterator`] over the read-only query items generated from an [`Entity`] list.1198///1199/// Items are returned in the order of the list of entities.1200/// Entities that don't match the query are skipped.1201///1202/// If you need to iterate multiple times at once but get borrowing errors,1203/// consider using [`Self::update_archetypes`] followed by multiple [`Self::iter_many_manual`] calls.1204///1205/// # See also1206///1207/// - [`iter_many_mut`](Self::iter_many_mut) to get mutable query items.1208#[inline]1209pub fn iter_many<'w, 's, EntityList: IntoIterator<Item: EntityEquivalent>>(1210&'s mut self,1211world: &'w World,1212entities: EntityList,1213) -> QueryManyIter<'w, 's, D::ReadOnly, F, EntityList::IntoIter> {1214self.query(world).iter_many_inner(entities)1215}12161217/// Returns an [`Iterator`] over the read-only query items generated from an [`Entity`] list.1218///1219/// Items are returned in the order of the list of entities.1220/// Entities that don't match the query are skipped.1221///1222/// If `world` archetypes changed since [`Self::update_archetypes`] was last called,1223/// this will skip entities contained in new archetypes.1224///1225/// This can only be called for read-only queries.1226///1227/// # See also1228///1229/// - [`iter_many`](Self::iter_many) to update archetypes.1230/// - [`iter_manual`](Self::iter_manual) to iterate over all query items.1231#[inline]1232pub fn iter_many_manual<'w, 's, EntityList: IntoIterator<Item: EntityEquivalent>>(1233&'s self,1234world: &'w World,1235entities: EntityList,1236) -> QueryManyIter<'w, 's, D::ReadOnly, F, EntityList::IntoIter> {1237self.query_manual(world).iter_many_inner(entities)1238}12391240/// Returns an iterator over the query items generated from an [`Entity`] list.1241///1242/// Items are returned in the order of the list of entities.1243/// Entities that don't match the query are skipped.1244#[inline]1245pub fn iter_many_mut<'w, 's, EntityList: IntoIterator<Item: EntityEquivalent>>(1246&'s mut self,1247world: &'w mut World,1248entities: EntityList,1249) -> QueryManyIter<'w, 's, D, F, EntityList::IntoIter> {1250self.query_mut(world).iter_many_inner(entities)1251}12521253/// Returns an [`Iterator`] over the unique read-only query items generated from an [`EntitySet`].1254///1255/// Items are returned in the order of the list of entities.1256/// Entities that don't match the query are skipped.1257///1258/// # See also1259///1260/// - [`iter_many_unique_mut`](Self::iter_many_unique_mut) to get mutable query items.1261#[inline]1262pub fn iter_many_unique<'w, 's, EntityList: EntitySet>(1263&'s mut self,1264world: &'w World,1265entities: EntityList,1266) -> QueryManyUniqueIter<'w, 's, D::ReadOnly, F, EntityList::IntoIter> {1267self.query(world).iter_many_unique_inner(entities)1268}12691270/// Returns an [`Iterator`] over the unique read-only 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///1275/// If `world` archetypes changed since [`Self::update_archetypes`] was last called,1276/// this will skip entities contained in new archetypes.1277///1278/// This can only be called for read-only queries.1279///1280/// # See also1281///1282/// - [`iter_many_unique`](Self::iter_many) to update archetypes.1283/// - [`iter_many`](Self::iter_many) to iterate over a non-unique entity list.1284/// - [`iter_manual`](Self::iter_manual) to iterate over all query items.1285#[inline]1286pub fn iter_many_unique_manual<'w, 's, EntityList: EntitySet>(1287&'s self,1288world: &'w World,1289entities: EntityList,1290) -> QueryManyUniqueIter<'w, 's, D::ReadOnly, F, EntityList::IntoIter> {1291self.query_manual(world).iter_many_unique_inner(entities)1292}12931294/// Returns an iterator over the unique query items generated from an [`EntitySet`].1295///1296/// Items are returned in the order of the list of entities.1297/// Entities that don't match the query are skipped.1298#[inline]1299pub fn iter_many_unique_mut<'w, 's, EntityList: EntitySet>(1300&'s mut self,1301world: &'w mut World,1302entities: EntityList,1303) -> QueryManyUniqueIter<'w, 's, D, F, EntityList::IntoIter> {1304self.query_mut(world).iter_many_unique_inner(entities)1305}1306/// Returns an [`Iterator`] over the query results for the given [`World`].1307///1308/// This iterator is always guaranteed to return results from each matching entity once and only once.1309/// Iteration order is not guaranteed.1310///1311/// # Safety1312///1313/// This does not check for mutable query correctness. To be safe, make sure mutable queries1314/// have unique access to the components they query.1315#[inline]1316pub unsafe fn iter_unchecked<'w, 's>(1317&'s mut self,1318world: UnsafeWorldCell<'w>,1319) -> QueryIter<'w, 's, D, F> {1320// SAFETY: Upheld by caller1321unsafe { self.query_unchecked(world) }.into_iter()1322}13231324/// Returns an [`Iterator`] over all possible combinations of `K` query results for the1325/// given [`World`] without repetition.1326/// This can only be called for read-only queries.1327///1328/// This iterator is always guaranteed to return results from each unique pair of matching entities.1329/// Iteration order is not guaranteed.1330///1331/// # Safety1332///1333/// This does not check for mutable query correctness. To be safe, make sure mutable queries1334/// have unique access to the components they query.1335#[inline]1336pub unsafe fn iter_combinations_unchecked<'w, 's, const K: usize>(1337&'s mut self,1338world: UnsafeWorldCell<'w>,1339) -> QueryCombinationIter<'w, 's, D, F, K> {1340// SAFETY: Upheld by caller1341unsafe { self.query_unchecked(world) }.iter_combinations_inner()1342}13431344/// Returns a parallel iterator over the query results for the given [`World`].1345///1346/// This can only be called for read-only queries, see [`par_iter_mut`] for write-queries.1347///1348/// Note that you must use the `for_each` method to iterate over the1349/// results, see [`par_iter_mut`] for an example.1350///1351/// [`par_iter_mut`]: Self::par_iter_mut1352#[inline]1353pub fn par_iter<'w, 's>(1354&'s mut self,1355world: &'w World,1356) -> QueryParIter<'w, 's, D::ReadOnly, F> {1357self.query(world).par_iter_inner()1358}13591360/// Returns a parallel iterator over the query results for the given [`World`].1361///1362/// This can only be called for mutable queries, see [`par_iter`] for read-only-queries.1363///1364/// # Examples1365///1366/// ```1367/// use bevy_ecs::prelude::*;1368/// use bevy_ecs::query::QueryEntityError;1369///1370/// #[derive(Component, PartialEq, Debug)]1371/// struct A(usize);1372///1373/// # bevy_tasks::ComputeTaskPool::get_or_init(|| bevy_tasks::TaskPool::new());1374///1375/// let mut world = World::new();1376///1377/// # let entities: Vec<Entity> = (0..3).map(|i| world.spawn(A(i)).id()).collect();1378/// # let entities: [Entity; 3] = entities.try_into().unwrap();1379///1380/// let mut query_state = world.query::<&mut A>();1381///1382/// query_state.par_iter_mut(&mut world).for_each(|mut a| {1383/// a.0 += 5;1384/// });1385///1386/// # let component_values = query_state.get_many(&world, entities).unwrap();1387///1388/// # assert_eq!(component_values, [&A(5), &A(6), &A(7)]);1389///1390/// # let wrong_entity = Entity::from_raw_u32(57).unwrap();1391/// # let invalid_entity = world.spawn_empty().id();1392///1393/// # assert_eq!(match query_state.get_many(&mut world, [wrong_entity]).unwrap_err() {QueryEntityError::NotSpawned(error) => error.entity(), _ => panic!()}, wrong_entity);1394/// assert_eq!(match query_state.get_many_mut(&mut world, [invalid_entity]).unwrap_err() {QueryEntityError::QueryDoesNotMatch(entity, _) => entity, _ => panic!()}, invalid_entity);1395/// # assert_eq!(query_state.get_many_mut(&mut world, [entities[0], entities[0]]).unwrap_err(), QueryEntityError::AliasedMutability(entities[0]));1396/// ```1397///1398/// # Panics1399/// The [`ComputeTaskPool`] is not initialized. If using this from a query that is being1400/// initialized and run from the ECS scheduler, this should never panic.1401///1402/// [`par_iter`]: Self::par_iter1403/// [`ComputeTaskPool`]: bevy_tasks::ComputeTaskPool1404#[inline]1405pub fn par_iter_mut<'w, 's>(&'s mut self, world: &'w mut World) -> QueryParIter<'w, 's, D, F> {1406self.query_mut(world).par_iter_inner()1407}14081409/// Returns a contiguous iterator over the query results for the given [`World`] or [`None`] if1410/// the query is not dense hence not contiguously iterable.1411#[inline]1412pub fn contiguous_iter<'w, 's>(1413&'s mut self,1414world: &'w World,1415) -> Option<QueryContiguousIter<'w, 's, D::ReadOnly, F>>1416where1417D::ReadOnly: ContiguousQueryData,1418F: ArchetypeFilter,1419{1420self.query(world).contiguous_iter_inner().ok()1421}14221423/// Returns a contiguous iterator over the query results for the given [`World`] or [`None`] if1424/// the query is not dense hence not contiguously iterable.1425///1426/// This can only be called for mutable queries, see [`Self::contiguous_iter`] for read-only-queries.1427#[inline]1428pub fn contiguous_iter_mut<'w, 's>(1429&'s mut self,1430world: &'w mut World,1431) -> Option<QueryContiguousIter<'w, 's, D, F>>1432where1433D: ContiguousQueryData,1434F: ArchetypeFilter,1435{1436self.query_mut(world).contiguous_iter_inner().ok()1437}14381439/// Runs `func` on each query result in parallel for the given [`World`], where the last change and1440/// the current change tick are given. This is faster than the equivalent1441/// `iter()` method, but cannot be chained like a normal [`Iterator`].1442///1443/// # Panics1444/// The [`ComputeTaskPool`] is not initialized. If using this from a query that is being1445/// initialized and run from the ECS scheduler, this should never panic.1446///1447/// # Safety1448///1449/// This does not check for mutable query correctness. To be safe, make sure mutable queries1450/// have unique access to the components they query.1451/// This does not validate that `world.id()` matches `self.world_id`. Calling this on a `world`1452/// with a mismatched [`WorldId`] is unsound.1453///1454/// [`ComputeTaskPool`]: bevy_tasks::ComputeTaskPool1455#[cfg(all(not(target_arch = "wasm32"), feature = "multi_threaded"))]1456pub(crate) unsafe fn par_fold_init_unchecked_manual<'w, 's, T, FN, INIT>(1457&'s self,1458init_accum: INIT,1459world: UnsafeWorldCell<'w>,1460batch_size: u32,1461func: FN,1462last_run: Tick,1463this_run: Tick,1464) where1465FN: Fn(T, D::Item<'w, 's>) -> T + Send + Sync + Clone,1466INIT: Fn() -> T + Sync + Send + Clone,1467{1468// NOTE: If you are changing query iteration code, remember to update the following places, where relevant:1469// QueryIter, QueryIterationCursor, QueryManyIter, QueryCombinationIter,QueryState::par_fold_init_unchecked_manual,1470// QueryState::par_many_fold_init_unchecked_manual, QueryState::par_many_unique_fold_init_unchecked_manual, QueryContiguousIter::next1471use arrayvec::ArrayVec;14721473bevy_tasks::ComputeTaskPool::get().scope(|scope| {1474// SAFETY: We only access table data that has been registered in `self.component_access`.1475let tables = unsafe { &world.storages().tables };1476let archetypes = world.archetypes();1477let mut batch_queue = ArrayVec::new();1478let mut queue_entity_count = 0;14791480// submit a list of storages which smaller than batch_size as single task1481let submit_batch_queue = |queue: &mut ArrayVec<StorageId, 128>| {1482if queue.is_empty() {1483return;1484}1485let queue = core::mem::take(queue);1486let mut func = func.clone();1487let init_accum = init_accum.clone();1488scope.spawn(async move {1489#[cfg(feature = "trace")]1490let _span = self.par_iter_span.enter();1491let mut iter = self1492.query_unchecked_manual_with_ticks(world, last_run, this_run)1493.into_iter();1494let mut accum = init_accum();1495for storage_id in queue {1496accum = iter.fold_over_storage_range(accum, &mut func, storage_id, None);1497}1498});1499};15001501// submit single storage larger than batch_size1502let submit_single = |count, storage_id: StorageId| {1503for offset in (0..count).step_by(batch_size as usize) {1504let mut func = func.clone();1505let init_accum = init_accum.clone();1506let len = batch_size.min(count - offset);1507let batch = offset..offset + len;1508scope.spawn(async move {1509#[cfg(feature = "trace")]1510let _span = self.par_iter_span.enter();1511let accum = init_accum();1512self.query_unchecked_manual_with_ticks(world, last_run, this_run)1513.into_iter()1514.fold_over_storage_range(accum, &mut func, storage_id, Some(batch));1515});1516}1517};15181519let storage_entity_count = |storage_id: StorageId| -> u32 {1520if self.is_dense {1521tables[storage_id.table_id].entity_count()1522} else {1523archetypes[storage_id.archetype_id].len()1524}1525};15261527for storage_id in &self.matched_storage_ids {1528let count = storage_entity_count(*storage_id);15291530// skip empty storage1531if count == 0 {1532continue;1533}1534// immediately submit large storage1535if count >= batch_size {1536submit_single(count, *storage_id);1537continue;1538}1539// merge small storage1540batch_queue.push(*storage_id);1541queue_entity_count += count;15421543// submit batch_queue1544if queue_entity_count >= batch_size || batch_queue.is_full() {1545submit_batch_queue(&mut batch_queue);1546queue_entity_count = 0;1547}1548}1549submit_batch_queue(&mut batch_queue);1550});1551}15521553/// Runs `func` on each query result in parallel for the given [`EntitySet`],1554/// where the last change and the current change tick are given. This is faster than the1555/// equivalent `iter_many_unique()` method, but cannot be chained like a normal [`Iterator`].1556///1557/// # Panics1558/// The [`ComputeTaskPool`] is not initialized. If using this from a query that is being1559/// initialized and run from the ECS scheduler, this should never panic.1560///1561/// # Safety1562///1563/// This does not check for mutable query correctness. To be safe, make sure mutable queries1564/// have unique access to the components they query.1565/// This does not validate that `world.id()` matches `self.world_id`. Calling this on a `world`1566/// with a mismatched [`WorldId`] is unsound.1567///1568/// [`ComputeTaskPool`]: bevy_tasks::ComputeTaskPool1569#[cfg(all(not(target_arch = "wasm32"), feature = "multi_threaded"))]1570pub(crate) unsafe fn par_many_unique_fold_init_unchecked_manual<'w, 's, T, FN, INIT, E>(1571&'s self,1572init_accum: INIT,1573world: UnsafeWorldCell<'w>,1574entity_list: &UniqueEntityEquivalentSlice<E>,1575batch_size: u32,1576mut func: FN,1577last_run: Tick,1578this_run: Tick,1579) where1580FN: Fn(T, D::Item<'w, 's>) -> T + Send + Sync + Clone,1581INIT: Fn() -> T + Sync + Send + Clone,1582E: EntityEquivalent + Sync,1583{1584// NOTE: If you are changing query iteration code, remember to update the following places, where relevant:1585// QueryIter, QueryIterationCursor, QueryManyIter, QueryCombinationIter,QueryState::par_fold_init_unchecked_manual1586// QueryState::par_many_fold_init_unchecked_manual, QueryState::par_many_unique_fold_init_unchecked_manual, QueryContiguousIter::next15871588bevy_tasks::ComputeTaskPool::get().scope(|scope| {1589let chunks = entity_list.chunks_exact(batch_size as usize);1590let remainder = chunks.remainder();15911592for batch in chunks {1593let mut func = func.clone();1594let init_accum = init_accum.clone();1595scope.spawn(async move {1596#[cfg(feature = "trace")]1597let _span = self.par_iter_span.enter();1598let accum = init_accum();1599self.query_unchecked_manual_with_ticks(world, last_run, this_run)1600.iter_many_unique_inner(batch)1601.fold(accum, &mut func);1602});1603}16041605#[cfg(feature = "trace")]1606let _span = self.par_iter_span.enter();1607let accum = init_accum();1608self.query_unchecked_manual_with_ticks(world, last_run, this_run)1609.iter_many_unique_inner(remainder)1610.fold(accum, &mut func);1611});1612}1613}16141615impl<D: ReadOnlyQueryData, F: QueryFilter> QueryState<D, F> {1616/// Runs `func` on each read-only query result in parallel for the given [`Entity`] list,1617/// where the last change and the current change tick are given. This is faster than the equivalent1618/// `iter_many()` method, but cannot be chained like a normal [`Iterator`].1619///1620/// # Panics1621/// The [`ComputeTaskPool`] is not initialized. If using this from a query that is being1622/// initialized and run from the ECS scheduler, this should never panic.1623///1624/// # Safety1625///1626/// This does not check for mutable query correctness. To be safe, make sure mutable queries1627/// have unique access to the components they query.1628/// This does not validate that `world.id()` matches `self.world_id`. Calling this on a `world`1629/// with a mismatched [`WorldId`] is unsound.1630///1631/// [`ComputeTaskPool`]: bevy_tasks::ComputeTaskPool1632#[cfg(all(not(target_arch = "wasm32"), feature = "multi_threaded"))]1633pub(crate) unsafe fn par_many_fold_init_unchecked_manual<'w, 's, T, FN, INIT, E>(1634&'s self,1635init_accum: INIT,1636world: UnsafeWorldCell<'w>,1637entity_list: &[E],1638batch_size: u32,1639mut func: FN,1640last_run: Tick,1641this_run: Tick,1642) where1643FN: Fn(T, D::Item<'w, 's>) -> T + Send + Sync + Clone,1644INIT: Fn() -> T + Sync + Send + Clone,1645E: EntityEquivalent + Sync,1646{1647// NOTE: If you are changing query iteration code, remember to update the following places, where relevant:1648// QueryIter, QueryIterationCursor, QueryManyIter, QueryCombinationIter, QueryState::par_fold_init_unchecked_manual1649// QueryState::par_many_fold_init_unchecked_manual, QueryState::par_many_unique_fold_init_unchecked_manual, QueryContiguousIter::next16501651bevy_tasks::ComputeTaskPool::get().scope(|scope| {1652let chunks = entity_list.chunks_exact(batch_size as usize);1653let remainder = chunks.remainder();16541655for batch in chunks {1656let mut func = func.clone();1657let init_accum = init_accum.clone();1658scope.spawn(async move {1659#[cfg(feature = "trace")]1660let _span = self.par_iter_span.enter();1661let accum = init_accum();1662self.query_unchecked_manual_with_ticks(world, last_run, this_run)1663.iter_many_inner(batch)1664.fold(accum, &mut func);1665});1666}16671668#[cfg(feature = "trace")]1669let _span = self.par_iter_span.enter();1670let accum = init_accum();1671self.query_unchecked_manual_with_ticks(world, last_run, this_run)1672.iter_many_inner(remainder)1673.fold(accum, &mut func);1674});1675}1676}16771678impl<D: QueryData, F: QueryFilter> QueryState<D, F> {1679/// Returns a single immutable query result when there is exactly one entity matching1680/// the query.1681///1682/// This can only be called for read-only queries,1683/// see [`single_mut`](Self::single_mut) for write-queries.1684///1685/// If the number of query results is not exactly one, a [`QuerySingleError`] is returned1686/// instead.1687///1688/// # Example1689///1690/// Sometimes, you might want to handle the error in a specific way,1691/// generally by spawning the missing entity.1692///1693/// ```rust1694/// use bevy_ecs::prelude::*;1695/// use bevy_ecs::query::QuerySingleError;1696///1697/// #[derive(Component)]1698/// struct A(usize);1699///1700/// fn my_system(query: Query<&A>, mut commands: Commands) {1701/// match query.single() {1702/// Ok(a) => (), // Do something with `a`1703/// Err(err) => match err {1704/// QuerySingleError::NoEntities(_) => {1705/// commands.spawn(A(0));1706/// }1707/// QuerySingleError::MultipleEntities(_) => panic!("Multiple entities found!"),1708/// },1709/// }1710/// }1711/// ```1712///1713/// However in most cases, this error can simply be handled with a graceful early return.1714/// If this is an expected failure mode, you can do this using the `let else` pattern like so:1715/// ```rust1716/// use bevy_ecs::prelude::*;1717///1718/// #[derive(Component)]1719/// struct A(usize);1720///1721/// fn my_system(query: Query<&A>) {1722/// let Ok(a) = query.single() else {1723/// return;1724/// };1725///1726/// // Do something with `a`1727/// }1728/// ```1729///1730/// If this is unexpected though, you should probably use the `?` operator1731/// in combination with Bevy's error handling apparatus.1732///1733/// ```rust1734/// use bevy_ecs::prelude::*;1735///1736/// #[derive(Component)]1737/// struct A(usize);1738///1739/// fn my_system(query: Query<&A>) -> Result {1740/// let a = query.single()?;1741///1742/// // Do something with `a`1743/// Ok(())1744/// }1745/// ```1746///1747/// This allows you to globally control how errors are handled in your application,1748/// by setting up a custom error handler.1749/// See the [`bevy_ecs::error`] module docs for more information!1750/// Commonly, you might want to panic on an error during development, but log the error and continue1751/// execution in production.1752///1753/// Simply unwrapping the [`Result`] also works, but should generally be reserved for tests.1754#[inline]1755pub fn single<'w>(1756&mut self,1757world: &'w World,1758) -> Result<ROQueryItem<'w, '_, D>, QuerySingleError> {1759self.query(world).single_inner()1760}17611762/// Returns a single mutable query result when there is exactly one entity matching1763/// the query.1764///1765/// If the number of query results is not exactly one, a [`QuerySingleError`] is returned1766/// instead.1767///1768/// # Examples1769///1770/// Please see [`Query::single`] for advice on handling the error.1771#[inline]1772pub fn single_mut<'w>(1773&mut self,1774world: &'w mut World,1775) -> Result<D::Item<'w, '_>, QuerySingleError> {1776self.query_mut(world).single_inner()1777}17781779/// Returns a query result when there is exactly one entity matching the query.1780///1781/// If the number of query results is not exactly one, a [`QuerySingleError`] is returned1782/// instead.1783///1784/// # Safety1785///1786/// This does not check for mutable query correctness. To be safe, make sure mutable queries1787/// have unique access to the components they query.1788#[inline]1789pub unsafe fn single_unchecked<'w>(1790&mut self,1791world: UnsafeWorldCell<'w>,1792) -> Result<D::Item<'w, '_>, QuerySingleError> {1793// SAFETY: Upheld by caller1794unsafe { self.query_unchecked(world) }.single_inner()1795}17961797/// Returns a query result when there is exactly one entity matching the query,1798/// where the last change and the current change tick are given.1799///1800/// If the number of query results is not exactly one, a [`QuerySingleError`] is returned1801/// instead.1802///1803/// # Safety1804///1805/// This does not check for mutable query correctness. To be safe, make sure mutable queries1806/// have unique access to the components they query.1807/// This does not validate that `world.id()` matches `self.world_id`. Calling this on a `world`1808/// with a mismatched [`WorldId`] is unsound.1809#[inline]1810pub unsafe fn single_unchecked_manual<'w>(1811&self,1812world: UnsafeWorldCell<'w>,1813last_run: Tick,1814this_run: Tick,1815) -> Result<D::Item<'w, '_>, QuerySingleError> {1816// SAFETY:1817// - The caller ensured we have the correct access to the world.1818// - The caller ensured that the world matches.1819unsafe { self.query_unchecked_manual_with_ticks(world, last_run, this_run) }.single_inner()1820}1821}18221823impl<D: QueryData, F: QueryFilter> From<QueryBuilder<'_, D, F>> for QueryState<D, F> {1824fn from(mut value: QueryBuilder<D, F>) -> Self {1825QueryState::from_builder(&mut value)1826}1827}18281829#[cfg(test)]1830mod tests {1831use crate::{1832component::Component,1833entity_disabling::DefaultQueryFilters,1834prelude::*,1835system::{QueryLens, RunSystemOnce},1836world::{EntityRef, FilteredEntityMut, FilteredEntityRef},1837};18381839#[test]1840#[should_panic]1841fn right_world_get() {1842let mut world_1 = World::new();1843let world_2 = World::new();18441845let mut query_state = world_1.query::<Entity>();1846let _panics = query_state.get(&world_2, Entity::from_raw_u32(0).unwrap());1847}18481849#[test]1850#[should_panic]1851fn right_world_get_many() {1852let mut world_1 = World::new();1853let world_2 = World::new();18541855let mut query_state = world_1.query::<Entity>();1856let _panics = query_state.get_many(&world_2, []);1857}18581859#[test]1860#[should_panic]1861fn right_world_get_many_mut() {1862let mut world_1 = World::new();1863let mut world_2 = World::new();18641865let mut query_state = world_1.query::<Entity>();1866let _panics = query_state.get_many_mut(&mut world_2, []);1867}18681869#[derive(Component, PartialEq, Debug)]1870struct A(usize);18711872#[derive(Component, PartialEq, Debug)]1873struct B(usize);18741875#[derive(Component, PartialEq, Debug)]1876struct C(usize);18771878#[derive(Component)]1879struct D;18801881#[test]1882fn can_transmute_to_more_general() {1883let mut world = World::new();1884world.spawn((A(1), B(0)));18851886let query_state = world.query::<(&A, &B)>();1887let mut new_query_state = query_state.transmute::<&A>(&world);1888assert_eq!(new_query_state.iter(&world).len(), 1);1889let a = new_query_state.single(&world).unwrap();18901891assert_eq!(a.0, 1);1892}18931894#[test]1895fn cannot_get_data_not_in_original_query() {1896let mut world = World::new();1897world.spawn((A(0), B(0)));1898world.spawn((A(1), B(0), C(0)));18991900let query_state = world.query_filtered::<(&A, &B), Without<C>>();1901let mut new_query_state = query_state.transmute::<&A>(&world);1902// even though we change the query to not have Without<C>, we do not get the component with C.1903let a = new_query_state.single(&world).unwrap();19041905assert_eq!(a.0, 0);1906}19071908#[test]1909fn can_transmute_empty_tuple() {1910let mut world = World::new();1911world.register_component::<A>();1912let entity = world.spawn(A(10)).id();19131914let q = world.query_filtered::<(), With<A>>();1915let mut q = q.transmute::<Entity>(&world);1916assert_eq!(q.single(&world).unwrap(), entity);1917}19181919#[test]1920fn can_transmute_immut_fetch() {1921let mut world = World::new();1922world.spawn(A(10));19231924let q = world.query::<&A>();1925let mut new_q = q.transmute::<Ref<A>>(&world);1926assert!(new_q.single(&world).unwrap().is_added());19271928let q = world.query::<Ref<A>>();1929let _ = q.transmute::<&A>(&world);1930}19311932#[test]1933fn can_transmute_mut_fetch() {1934let mut world = World::new();1935world.spawn(A(0));19361937let q = world.query::<&mut A>();1938let _ = q.transmute::<Ref<A>>(&world);1939let _ = q.transmute::<&A>(&world);1940}19411942#[test]1943fn can_transmute_entity_mut() {1944let mut world = World::new();1945world.spawn(A(0));19461947let q: QueryState<EntityMut<'_>> = world.query::<EntityMut>();1948let _ = q.transmute::<EntityRef>(&world);1949}19501951#[test]1952fn can_generalize_with_option() {1953let mut world = World::new();1954world.spawn((A(0), B(0)));19551956let query_state = world.query::<(Option<&A>, &B)>();1957let _ = query_state.transmute::<Option<&A>>(&world);1958let _ = query_state.transmute::<&B>(&world);1959}19601961#[test]1962#[should_panic]1963fn cannot_transmute_to_include_data_not_in_original_query() {1964let mut world = World::new();1965world.register_component::<A>();1966world.register_component::<B>();1967world.spawn(A(0));19681969let query_state = world.query::<&A>();1970let mut _new_query_state = query_state.transmute::<(&A, &B)>(&world);1971}19721973#[test]1974#[should_panic]1975fn cannot_transmute_immut_to_mut() {1976let mut world = World::new();1977world.spawn(A(0));19781979let query_state = world.query::<&A>();1980let mut _new_query_state = query_state.transmute::<&mut A>(&world);1981}19821983#[test]1984#[should_panic]1985fn cannot_transmute_option_to_immut() {1986let mut world = World::new();1987world.spawn(C(0));19881989let query_state = world.query::<Option<&A>>();1990let mut new_query_state = query_state.transmute::<&A>(&world);1991let x = new_query_state.single(&world).unwrap();1992assert_eq!(x.0, 1234);1993}19941995#[test]1996#[should_panic]1997fn cannot_transmute_entity_ref() {1998let mut world = World::new();1999world.register_component::<A>();20002001let q = world.query::<EntityRef>();2002let _ = q.transmute::<&A>(&world);2003}20042005#[test]2006fn can_transmute_filtered_entity() {2007let mut world = World::new();2008let entity = world.spawn((A(0), B(1))).id();2009let query = QueryState::<(Entity, &A, &B)>::new(&mut world)2010.transmute::<(Entity, FilteredEntityRef)>(&world);20112012let mut query = query;2013// Our result is completely untyped2014let (_entity, entity_ref) = query.single(&world).unwrap();20152016assert_eq!(entity, entity_ref.id());2017assert_eq!(0, entity_ref.get::<A>().unwrap().0);2018assert_eq!(1, entity_ref.get::<B>().unwrap().0);2019}20202021#[test]2022fn can_transmute_added() {2023let mut world = World::new();2024let entity_a = world.spawn(A(0)).id();20252026let mut query = QueryState::<(Entity, &A, Has<B>)>::new(&mut world)2027.transmute_filtered::<(Entity, Has<B>), Added<A>>(&world);20282029assert_eq!((entity_a, false), query.single(&world).unwrap());20302031world.clear_trackers();20322033let entity_b = world.spawn((A(0), B(0))).id();2034assert_eq!((entity_b, true), query.single(&world).unwrap());20352036world.clear_trackers();20372038assert!(query.single(&world).is_err());2039}20402041#[test]2042fn can_transmute_changed() {2043let mut world = World::new();2044let entity_a = world.spawn(A(0)).id();20452046let mut detection_query = QueryState::<(Entity, &A)>::new(&mut world)2047.transmute_filtered::<Entity, Changed<A>>(&world);20482049let mut change_query = QueryState::<&mut A>::new(&mut world);2050assert_eq!(entity_a, detection_query.single(&world).unwrap());20512052world.clear_trackers();20532054assert!(detection_query.single(&world).is_err());20552056change_query.single_mut(&mut world).unwrap().0 = 1;20572058assert_eq!(entity_a, detection_query.single(&world).unwrap());2059}20602061#[test]2062#[should_panic]2063fn cannot_transmute_changed_without_access() {2064let mut world = World::new();2065world.register_component::<A>();2066world.register_component::<B>();2067let query = QueryState::<&A>::new(&mut world);2068let _new_query = query.transmute_filtered::<Entity, Changed<B>>(&world);2069}20702071#[test]2072#[should_panic]2073fn cannot_transmute_mutable_after_readonly() {2074let mut world = World::new();2075// Calling this method would mean we had aliasing queries.2076fn bad(_: Query<&mut A>, _: Query<&A>) {}2077world2078.run_system_once(|query: Query<&mut A>| {2079let mut readonly = query.as_readonly();2080let mut lens: QueryLens<&mut A> = readonly.transmute_lens();2081bad(lens.query(), query.as_readonly());2082})2083.unwrap();2084}20852086// Regression test for #146292087#[test]2088#[should_panic]2089fn transmute_with_different_world() {2090let mut world = World::new();2091world.spawn((A(1), B(2)));20922093let mut world2 = World::new();2094world2.register_component::<B>();20952096world.query::<(&A, &B)>().transmute::<&B>(&world2);2097}20982099/// Regression test for issue #145282100#[test]2101fn transmute_from_sparse_to_dense() {2102#[derive(Component)]2103struct Dense;21042105#[derive(Component)]2106#[component(storage = "SparseSet")]2107struct Sparse;21082109let mut world = World::new();21102111world.spawn(Dense);2112world.spawn((Dense, Sparse));21132114let mut query = world2115.query_filtered::<&Dense, With<Sparse>>()2116.transmute::<&Dense>(&world);21172118let matched = query.iter(&world).count();2119assert_eq!(matched, 1);2120}2121#[test]2122fn transmute_from_dense_to_sparse() {2123#[derive(Component)]2124struct Dense;21252126#[derive(Component)]2127#[component(storage = "SparseSet")]2128struct Sparse;21292130let mut world = World::new();21312132world.spawn(Dense);2133world.spawn((Dense, Sparse));21342135let mut query = world2136.query::<&Dense>()2137.transmute_filtered::<&Dense, With<Sparse>>(&world);21382139// Note: `transmute_filtered` is supposed to keep the same matched tables/archetypes,2140// so it doesn't actually filter out those entities without `Sparse` and the iteration2141// remains dense.2142let matched = query.iter(&world).count();2143assert_eq!(matched, 2);2144}21452146#[test]2147fn transmute_to_or_filter() {2148let mut world = World::new();2149world.spawn(D);2150world.spawn((A(0), D));21512152let mut query = world2153.query::<(&D, Option<&A>)>()2154.transmute_filtered::<Entity, Or<(With<A>,)>>(&world);2155let iter = query.iter(&world);2156let len = iter.len();2157let count = iter.count();2158// `transmute_filtered` keeps the same matched tables, so it should match both entities2159// More importantly, `count()` and `len()` should return the same result!2160assert_eq!(len, 2);2161assert_eq!(count, len);21622163let mut query = world2164.query::<(&D, Option<&A>)>()2165.transmute_filtered::<Entity, Or<(Changed<A>,)>>(&world);2166let iter = query.iter(&world);2167let count = iter.count();2168// The behavior of a non-archetypal filter like `Changed` should be the same as an archetypal one like `With`.2169assert_eq!(count, 2);2170}21712172#[test]2173fn dense_query_over_option_is_buggy() {2174#[derive(Component)]2175#[component(storage = "SparseSet")]2176struct Sparse;21772178let mut world = World::new();2179world.spawn(Sparse);21802181let mut query =2182QueryState::<EntityRef>::new(&mut world).transmute::<Option<&Sparse>>(&world);2183// EntityRef always performs dense iteration2184// But `Option<&Sparse>` will incorrectly report a component as never being present when doing dense iteration2185// See https://github.com/bevyengine/bevy/issues/163972186assert!(query.is_dense);2187let matched = query.iter(&world).filter(Option::is_some).count();2188assert_eq!(matched, 0);21892190let mut query = QueryState::<EntityRef>::new(&mut world).transmute::<Has<Sparse>>(&world);2191// EntityRef always performs dense iteration2192// But `Has<Sparse>` will incorrectly report a component as never being present when doing dense iteration2193// See https://github.com/bevyengine/bevy/issues/163972194assert!(query.is_dense);2195let matched = query.iter(&world).filter(|&has| has).count();2196assert_eq!(matched, 0);2197}21982199#[test]2200fn join() {2201let mut world = World::new();2202world.spawn(A(0));2203world.spawn(B(1));2204let entity_ab = world.spawn((A(2), B(3))).id();2205world.spawn((A(4), B(5), C(6)));22062207let query_1 = QueryState::<&A, Without<C>>::new(&mut world);2208let query_2 = QueryState::<&B, Without<C>>::new(&mut world);2209let mut new_query: QueryState<Entity, ()> = query_1.join_filtered(&world, &query_2);22102211assert_eq!(new_query.single(&world).unwrap(), entity_ab);2212}22132214#[test]2215fn join_with_get() {2216let mut world = World::new();2217world.spawn(A(0));2218world.spawn(B(1));2219let entity_ab = world.spawn((A(2), B(3))).id();2220let entity_abc = world.spawn((A(4), B(5), C(6))).id();22212222let query_1 = QueryState::<&A>::new(&mut world);2223let query_2 = QueryState::<&B, Without<C>>::new(&mut world);2224let mut new_query: QueryState<Entity, ()> = query_1.join_filtered(&world, &query_2);22252226assert!(new_query.get(&world, entity_ab).is_ok());2227// should not be able to get entity with c.2228assert!(new_query.get(&world, entity_abc).is_err());2229}22302231#[test]2232#[should_panic]2233fn cannot_join_wrong_fetch() {2234let mut world = World::new();2235world.register_component::<C>();2236let query_1 = QueryState::<&A>::new(&mut world);2237let query_2 = QueryState::<&B>::new(&mut world);2238let _query: QueryState<&C> = query_1.join(&world, &query_2);2239}22402241#[test]2242#[should_panic]2243fn cannot_join_wrong_filter() {2244let mut world = World::new();2245let query_1 = QueryState::<&A, Without<C>>::new(&mut world);2246let query_2 = QueryState::<&B, Without<C>>::new(&mut world);2247let _: QueryState<Entity, Changed<C>> = query_1.join_filtered(&world, &query_2);2248}22492250#[test]2251#[should_panic]2252fn cannot_join_mutable_after_readonly() {2253let mut world = World::new();2254// Calling this method would mean we had aliasing queries.2255fn bad(_: Query<(&mut A, &mut B)>, _: Query<&A>) {}2256world2257.run_system_once(|query_a: Query<&mut A>, mut query_b: Query<&mut B>| {2258let mut readonly = query_a.as_readonly();2259let mut lens: QueryLens<(&mut A, &mut B)> = readonly.join(&mut query_b);2260bad(lens.query(), query_a.as_readonly());2261})2262.unwrap();2263}22642265#[test]2266fn join_to_filtered_entity_mut() {2267let mut world = World::new();2268world.spawn((A(2), B(3)));22692270let query_1 = QueryState::<&mut A>::new(&mut world);2271let query_2 = QueryState::<&mut B>::new(&mut world);2272let mut new_query: QueryState<(Entity, FilteredEntityMut)> = query_1.join(&world, &query_2);22732274let (_entity, mut entity_mut) = new_query.single_mut(&mut world).unwrap();2275assert!(entity_mut.get_mut::<A>().is_some());2276assert!(entity_mut.get_mut::<B>().is_some());2277}22782279#[test]2280fn query_respects_default_filters() {2281let mut world = World::new();2282world.spawn((A(0), B(0), D));2283world.spawn((B(0), C(0), D));2284world.spawn((C(0), D));22852286world.register_disabling_component::<C>();22872288// Without<C> only matches the first entity2289let mut query = QueryState::<&D>::new(&mut world);2290assert_eq!(1, query.iter(&world).count());22912292// With<C> matches the last two entities2293let mut query = QueryState::<&D, With<C>>::new(&mut world);2294assert_eq!(2, query.iter(&world).count());22952296// Has should bypass the filter entirely2297let mut query = QueryState::<(&D, Has<C>)>::new(&mut world);2298assert_eq!(3, query.iter(&world).count());22992300// Allow should bypass the filter entirely2301let mut query = QueryState::<&D, Allow<C>>::new(&mut world);2302assert_eq!(3, query.iter(&world).count());23032304// Other filters should still be respected2305let mut query = QueryState::<(&D, Has<C>), Without<B>>::new(&mut world);2306assert_eq!(1, query.iter(&world).count());2307}23082309#[derive(Component)]2310struct Table;23112312#[derive(Component)]2313#[component(storage = "SparseSet")]2314struct Sparse;23152316#[derive(Component)]2317struct Dummy;23182319#[test]2320fn query_default_filters_updates_is_dense() {2321let mut world = World::new();2322world.spawn((Dummy, Table, Sparse));2323world.spawn((Dummy, Table));2324world.spawn((Dummy, Sparse));23252326let mut query = QueryState::<&Dummy>::new(&mut world);2327// There are no sparse components involved thus the query is dense2328assert!(query.is_dense);2329assert_eq!(3, query.query(&world).count());23302331world.register_disabling_component::<Sparse>();23322333let mut query = QueryState::<&Dummy>::new(&mut world);2334// The query doesn't ask for sparse components, but the default filters adds2335// a sparse component thus it is NOT dense2336assert!(!query.is_dense);2337assert_eq!(1, query.query(&world).count());23382339let mut df = DefaultQueryFilters::from_world(&mut world);2340df.register_disabling_component(world.register_component::<Table>());2341world.insert_resource(df);23422343let mut query = QueryState::<&Dummy>::new(&mut world);2344// If the filter is instead a table components, the query can still be dense2345assert!(query.is_dense);2346assert_eq!(1, query.query(&world).count());23472348let mut query = QueryState::<&Sparse>::new(&mut world);2349// But only if the original query was dense2350assert!(!query.is_dense);2351assert_eq!(1, query.query(&world).count());2352}2353}235423552356