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