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