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