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