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