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