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