Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_ecs/src/query/fetch.rs
9358 views
1
use crate::{
2
archetype::{Archetype, Archetypes},
3
bundle::Bundle,
4
change_detection::{
5
ComponentTicksMut, ComponentTicksRef, ContiguousComponentTicksMut,
6
ContiguousComponentTicksRef, ContiguousMut, ContiguousRef, MaybeLocation, Tick,
7
},
8
component::{Component, ComponentId, Components, Mutable, StorageType},
9
entity::{Entities, Entity, EntityLocation},
10
query::{
11
access_iter::{EcsAccessLevel, EcsAccessType},
12
Access, DebugCheckedUnwrap, FilteredAccess, WorldQuery,
13
},
14
storage::{ComponentSparseSet, Table, TableRow},
15
world::{
16
unsafe_world_cell::UnsafeWorldCell, EntityMut, EntityMutExcept, EntityRef, EntityRefExcept,
17
FilteredEntityMut, FilteredEntityRef, Mut, Ref, World,
18
},
19
};
20
use bevy_ptr::{ThinSlicePtr, UnsafeCellDeref};
21
use bevy_utils::prelude::DebugName;
22
use core::{cell::UnsafeCell, iter, marker::PhantomData, panic::Location};
23
use variadics_please::all_tuples;
24
25
/// Types that can be fetched from a [`World`] using a [`Query`].
26
///
27
/// There are many types that natively implement this trait:
28
///
29
/// - **Component references. (&T and &mut T)**
30
/// Fetches a component by reference (immutably or mutably).
31
/// - **`QueryData` tuples.**
32
/// If every element of a tuple implements `QueryData`, then the tuple itself also implements the same trait.
33
/// This enables a single `Query` to access multiple components.
34
/// Due to the current lack of variadic generics in Rust, the trait has been implemented for tuples from 0 to 15 elements,
35
/// but nesting of tuples allows infinite `WorldQuery`s.
36
/// - **[`Entity`].**
37
/// Gets the identifier of the queried entity.
38
/// - **[`EntityLocation`].**
39
/// Gets the location metadata of the queried entity.
40
/// - **[`SpawnDetails`].**
41
/// Gets the tick the entity was spawned at.
42
/// - **[`EntityRef`].**
43
/// Read-only access to arbitrary components on the queried entity.
44
/// - **[`EntityMut`].**
45
/// Mutable access to arbitrary components on the queried entity.
46
/// - **[`&Archetype`](Archetype).**
47
/// Read-only access to the archetype-level metadata of the queried entity.
48
/// - **[`Option`].**
49
/// By default, a world query only tests entities that have the matching component types.
50
/// Wrapping it into an `Option` will increase the query search space, and it will return `None` if an entity doesn't satisfy the `WorldQuery`.
51
/// - **[`AnyOf`].**
52
/// Equivalent to wrapping each world query inside it into an `Option`.
53
/// - **[`Ref`].**
54
/// Similar to change detection filters but it is used as a query fetch parameter.
55
/// It exposes methods to check for changes to the wrapped component.
56
/// - **[`Mut`].**
57
/// Mutable component access, with change detection data.
58
/// - **[`Has`].**
59
/// Returns a bool indicating whether the entity has the specified component.
60
///
61
/// Implementing the trait manually can allow for a fundamentally new type of behavior.
62
///
63
/// # Trait derivation
64
///
65
/// Query design can be easily structured by deriving `QueryData` for custom types.
66
/// Despite the added complexity, this approach has several advantages over using `QueryData` tuples.
67
/// The most relevant improvements are:
68
///
69
/// - Reusability across multiple systems.
70
/// - There is no need to destructure a tuple since all fields are named.
71
/// - Subqueries can be composed together to create a more complex query.
72
/// - Methods can be implemented for the query items.
73
/// - There is no hardcoded limit on the number of elements.
74
///
75
/// This trait can only be derived for structs, if each field also implements `QueryData`.
76
///
77
/// ```
78
/// # use bevy_ecs::prelude::*;
79
/// use bevy_ecs::query::QueryData;
80
/// #
81
/// # #[derive(Component)]
82
/// # struct ComponentA;
83
/// # #[derive(Component)]
84
/// # struct ComponentB;
85
///
86
/// #[derive(QueryData)]
87
/// struct MyQuery {
88
/// entity: Entity,
89
/// // It is required that all reference lifetimes are explicitly annotated, just like in any
90
/// // struct. Each lifetime should be 'static.
91
/// component_a: &'static ComponentA,
92
/// component_b: &'static ComponentB,
93
/// }
94
///
95
/// fn my_system(query: Query<MyQuery>) {
96
/// for q in &query {
97
/// q.component_a;
98
/// }
99
/// }
100
/// # bevy_ecs::system::assert_is_system(my_system);
101
/// ```
102
///
103
/// ## Macro expansion
104
///
105
/// Expanding the macro will declare one to five additional structs, depending on whether or not the struct is marked as mutable or as contiguous.
106
/// For a struct named `X`, the additional structs will be:
107
///
108
/// |Struct name|`mutable` only|`contiguous` target|Description|
109
/// |:---:|:---:|:---:|---|
110
/// |`XItem`|---|---|The type of the query item for `X`|
111
/// |`XReadOnlyItem`|✓|---|The type of the query item for `XReadOnly`|
112
/// |`XReadOnly`|✓|---|[`ReadOnly`] variant of `X`|
113
/// |`XContiguousItem`|---|`mutable` or `all`|The type of the contiguous query item for `X`|
114
/// |`XReadOnlyContiguousItem`|✓|`immutable` or `all`|The type of the contiguous query item for `XReadOnly`|
115
///
116
/// ## Adding mutable references
117
///
118
/// Simply adding mutable references to a derived `QueryData` will result in a compilation error:
119
///
120
/// ```compile_fail
121
/// # use bevy_ecs::prelude::*;
122
/// # use bevy_ecs::query::QueryData;
123
/// #
124
/// # #[derive(Component)]
125
/// # struct ComponentA;
126
/// #
127
/// #[derive(QueryData)]
128
/// struct CustomQuery {
129
/// component_a: &'static mut ComponentA,
130
/// }
131
/// ```
132
///
133
/// To grant mutable access to components, the struct must be marked with the `#[query_data(mutable)]` attribute.
134
/// This will also create three more structs that will be used for accessing the query immutably (see table above).
135
///
136
/// ```
137
/// # use bevy_ecs::prelude::*;
138
/// # use bevy_ecs::query::QueryData;
139
/// #
140
/// # #[derive(Component)]
141
/// # struct ComponentA;
142
/// #
143
/// #[derive(QueryData)]
144
/// #[query_data(mutable)]
145
/// struct CustomQuery {
146
/// component_a: &'static mut ComponentA,
147
/// }
148
/// ```
149
///
150
/// ## Supporting contiguous iteration
151
///
152
/// To create contiguous items additionally (to support contiguous iteration), the struct must be marked with the `#[query_data(contiguous(target))]` attribute,
153
/// where the target may be `all`, `mutable` or `immutable` (see the table above).
154
///
155
/// For mutable queries it may be done like this:
156
/// ```
157
/// # use bevy_ecs::prelude::*;
158
/// # use bevy_ecs::query::QueryData;
159
/// #
160
/// # #[derive(Component)]
161
/// # struct ComponentA;
162
/// #
163
/// #[derive(QueryData)]
164
/// /// - contiguous(all) will create contiguous items for both read and mutable versions
165
/// /// - contiguous(mutable) will only create a contiguous item for the mutable version
166
/// /// - contiguous(immutable) will only create a contiguous item for the read only version
167
/// #[query_data(mutable, contiguous(all))]
168
/// struct CustomQuery {
169
/// component_a: &'static mut ComponentA,
170
/// }
171
/// ```
172
///
173
/// For immutable queries `contiguous(immutable)` attribute will be **ignored**, meanwhile `contiguous(mutable)` and `contiguous(all)`
174
/// will only generate a contiguous item for the (original) read only version.
175
///
176
/// To understand contiguous iteration refer to
177
/// [`Query::contiguous_iter`](`crate::system::Query::contiguous_iter`)
178
///
179
/// ## Adding methods to query items
180
///
181
/// It is possible to add methods to query items in order to write reusable logic about related components.
182
/// This will often make systems more readable because low level logic is moved out from them.
183
/// It is done by adding `impl` blocks with methods for the `-Item`, `-ReadOnlyItem`, `-ContiguousItem` or `ContiguousReadOnlyItem`
184
/// generated structs.
185
///
186
/// ```
187
/// # use bevy_ecs::prelude::*;
188
/// # use bevy_ecs::query::QueryData;
189
/// #
190
/// #[derive(Component)]
191
/// struct Health(f32);
192
///
193
/// #[derive(Component)]
194
/// struct Buff(f32);
195
///
196
/// #[derive(QueryData)]
197
/// #[query_data(mutable)]
198
/// struct HealthQuery {
199
/// health: &'static mut Health,
200
/// buff: Option<&'static mut Buff>,
201
/// }
202
///
203
/// // `HealthQueryItem` is only available when accessing the query with mutable methods.
204
/// impl<'w, 's> HealthQueryItem<'w, 's> {
205
/// fn damage(&mut self, value: f32) {
206
/// self.health.0 -= value;
207
/// }
208
///
209
/// fn total(&self) -> f32 {
210
/// self.health.0 + self.buff.as_deref().map_or(0.0, |Buff(buff)| *buff)
211
/// }
212
/// }
213
///
214
/// // `HealthQueryReadOnlyItem` is only available when accessing the query with immutable methods.
215
/// impl<'w, 's> HealthQueryReadOnlyItem<'w, 's> {
216
/// fn total(&self) -> f32 {
217
/// self.health.0 + self.buff.map_or(0.0, |Buff(buff)| *buff)
218
/// }
219
/// }
220
///
221
/// fn my_system(mut health_query: Query<HealthQuery>) {
222
/// // The item returned by the iterator is of type `HealthQueryReadOnlyItem`.
223
/// for health in health_query.iter() {
224
/// println!("Total: {}", health.total());
225
/// }
226
/// // The item returned by the iterator is of type `HealthQueryItem`.
227
/// for mut health in &mut health_query {
228
/// health.damage(1.0);
229
/// println!("Total (mut): {}", health.total());
230
/// }
231
/// }
232
/// # bevy_ecs::system::assert_is_system(my_system);
233
/// ```
234
///
235
/// ## Deriving traits for query items
236
///
237
/// The `QueryData` derive macro does not automatically implement the traits of the struct to the query item types.
238
/// Something similar can be done by using the `#[query_data(derive(...))]` attribute.
239
/// This will apply the listed derivable traits to the query item structs.
240
///
241
/// ```
242
/// # use bevy_ecs::prelude::*;
243
/// # use bevy_ecs::query::QueryData;
244
/// #
245
/// # #[derive(Component, Debug)]
246
/// # struct ComponentA;
247
/// #
248
/// #[derive(QueryData)]
249
/// #[query_data(mutable, derive(Debug), contiguous(all))]
250
/// struct CustomQuery {
251
/// component_a: &'static ComponentA,
252
/// }
253
///
254
/// // This function statically checks that `T` implements `Debug`.
255
/// fn assert_debug<T: std::fmt::Debug>() {}
256
///
257
/// assert_debug::<CustomQueryItem>();
258
/// assert_debug::<CustomQueryReadOnlyItem>();
259
/// assert_debug::<CustomQueryContiguousItem>();
260
/// assert_debug::<CustomQueryReadOnlyContiguousItem>();
261
/// ```
262
///
263
/// ## Query composition
264
///
265
/// It is possible to use any `QueryData` as a field of another one.
266
/// This means that a `QueryData` can also be used as a subquery, potentially in multiple places.
267
///
268
/// ```
269
/// # use bevy_ecs::prelude::*;
270
/// # use bevy_ecs::query::QueryData;
271
/// #
272
/// # #[derive(Component)]
273
/// # struct ComponentA;
274
/// # #[derive(Component)]
275
/// # struct ComponentB;
276
/// # #[derive(Component)]
277
/// # struct ComponentC;
278
/// #
279
/// #[derive(QueryData)]
280
/// struct SubQuery {
281
/// component_a: &'static ComponentA,
282
/// component_b: &'static ComponentB,
283
/// }
284
///
285
/// #[derive(QueryData)]
286
/// struct MyQuery {
287
/// subquery: SubQuery,
288
/// component_c: &'static ComponentC,
289
/// }
290
/// ```
291
///
292
/// # Generic Queries
293
///
294
/// When writing generic code, it is often necessary to use [`PhantomData`]
295
/// to constrain type parameters. Since `QueryData` is implemented for all
296
/// `PhantomData<T>` types, this pattern can be used with this macro.
297
///
298
/// ```
299
/// # use bevy_ecs::{prelude::*, query::QueryData};
300
/// # use std::marker::PhantomData;
301
/// #[derive(QueryData)]
302
/// pub struct GenericQuery<T> {
303
/// id: Entity,
304
/// marker: PhantomData<T>,
305
/// }
306
/// # fn my_system(q: Query<GenericQuery<()>>) {}
307
/// # bevy_ecs::system::assert_is_system(my_system);
308
/// ```
309
///
310
/// # Safety
311
///
312
/// - Component access of `Self::ReadOnly` must be a subset of `Self`
313
/// and `Self::ReadOnly` must match exactly the same archetypes/tables as `Self`
314
/// - `IS_READ_ONLY` must be `true` if and only if `Self: ReadOnlyQueryData`
315
///
316
/// [`Query`]: crate::system::Query
317
/// [`ReadOnly`]: Self::ReadOnly
318
#[diagnostic::on_unimplemented(
319
message = "`{Self}` is not valid to request as data in a `Query`",
320
label = "invalid `Query` data",
321
note = "if `{Self}` is a component type, try using `&{Self}` or `&mut {Self}`"
322
)]
323
pub unsafe trait QueryData: WorldQuery {
324
/// True if this query is read-only and may not perform mutable access.
325
const IS_READ_ONLY: bool;
326
327
/// Returns true if (and only if) this query data relies strictly on archetypes to limit which
328
/// entities are accessed by the Query.
329
///
330
/// This enables optimizations for [`QueryIter`](`crate::query::QueryIter`) that rely on knowing exactly how
331
/// many elements are being iterated (such as `Iterator::collect()`).
332
///
333
/// If this is `true`, then [`QueryData::fetch`] must always return `Some`.
334
const IS_ARCHETYPAL: bool;
335
336
/// The read-only variant of this [`QueryData`], which satisfies the [`ReadOnlyQueryData`] trait.
337
type ReadOnly: ReadOnlyQueryData<State = <Self as WorldQuery>::State>;
338
339
/// The item returned by this [`WorldQuery`]
340
/// This will be the data retrieved by the query,
341
/// and is visible to the end user when calling e.g. `Query<Self>::get`.
342
type Item<'w, 's>;
343
344
/// This function manually implements subtyping for the query items.
345
fn shrink<'wlong: 'wshort, 'wshort, 's>(
346
item: Self::Item<'wlong, 's>,
347
) -> Self::Item<'wshort, 's>;
348
349
/// Offers additional access above what we requested in `update_component_access`.
350
/// Implementations may add additional access that is a subset of `available_access`
351
/// and does not conflict with anything in `access`,
352
/// and must update `access` to include that access.
353
///
354
/// This is used by [`WorldQuery`] types like [`FilteredEntityRef`]
355
/// and [`FilteredEntityMut`] to support dynamic access.
356
///
357
/// Called when constructing a [`QueryLens`](crate::system::QueryLens) or calling [`QueryState::from_builder`](super::QueryState::from_builder)
358
fn provide_extra_access(
359
_state: &mut Self::State,
360
_access: &mut Access,
361
_available_access: &Access,
362
) {
363
}
364
365
/// Fetch [`Self::Item`](`QueryData::Item`) for either the given `entity` in the current [`Table`],
366
/// or for the given `entity` in the current [`Archetype`]. This must always be called after
367
/// [`WorldQuery::set_table`] with a `table_row` in the range of the current [`Table`] or after
368
/// [`WorldQuery::set_archetype`] with an `entity` in the current archetype.
369
/// Accesses components registered in [`WorldQuery::update_component_access`].
370
///
371
/// This method returns `None` if the entity does not match the query.
372
/// If `Self` implements [`ArchetypeQueryData`], this must always return `Some`.
373
///
374
/// # Safety
375
///
376
/// - Must always be called _after_ [`WorldQuery::set_table`] or [`WorldQuery::set_archetype`]. `entity` and
377
/// `table_row` must be in the range of the current table and archetype.
378
/// - There must not be simultaneous conflicting component access registered in `update_component_access`.
379
unsafe fn fetch<'w, 's>(
380
state: &'s Self::State,
381
fetch: &mut Self::Fetch<'w>,
382
entity: Entity,
383
table_row: TableRow,
384
) -> Option<Self::Item<'w, 's>>;
385
386
/// Returns an iterator over the access needed by [`QueryData::fetch`]. Access conflicts are usually
387
/// checked in [`WorldQuery::update_component_access`], but in certain cases this method can be useful to implement
388
/// a way of checking for access conflicts in a non-allocating way.
389
fn iter_access(state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>>;
390
}
391
392
/// A [`QueryData`] which allows getting a direct access to contiguous chunks of components'
393
/// values, which may be used to apply simd-operations.
394
///
395
/// Contiguous iteration may be done via:
396
/// - [`Query::contiguous_iter`](crate::system::Query::contiguous_iter),
397
/// - [`Query::contiguous_iter_mut`](crate::system::Query::contiguous_iter_mut),
398
///
399
// NOTE: Even though all component references (&T, &mut T) implement this trait, it won't be executed for
400
// SparseSet components because in that case the query is not dense.
401
#[diagnostic::on_unimplemented(
402
message = "`{Self}` cannot be iterated contiguously",
403
label = "invalid contiguous `Query` data",
404
note = "if `{Self}` is a custom query type, using `QueryData` derive macro, ensure that the `#[query_data(contiguous(target))]` attribute is added"
405
)]
406
pub trait ContiguousQueryData: ArchetypeQueryData {
407
/// Item returned by [`ContiguousQueryData::fetch_contiguous`].
408
/// Represents a contiguous chunk of memory.
409
type Contiguous<'w, 's>;
410
411
/// Fetch [`ContiguousQueryData::Contiguous`] which represents a contiguous chunk of memory (e.g., an array) in the current [`Table`].
412
/// This must always be called after [`WorldQuery::set_table`].
413
///
414
/// # Safety
415
///
416
/// - Must always be called _after_ [`WorldQuery::set_table`].
417
/// - `entities`'s length must match the length of the set table.
418
/// - `entities` must match the entities of the set table.
419
/// - There must not be simultaneous conflicting component access registered in `update_component_access`.
420
unsafe fn fetch_contiguous<'w, 's>(
421
state: &'s Self::State,
422
fetch: &mut Self::Fetch<'w>,
423
entities: &'w [Entity],
424
) -> Self::Contiguous<'w, 's>;
425
}
426
427
/// A [`QueryData`] that is read only.
428
///
429
/// # Safety
430
///
431
/// This must only be implemented for read-only [`QueryData`]'s.
432
pub unsafe trait ReadOnlyQueryData: QueryData<ReadOnly = Self> {}
433
434
/// The item type returned when a [`WorldQuery`] is iterated over
435
pub type QueryItem<'w, 's, Q> = <Q as QueryData>::Item<'w, 's>;
436
/// The read-only variant of the item type returned when a [`QueryData`] is iterated over immutably
437
pub type ROQueryItem<'w, 's, D> = QueryItem<'w, 's, <D as QueryData>::ReadOnly>;
438
439
/// A [`QueryData`] that does not borrow from its [`QueryState`](crate::query::QueryState).
440
///
441
/// This is implemented by most `QueryData` types.
442
/// The main exceptions are [`FilteredEntityRef`], [`FilteredEntityMut`], [`EntityRefExcept`], and [`EntityMutExcept`],
443
/// which borrow an access list from their query state.
444
/// Consider using a full [`EntityRef`] or [`EntityMut`] if you would need those.
445
pub trait ReleaseStateQueryData: QueryData {
446
/// Releases the borrow from the query state by converting an item to have a `'static` state lifetime.
447
fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static>;
448
}
449
450
/// A marker trait to indicate that the query data filters at an archetype level.
451
///
452
/// This is needed to implement [`ExactSizeIterator`] for
453
/// [`QueryIter`](crate::query::QueryIter) that contains archetype-level filters.
454
///
455
/// The trait must only be implemented for query data where its corresponding [`QueryData::IS_ARCHETYPAL`] is [`prim@true`].
456
pub trait ArchetypeQueryData: QueryData {}
457
458
// SAFETY:
459
// `update_component_access` does nothing.
460
// This is sound because `fetch` does not access components.
461
unsafe impl WorldQuery for Entity {
462
type Fetch<'w> = ();
463
type State = ();
464
465
fn shrink_fetch<'wlong: 'wshort, 'wshort>(_: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {}
466
467
unsafe fn init_fetch<'w, 's>(
468
_world: UnsafeWorldCell<'w>,
469
_state: &'s Self::State,
470
_last_run: Tick,
471
_this_run: Tick,
472
) -> Self::Fetch<'w> {
473
}
474
475
const IS_DENSE: bool = true;
476
477
#[inline]
478
unsafe fn set_archetype<'w, 's>(
479
_fetch: &mut Self::Fetch<'w>,
480
_state: &'s Self::State,
481
_archetype: &'w Archetype,
482
_table: &Table,
483
) {
484
}
485
486
#[inline]
487
unsafe fn set_table<'w, 's>(
488
_fetch: &mut Self::Fetch<'w>,
489
_state: &'s Self::State,
490
_table: &'w Table,
491
) {
492
}
493
494
fn update_component_access(_state: &Self::State, _access: &mut FilteredAccess) {}
495
496
fn init_state(_world: &mut World) {}
497
498
fn get_state(_components: &Components) -> Option<()> {
499
Some(())
500
}
501
502
fn matches_component_set(
503
_state: &Self::State,
504
_set_contains_id: &impl Fn(ComponentId) -> bool,
505
) -> bool {
506
true
507
}
508
}
509
510
// SAFETY: `Self` is the same as `Self::ReadOnly`
511
unsafe impl QueryData for Entity {
512
const IS_READ_ONLY: bool = true;
513
const IS_ARCHETYPAL: bool = true;
514
type ReadOnly = Self;
515
516
type Item<'w, 's> = Entity;
517
518
fn shrink<'wlong: 'wshort, 'wshort, 's>(
519
item: Self::Item<'wlong, 's>,
520
) -> Self::Item<'wshort, 's> {
521
item
522
}
523
524
#[inline(always)]
525
unsafe fn fetch<'w, 's>(
526
_state: &'s Self::State,
527
_fetch: &mut Self::Fetch<'w>,
528
entity: Entity,
529
_table_row: TableRow,
530
) -> Option<Self::Item<'w, 's>> {
531
Some(entity)
532
}
533
534
fn iter_access(_state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
535
iter::empty()
536
}
537
}
538
539
// SAFETY: access is read only
540
unsafe impl ReadOnlyQueryData for Entity {}
541
542
impl ReleaseStateQueryData for Entity {
543
fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
544
item
545
}
546
}
547
548
impl ArchetypeQueryData for Entity {}
549
550
impl ContiguousQueryData for Entity {
551
type Contiguous<'w, 's> = &'w [Entity];
552
553
unsafe fn fetch_contiguous<'w, 's>(
554
_state: &'s Self::State,
555
_fetch: &mut Self::Fetch<'w>,
556
entities: &'w [Entity],
557
) -> Self::Contiguous<'w, 's> {
558
entities
559
}
560
}
561
562
// SAFETY:
563
// `update_component_access` does nothing.
564
// This is sound because `fetch` does not access components.
565
unsafe impl WorldQuery for EntityLocation {
566
type Fetch<'w> = &'w Entities;
567
type State = ();
568
569
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
570
fetch
571
}
572
573
unsafe fn init_fetch<'w, 's>(
574
world: UnsafeWorldCell<'w>,
575
_state: &'s Self::State,
576
_last_run: Tick,
577
_this_run: Tick,
578
) -> Self::Fetch<'w> {
579
world.entities()
580
}
581
582
// This is set to true to avoid forcing archetypal iteration in compound queries, is likely to be slower
583
// in most practical use case.
584
const IS_DENSE: bool = true;
585
586
#[inline]
587
unsafe fn set_archetype<'w, 's>(
588
_fetch: &mut Self::Fetch<'w>,
589
_state: &'s Self::State,
590
_archetype: &'w Archetype,
591
_table: &Table,
592
) {
593
}
594
595
#[inline]
596
unsafe fn set_table<'w, 's>(
597
_fetch: &mut Self::Fetch<'w>,
598
_state: &'s Self::State,
599
_table: &'w Table,
600
) {
601
}
602
603
fn update_component_access(_state: &Self::State, _access: &mut FilteredAccess) {}
604
605
fn init_state(_world: &mut World) {}
606
607
fn get_state(_components: &Components) -> Option<()> {
608
Some(())
609
}
610
611
fn matches_component_set(
612
_state: &Self::State,
613
_set_contains_id: &impl Fn(ComponentId) -> bool,
614
) -> bool {
615
true
616
}
617
}
618
619
// SAFETY: `Self` is the same as `Self::ReadOnly`
620
unsafe impl QueryData for EntityLocation {
621
const IS_READ_ONLY: bool = true;
622
const IS_ARCHETYPAL: bool = true;
623
type ReadOnly = Self;
624
type Item<'w, 's> = EntityLocation;
625
626
fn shrink<'wlong: 'wshort, 'wshort, 's>(
627
item: Self::Item<'wlong, 's>,
628
) -> Self::Item<'wshort, 's> {
629
item
630
}
631
632
#[inline(always)]
633
unsafe fn fetch<'w, 's>(
634
_state: &'s Self::State,
635
fetch: &mut Self::Fetch<'w>,
636
entity: Entity,
637
_table_row: TableRow,
638
) -> Option<Self::Item<'w, 's>> {
639
// SAFETY: `fetch` must be called with an entity that exists in the world
640
Some(unsafe { fetch.get_spawned(entity).debug_checked_unwrap() })
641
}
642
643
fn iter_access(_state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
644
iter::empty()
645
}
646
}
647
648
// SAFETY: access is read only
649
unsafe impl ReadOnlyQueryData for EntityLocation {}
650
651
impl ReleaseStateQueryData for EntityLocation {
652
fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
653
item
654
}
655
}
656
657
impl ArchetypeQueryData for EntityLocation {}
658
659
/// The `SpawnDetails` query parameter fetches the [`Tick`] the entity was spawned at.
660
///
661
/// To evaluate whether the spawn happened since the last time the system ran, the system
662
/// param [`SystemChangeTick`](bevy_ecs::system::SystemChangeTick) needs to be used.
663
///
664
/// If the query should filter for spawned entities instead, use the
665
/// [`Spawned`](bevy_ecs::query::Spawned) query filter instead.
666
///
667
/// # Examples
668
///
669
/// ```
670
/// # use bevy_ecs::component::Component;
671
/// # use bevy_ecs::entity::Entity;
672
/// # use bevy_ecs::system::Query;
673
/// # use bevy_ecs::query::Spawned;
674
/// # use bevy_ecs::query::SpawnDetails;
675
///
676
/// fn print_spawn_details(query: Query<(Entity, SpawnDetails)>) {
677
/// for (entity, spawn_details) in &query {
678
/// if spawn_details.is_spawned() {
679
/// print!("new ");
680
/// }
681
/// print!(
682
/// "entity {:?} spawned at {:?}",
683
/// entity,
684
/// spawn_details.spawn_tick()
685
/// );
686
/// match spawn_details.spawned_by().into_option() {
687
/// Some(location) => println!(" by {:?}", location),
688
/// None => println!()
689
/// }
690
/// }
691
/// }
692
///
693
/// # bevy_ecs::system::assert_is_system(print_spawn_details);
694
/// ```
695
#[derive(Clone, Copy, Debug)]
696
pub struct SpawnDetails {
697
spawned_by: MaybeLocation,
698
spawn_tick: Tick,
699
last_run: Tick,
700
this_run: Tick,
701
}
702
703
impl SpawnDetails {
704
/// Returns `true` if the entity spawned since the last time this system ran.
705
/// Otherwise, returns `false`.
706
pub fn is_spawned(self) -> bool {
707
self.spawn_tick.is_newer_than(self.last_run, self.this_run)
708
}
709
710
/// Returns the `Tick` this entity spawned at.
711
pub fn spawn_tick(self) -> Tick {
712
self.spawn_tick
713
}
714
715
/// Returns the source code location from which this entity has been spawned.
716
pub fn spawned_by(self) -> MaybeLocation {
717
self.spawned_by
718
}
719
}
720
721
#[doc(hidden)]
722
#[derive(Clone)]
723
pub struct SpawnDetailsFetch<'w> {
724
entities: &'w Entities,
725
last_run: Tick,
726
this_run: Tick,
727
}
728
729
// SAFETY:
730
// No components are accessed.
731
unsafe impl WorldQuery for SpawnDetails {
732
type Fetch<'w> = SpawnDetailsFetch<'w>;
733
type State = ();
734
735
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
736
fetch
737
}
738
739
unsafe fn init_fetch<'w, 's>(
740
world: UnsafeWorldCell<'w>,
741
_state: &'s Self::State,
742
last_run: Tick,
743
this_run: Tick,
744
) -> Self::Fetch<'w> {
745
SpawnDetailsFetch {
746
entities: world.entities(),
747
last_run,
748
this_run,
749
}
750
}
751
752
const IS_DENSE: bool = true;
753
754
#[inline]
755
unsafe fn set_archetype<'w, 's>(
756
_fetch: &mut Self::Fetch<'w>,
757
_state: &'s Self::State,
758
_archetype: &'w Archetype,
759
_table: &'w Table,
760
) {
761
}
762
763
#[inline]
764
unsafe fn set_table<'w, 's>(
765
_fetch: &mut Self::Fetch<'w>,
766
_state: &'s Self::State,
767
_table: &'w Table,
768
) {
769
}
770
771
fn update_component_access(_state: &Self::State, _access: &mut FilteredAccess) {}
772
773
fn init_state(_world: &mut World) {}
774
775
fn get_state(_components: &Components) -> Option<()> {
776
Some(())
777
}
778
779
fn matches_component_set(
780
_state: &Self::State,
781
_set_contains_id: &impl Fn(ComponentId) -> bool,
782
) -> bool {
783
true
784
}
785
}
786
787
// SAFETY:
788
// No components are accessed.
789
// Is its own ReadOnlyQueryData.
790
unsafe impl QueryData for SpawnDetails {
791
const IS_READ_ONLY: bool = true;
792
const IS_ARCHETYPAL: bool = true;
793
type ReadOnly = Self;
794
type Item<'w, 's> = Self;
795
796
fn shrink<'wlong: 'wshort, 'wshort, 's>(
797
item: Self::Item<'wlong, 's>,
798
) -> Self::Item<'wshort, 's> {
799
item
800
}
801
802
#[inline(always)]
803
unsafe fn fetch<'w, 's>(
804
_state: &'s Self::State,
805
fetch: &mut Self::Fetch<'w>,
806
entity: Entity,
807
_table_row: TableRow,
808
) -> Option<Self::Item<'w, 's>> {
809
// SAFETY: only living entities are queried
810
let (spawned_by, spawn_tick) = unsafe {
811
fetch
812
.entities
813
.entity_get_spawned_or_despawned_unchecked(entity)
814
};
815
Some(Self {
816
spawned_by,
817
spawn_tick,
818
last_run: fetch.last_run,
819
this_run: fetch.this_run,
820
})
821
}
822
823
fn iter_access(_state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
824
iter::empty()
825
}
826
}
827
828
// SAFETY: access is read only
829
unsafe impl ReadOnlyQueryData for SpawnDetails {}
830
831
impl ReleaseStateQueryData for SpawnDetails {
832
fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
833
item
834
}
835
}
836
837
impl ArchetypeQueryData for SpawnDetails {}
838
839
/// The [`WorldQuery::Fetch`] type for WorldQueries that can fetch multiple components from an entity
840
/// ([`EntityRef`], [`EntityMut`], etc.)
841
#[derive(Copy, Clone)]
842
#[doc(hidden)]
843
pub struct EntityFetch<'w> {
844
world: UnsafeWorldCell<'w>,
845
last_run: Tick,
846
this_run: Tick,
847
}
848
849
// SAFETY:
850
// `fetch` accesses all components in a readonly way.
851
// This is sound because `update_component_access` sets read access for all components and panic when appropriate.
852
// Filters are unchanged.
853
unsafe impl<'a> WorldQuery for EntityRef<'a> {
854
type Fetch<'w> = EntityFetch<'w>;
855
type State = ();
856
857
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
858
fetch
859
}
860
861
unsafe fn init_fetch<'w, 's>(
862
world: UnsafeWorldCell<'w>,
863
_state: &'s Self::State,
864
last_run: Tick,
865
this_run: Tick,
866
) -> Self::Fetch<'w> {
867
EntityFetch {
868
world,
869
last_run,
870
this_run,
871
}
872
}
873
874
const IS_DENSE: bool = true;
875
876
#[inline]
877
unsafe fn set_archetype<'w, 's>(
878
_fetch: &mut Self::Fetch<'w>,
879
_state: &'s Self::State,
880
_archetype: &'w Archetype,
881
_table: &Table,
882
) {
883
}
884
885
#[inline]
886
unsafe fn set_table<'w, 's>(
887
_fetch: &mut Self::Fetch<'w>,
888
_state: &'s Self::State,
889
_table: &'w Table,
890
) {
891
}
892
893
fn update_component_access(_state: &Self::State, access: &mut FilteredAccess) {
894
assert!(
895
!access.access().has_any_component_write(),
896
"EntityRef conflicts with a previous access in this query. Shared access cannot coincide with exclusive access.",
897
);
898
access.read_all_components();
899
}
900
901
fn init_state(_world: &mut World) {}
902
903
fn get_state(_components: &Components) -> Option<()> {
904
Some(())
905
}
906
907
fn matches_component_set(
908
_state: &Self::State,
909
_set_contains_id: &impl Fn(ComponentId) -> bool,
910
) -> bool {
911
true
912
}
913
}
914
915
// SAFETY: `Self` is the same as `Self::ReadOnly`
916
unsafe impl<'a> QueryData for EntityRef<'a> {
917
const IS_READ_ONLY: bool = true;
918
const IS_ARCHETYPAL: bool = true;
919
type ReadOnly = Self;
920
type Item<'w, 's> = EntityRef<'w>;
921
922
fn shrink<'wlong: 'wshort, 'wshort, 's>(
923
item: Self::Item<'wlong, 's>,
924
) -> Self::Item<'wshort, 's> {
925
item
926
}
927
928
#[inline(always)]
929
unsafe fn fetch<'w, 's>(
930
_state: &'s Self::State,
931
fetch: &mut Self::Fetch<'w>,
932
entity: Entity,
933
_table_row: TableRow,
934
) -> Option<Self::Item<'w, 's>> {
935
// SAFETY: `fetch` must be called with an entity that exists in the world
936
let cell = unsafe {
937
fetch
938
.world
939
.get_entity_with_ticks(entity, fetch.last_run, fetch.this_run)
940
.debug_checked_unwrap()
941
};
942
// SAFETY: Read-only access to every component has been registered.
943
Some(unsafe { EntityRef::new(cell) })
944
}
945
946
fn iter_access(_state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
947
iter::once(EcsAccessType::Component(EcsAccessLevel::ReadAll))
948
}
949
}
950
951
// SAFETY: access is read only
952
unsafe impl ReadOnlyQueryData for EntityRef<'_> {}
953
954
impl ReleaseStateQueryData for EntityRef<'_> {
955
fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
956
item
957
}
958
}
959
960
impl ArchetypeQueryData for EntityRef<'_> {}
961
962
// SAFETY: The accesses of `Self::ReadOnly` are a subset of the accesses of `Self`
963
unsafe impl<'a> WorldQuery for EntityMut<'a> {
964
type Fetch<'w> = EntityFetch<'w>;
965
type State = ();
966
967
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
968
fetch
969
}
970
971
unsafe fn init_fetch<'w, 's>(
972
world: UnsafeWorldCell<'w>,
973
_state: &'s Self::State,
974
last_run: Tick,
975
this_run: Tick,
976
) -> Self::Fetch<'w> {
977
EntityFetch {
978
world,
979
last_run,
980
this_run,
981
}
982
}
983
984
const IS_DENSE: bool = true;
985
986
#[inline]
987
unsafe fn set_archetype<'w, 's>(
988
_fetch: &mut Self::Fetch<'w>,
989
_state: &'s Self::State,
990
_archetype: &'w Archetype,
991
_table: &Table,
992
) {
993
}
994
995
#[inline]
996
unsafe fn set_table<'w, 's>(
997
_fetch: &mut Self::Fetch<'w>,
998
_state: &'s Self::State,
999
_table: &'w Table,
1000
) {
1001
}
1002
1003
fn update_component_access(_state: &Self::State, access: &mut FilteredAccess) {
1004
assert!(
1005
!access.access().has_any_component_read(),
1006
"EntityMut conflicts with a previous access in this query. Exclusive access cannot coincide with any other accesses.",
1007
);
1008
access.write_all_components();
1009
}
1010
1011
fn init_state(_world: &mut World) {}
1012
1013
fn get_state(_components: &Components) -> Option<()> {
1014
Some(())
1015
}
1016
1017
fn matches_component_set(
1018
_state: &Self::State,
1019
_set_contains_id: &impl Fn(ComponentId) -> bool,
1020
) -> bool {
1021
true
1022
}
1023
}
1024
1025
// SAFETY: access of `EntityRef` is a subset of `EntityMut`
1026
unsafe impl<'a> QueryData for EntityMut<'a> {
1027
const IS_READ_ONLY: bool = false;
1028
const IS_ARCHETYPAL: bool = true;
1029
type ReadOnly = EntityRef<'a>;
1030
type Item<'w, 's> = EntityMut<'w>;
1031
1032
fn shrink<'wlong: 'wshort, 'wshort, 's>(
1033
item: Self::Item<'wlong, 's>,
1034
) -> Self::Item<'wshort, 's> {
1035
item
1036
}
1037
1038
#[inline(always)]
1039
unsafe fn fetch<'w, 's>(
1040
_state: &'s Self::State,
1041
fetch: &mut Self::Fetch<'w>,
1042
entity: Entity,
1043
_table_row: TableRow,
1044
) -> Option<Self::Item<'w, 's>> {
1045
// SAFETY: `fetch` must be called with an entity that exists in the world
1046
let cell = unsafe {
1047
fetch
1048
.world
1049
.get_entity_with_ticks(entity, fetch.last_run, fetch.this_run)
1050
.debug_checked_unwrap()
1051
};
1052
// SAFETY: mutable access to every component has been registered.
1053
Some(unsafe { EntityMut::new(cell) })
1054
}
1055
1056
fn iter_access(_state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
1057
iter::once(EcsAccessType::Component(EcsAccessLevel::WriteAll))
1058
}
1059
}
1060
1061
impl ReleaseStateQueryData for EntityMut<'_> {
1062
fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
1063
item
1064
}
1065
}
1066
1067
impl ArchetypeQueryData for EntityMut<'_> {}
1068
1069
// SAFETY: The accesses of `Self::ReadOnly` are a subset of the accesses of `Self`
1070
unsafe impl WorldQuery for FilteredEntityRef<'_, '_> {
1071
type Fetch<'w> = EntityFetch<'w>;
1072
type State = Access;
1073
1074
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
1075
fetch
1076
}
1077
1078
const IS_DENSE: bool = true;
1079
1080
unsafe fn init_fetch<'w, 's>(
1081
world: UnsafeWorldCell<'w>,
1082
_state: &'s Self::State,
1083
last_run: Tick,
1084
this_run: Tick,
1085
) -> Self::Fetch<'w> {
1086
EntityFetch {
1087
world,
1088
last_run,
1089
this_run,
1090
}
1091
}
1092
1093
#[inline]
1094
unsafe fn set_archetype<'w, 's>(
1095
_fetch: &mut Self::Fetch<'w>,
1096
_state: &'s Self::State,
1097
_: &'w Archetype,
1098
_table: &Table,
1099
) {
1100
}
1101
1102
#[inline]
1103
unsafe fn set_table<'w, 's>(
1104
_fetch: &mut Self::Fetch<'w>,
1105
_state: &'s Self::State,
1106
_: &'w Table,
1107
) {
1108
}
1109
1110
fn update_component_access(state: &Self::State, filtered_access: &mut FilteredAccess) {
1111
assert!(
1112
filtered_access.access().is_compatible(state),
1113
"FilteredEntityRef conflicts with a previous access in this query. Exclusive access cannot coincide with any other accesses.",
1114
);
1115
filtered_access.access.extend(state);
1116
}
1117
1118
fn init_state(_world: &mut World) -> Self::State {
1119
Access::default()
1120
}
1121
1122
fn get_state(_components: &Components) -> Option<Self::State> {
1123
Some(Access::default())
1124
}
1125
1126
fn matches_component_set(
1127
_state: &Self::State,
1128
_set_contains_id: &impl Fn(ComponentId) -> bool,
1129
) -> bool {
1130
true
1131
}
1132
}
1133
1134
// SAFETY: `Self` is the same as `Self::ReadOnly`
1135
unsafe impl<'a, 'b> QueryData for FilteredEntityRef<'a, 'b> {
1136
const IS_READ_ONLY: bool = true;
1137
const IS_ARCHETYPAL: bool = true;
1138
type ReadOnly = Self;
1139
type Item<'w, 's> = FilteredEntityRef<'w, 's>;
1140
1141
fn shrink<'wlong: 'wshort, 'wshort, 's>(
1142
item: Self::Item<'wlong, 's>,
1143
) -> Self::Item<'wshort, 's> {
1144
item
1145
}
1146
1147
#[inline]
1148
fn provide_extra_access(
1149
state: &mut Self::State,
1150
access: &mut Access,
1151
available_access: &Access,
1152
) {
1153
// Claim any extra access that doesn't conflict with other subqueries
1154
// This is used when constructing a `QueryLens` or creating a query from a `QueryBuilder`
1155
// Start with the entire available access, since that is the most we can possibly access
1156
state.clone_from(available_access);
1157
// Prevent all writes, since `FilteredEntityRef` only performs read access
1158
state.clear_writes();
1159
// Prevent any access that would conflict with other accesses in the current query
1160
state.remove_conflicting_access(access);
1161
// Finally, add the resulting access to the query access
1162
// to make sure a later `FilteredEntityMut` won't conflict with this.
1163
access.extend(state);
1164
}
1165
1166
#[inline(always)]
1167
unsafe fn fetch<'w, 's>(
1168
access: &'s Self::State,
1169
fetch: &mut Self::Fetch<'w>,
1170
entity: Entity,
1171
_table_row: TableRow,
1172
) -> Option<Self::Item<'w, 's>> {
1173
// SAFETY: `fetch` must be called with an entity that exists in the world
1174
let cell = unsafe {
1175
fetch
1176
.world
1177
.get_entity_with_ticks(entity, fetch.last_run, fetch.this_run)
1178
.debug_checked_unwrap()
1179
};
1180
// SAFETY: mutable access to every component has been registered.
1181
Some(unsafe { FilteredEntityRef::new(cell, access) })
1182
}
1183
1184
fn iter_access(state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
1185
iter::once(EcsAccessType::Access(state))
1186
}
1187
}
1188
1189
// SAFETY: Access is read-only.
1190
unsafe impl ReadOnlyQueryData for FilteredEntityRef<'_, '_> {}
1191
1192
impl ArchetypeQueryData for FilteredEntityRef<'_, '_> {}
1193
1194
// SAFETY: The accesses of `Self::ReadOnly` are a subset of the accesses of `Self`
1195
unsafe impl WorldQuery for FilteredEntityMut<'_, '_> {
1196
type Fetch<'w> = EntityFetch<'w>;
1197
type State = Access;
1198
1199
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
1200
fetch
1201
}
1202
1203
const IS_DENSE: bool = true;
1204
1205
unsafe fn init_fetch<'w, 's>(
1206
world: UnsafeWorldCell<'w>,
1207
_state: &'s Self::State,
1208
last_run: Tick,
1209
this_run: Tick,
1210
) -> Self::Fetch<'w> {
1211
EntityFetch {
1212
world,
1213
last_run,
1214
this_run,
1215
}
1216
}
1217
1218
#[inline]
1219
unsafe fn set_archetype<'w, 's>(
1220
_fetch: &mut Self::Fetch<'w>,
1221
_state: &'s Self::State,
1222
_: &'w Archetype,
1223
_table: &Table,
1224
) {
1225
}
1226
1227
#[inline]
1228
unsafe fn set_table<'w, 's>(
1229
_fetch: &mut Self::Fetch<'w>,
1230
_state: &'s Self::State,
1231
_: &'w Table,
1232
) {
1233
}
1234
1235
fn update_component_access(state: &Self::State, filtered_access: &mut FilteredAccess) {
1236
assert!(
1237
filtered_access.access().is_compatible(state),
1238
"FilteredEntityMut conflicts with a previous access in this query. Exclusive access cannot coincide with any other accesses.",
1239
);
1240
filtered_access.access.extend(state);
1241
}
1242
1243
fn init_state(_world: &mut World) -> Self::State {
1244
Access::default()
1245
}
1246
1247
fn get_state(_components: &Components) -> Option<Self::State> {
1248
Some(Access::default())
1249
}
1250
1251
fn matches_component_set(
1252
_state: &Self::State,
1253
_set_contains_id: &impl Fn(ComponentId) -> bool,
1254
) -> bool {
1255
true
1256
}
1257
}
1258
1259
// SAFETY: access of `FilteredEntityRef` is a subset of `FilteredEntityMut`
1260
unsafe impl<'a, 'b> QueryData for FilteredEntityMut<'a, 'b> {
1261
const IS_READ_ONLY: bool = false;
1262
const IS_ARCHETYPAL: bool = true;
1263
type ReadOnly = FilteredEntityRef<'a, 'b>;
1264
type Item<'w, 's> = FilteredEntityMut<'w, 's>;
1265
1266
fn shrink<'wlong: 'wshort, 'wshort, 's>(
1267
item: Self::Item<'wlong, 's>,
1268
) -> Self::Item<'wshort, 's> {
1269
item
1270
}
1271
1272
#[inline]
1273
fn provide_extra_access(
1274
state: &mut Self::State,
1275
access: &mut Access,
1276
available_access: &Access,
1277
) {
1278
// Claim any extra access that doesn't conflict with other subqueries
1279
// This is used when constructing a `QueryLens` or creating a query from a `QueryBuilder`
1280
// Start with the entire available access, since that is the most we can possibly access
1281
state.clone_from(available_access);
1282
// Prevent any access that would conflict with other accesses in the current query
1283
state.remove_conflicting_access(access);
1284
// Finally, add the resulting access to the query access
1285
// to make sure a later `FilteredEntityRef` or `FilteredEntityMut` won't conflict with this.
1286
access.extend(state);
1287
}
1288
1289
#[inline(always)]
1290
unsafe fn fetch<'w, 's>(
1291
access: &'s Self::State,
1292
fetch: &mut Self::Fetch<'w>,
1293
entity: Entity,
1294
_table_row: TableRow,
1295
) -> Option<Self::Item<'w, 's>> {
1296
// SAFETY: `fetch` must be called with an entity that exists in the world
1297
let cell = unsafe {
1298
fetch
1299
.world
1300
.get_entity_with_ticks(entity, fetch.last_run, fetch.this_run)
1301
.debug_checked_unwrap()
1302
};
1303
// SAFETY: mutable access to every component has been registered.
1304
Some(unsafe { FilteredEntityMut::new(cell, access) })
1305
}
1306
1307
fn iter_access(state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
1308
iter::once(EcsAccessType::Access(state))
1309
}
1310
}
1311
1312
impl ArchetypeQueryData for FilteredEntityMut<'_, '_> {}
1313
1314
// SAFETY: `EntityRefExcept` guards access to all components in the bundle `B`
1315
// and populates `Access` values so that queries that conflict with this access
1316
// are rejected.
1317
unsafe impl<'a, 'b, B> WorldQuery for EntityRefExcept<'a, 'b, B>
1318
where
1319
B: Bundle,
1320
{
1321
type Fetch<'w> = EntityFetch<'w>;
1322
type State = Access;
1323
1324
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
1325
fetch
1326
}
1327
1328
unsafe fn init_fetch<'w, 's>(
1329
world: UnsafeWorldCell<'w>,
1330
_: &'s Self::State,
1331
last_run: Tick,
1332
this_run: Tick,
1333
) -> Self::Fetch<'w> {
1334
EntityFetch {
1335
world,
1336
last_run,
1337
this_run,
1338
}
1339
}
1340
1341
const IS_DENSE: bool = true;
1342
1343
unsafe fn set_archetype<'w, 's>(
1344
_: &mut Self::Fetch<'w>,
1345
_: &'s Self::State,
1346
_: &'w Archetype,
1347
_: &'w Table,
1348
) {
1349
}
1350
1351
unsafe fn set_table<'w, 's>(_: &mut Self::Fetch<'w>, _: &'s Self::State, _: &'w Table) {}
1352
1353
fn update_component_access(state: &Self::State, filtered_access: &mut FilteredAccess) {
1354
let access = filtered_access.access_mut();
1355
assert!(
1356
access.is_compatible(state),
1357
"`EntityRefExcept<{}>` conflicts with a previous access in this query.",
1358
DebugName::type_name::<B>(),
1359
);
1360
access.extend(state);
1361
}
1362
1363
fn init_state(world: &mut World) -> Self::State {
1364
let mut access = Access::new();
1365
access.read_all_components();
1366
for id in B::component_ids(&mut world.components_registrator()) {
1367
access.remove_component_read(id);
1368
}
1369
access
1370
}
1371
1372
fn get_state(components: &Components) -> Option<Self::State> {
1373
let mut access = Access::new();
1374
access.read_all_components();
1375
// If the component isn't registered, we don't have a `ComponentId`
1376
// to use to exclude its access.
1377
// Rather than fail, just try to take additional access.
1378
// This is sound because access checks will run on the resulting access.
1379
// Since the component isn't registered, there are no entities with that
1380
// component, and the extra access will usually have no effect.
1381
for id in B::get_component_ids(components).flatten() {
1382
access.remove_component_read(id);
1383
}
1384
Some(access)
1385
}
1386
1387
fn matches_component_set(_: &Self::State, _: &impl Fn(ComponentId) -> bool) -> bool {
1388
true
1389
}
1390
}
1391
1392
// SAFETY: `Self` is the same as `Self::ReadOnly`.
1393
unsafe impl<'a, 'b, B> QueryData for EntityRefExcept<'a, 'b, B>
1394
where
1395
B: Bundle,
1396
{
1397
const IS_READ_ONLY: bool = true;
1398
const IS_ARCHETYPAL: bool = true;
1399
type ReadOnly = Self;
1400
type Item<'w, 's> = EntityRefExcept<'w, 's, B>;
1401
1402
fn shrink<'wlong: 'wshort, 'wshort, 's>(
1403
item: Self::Item<'wlong, 's>,
1404
) -> Self::Item<'wshort, 's> {
1405
item
1406
}
1407
1408
unsafe fn fetch<'w, 's>(
1409
access: &'s Self::State,
1410
fetch: &mut Self::Fetch<'w>,
1411
entity: Entity,
1412
_: TableRow,
1413
) -> Option<Self::Item<'w, 's>> {
1414
let cell = fetch
1415
.world
1416
.get_entity_with_ticks(entity, fetch.last_run, fetch.this_run)
1417
.unwrap();
1418
Some(EntityRefExcept::new(cell, access))
1419
}
1420
1421
fn iter_access(state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
1422
iter::once(EcsAccessType::Access(state))
1423
}
1424
}
1425
1426
// SAFETY: `EntityRefExcept` enforces read-only access to its contained
1427
// components.
1428
unsafe impl<B> ReadOnlyQueryData for EntityRefExcept<'_, '_, B> where B: Bundle {}
1429
1430
impl<B: Bundle> ArchetypeQueryData for EntityRefExcept<'_, '_, B> {}
1431
1432
// SAFETY: `EntityMutExcept` guards access to all components in the bundle `B`
1433
// and populates `Access` values so that queries that conflict with this access
1434
// are rejected.
1435
unsafe impl<'a, 'b, B> WorldQuery for EntityMutExcept<'a, 'b, B>
1436
where
1437
B: Bundle,
1438
{
1439
type Fetch<'w> = EntityFetch<'w>;
1440
type State = Access;
1441
1442
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
1443
fetch
1444
}
1445
1446
unsafe fn init_fetch<'w, 's>(
1447
world: UnsafeWorldCell<'w>,
1448
_: &'s Self::State,
1449
last_run: Tick,
1450
this_run: Tick,
1451
) -> Self::Fetch<'w> {
1452
EntityFetch {
1453
world,
1454
last_run,
1455
this_run,
1456
}
1457
}
1458
1459
const IS_DENSE: bool = true;
1460
1461
unsafe fn set_archetype<'w, 's>(
1462
_: &mut Self::Fetch<'w>,
1463
_: &'s Self::State,
1464
_: &'w Archetype,
1465
_: &'w Table,
1466
) {
1467
}
1468
1469
unsafe fn set_table<'w, 's>(_: &mut Self::Fetch<'w>, _: &'s Self::State, _: &'w Table) {}
1470
1471
fn update_component_access(state: &Self::State, filtered_access: &mut FilteredAccess) {
1472
let access = filtered_access.access_mut();
1473
assert!(
1474
access.is_compatible(state),
1475
"`EntityMutExcept<{}>` conflicts with a previous access in this query.",
1476
DebugName::type_name::<B>()
1477
);
1478
access.extend(state);
1479
}
1480
1481
fn init_state(world: &mut World) -> Self::State {
1482
let mut access = Access::new();
1483
access.write_all_components();
1484
for id in B::component_ids(&mut world.components_registrator()) {
1485
access.remove_component_read(id);
1486
}
1487
access
1488
}
1489
1490
fn get_state(components: &Components) -> Option<Self::State> {
1491
let mut access = Access::new();
1492
access.write_all_components();
1493
// If the component isn't registered, we don't have a `ComponentId`
1494
// to use to exclude its access.
1495
// Rather than fail, just try to take additional access.
1496
// This is sound because access checks will run on the resulting access.
1497
// Since the component isn't registered, there are no entities with that
1498
// component, and the extra access will usually have no effect.
1499
for id in B::get_component_ids(components).flatten() {
1500
access.remove_component_read(id);
1501
}
1502
Some(access)
1503
}
1504
1505
fn matches_component_set(_: &Self::State, _: &impl Fn(ComponentId) -> bool) -> bool {
1506
true
1507
}
1508
}
1509
1510
// SAFETY: All accesses that `EntityRefExcept` provides are also accesses that
1511
// `EntityMutExcept` provides.
1512
unsafe impl<'a, 'b, B> QueryData for EntityMutExcept<'a, 'b, B>
1513
where
1514
B: Bundle,
1515
{
1516
const IS_READ_ONLY: bool = false;
1517
const IS_ARCHETYPAL: bool = true;
1518
type ReadOnly = EntityRefExcept<'a, 'b, B>;
1519
type Item<'w, 's> = EntityMutExcept<'w, 's, B>;
1520
1521
fn shrink<'wlong: 'wshort, 'wshort, 's>(
1522
item: Self::Item<'wlong, 's>,
1523
) -> Self::Item<'wshort, 's> {
1524
item
1525
}
1526
1527
unsafe fn fetch<'w, 's>(
1528
access: &'s Self::State,
1529
fetch: &mut Self::Fetch<'w>,
1530
entity: Entity,
1531
_: TableRow,
1532
) -> Option<Self::Item<'w, 's>> {
1533
let cell = fetch
1534
.world
1535
.get_entity_with_ticks(entity, fetch.last_run, fetch.this_run)
1536
.unwrap();
1537
Some(EntityMutExcept::new(cell, access))
1538
}
1539
1540
fn iter_access(state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
1541
iter::once(EcsAccessType::Access(state))
1542
}
1543
}
1544
1545
impl<B: Bundle> ArchetypeQueryData for EntityMutExcept<'_, '_, B> {}
1546
1547
// SAFETY:
1548
// `update_component_access` does nothing.
1549
// This is sound because `fetch` does not access components.
1550
unsafe impl WorldQuery for &Archetype {
1551
type Fetch<'w> = (&'w Entities, &'w Archetypes);
1552
type State = ();
1553
1554
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
1555
fetch
1556
}
1557
1558
unsafe fn init_fetch<'w, 's>(
1559
world: UnsafeWorldCell<'w>,
1560
_state: &'s Self::State,
1561
_last_run: Tick,
1562
_this_run: Tick,
1563
) -> Self::Fetch<'w> {
1564
(world.entities(), world.archetypes())
1565
}
1566
1567
// This could probably be a non-dense query and just set a Option<&Archetype> fetch value in
1568
// set_archetypes, but forcing archetypal iteration is likely to be slower in any compound query.
1569
const IS_DENSE: bool = true;
1570
1571
#[inline]
1572
unsafe fn set_archetype<'w, 's>(
1573
_fetch: &mut Self::Fetch<'w>,
1574
_state: &'s Self::State,
1575
_archetype: &'w Archetype,
1576
_table: &Table,
1577
) {
1578
}
1579
1580
#[inline]
1581
unsafe fn set_table<'w, 's>(
1582
_fetch: &mut Self::Fetch<'w>,
1583
_state: &'s Self::State,
1584
_table: &'w Table,
1585
) {
1586
}
1587
1588
fn update_component_access(_state: &Self::State, _access: &mut FilteredAccess) {}
1589
1590
fn init_state(_world: &mut World) {}
1591
1592
fn get_state(_components: &Components) -> Option<()> {
1593
Some(())
1594
}
1595
1596
fn matches_component_set(
1597
_state: &Self::State,
1598
_set_contains_id: &impl Fn(ComponentId) -> bool,
1599
) -> bool {
1600
true
1601
}
1602
}
1603
1604
// SAFETY: `Self` is the same as `Self::ReadOnly`
1605
unsafe impl QueryData for &Archetype {
1606
const IS_READ_ONLY: bool = true;
1607
const IS_ARCHETYPAL: bool = true;
1608
type ReadOnly = Self;
1609
type Item<'w, 's> = &'w Archetype;
1610
1611
fn shrink<'wlong: 'wshort, 'wshort, 's>(
1612
item: Self::Item<'wlong, 's>,
1613
) -> Self::Item<'wshort, 's> {
1614
item
1615
}
1616
1617
#[inline(always)]
1618
unsafe fn fetch<'w, 's>(
1619
_state: &'s Self::State,
1620
fetch: &mut Self::Fetch<'w>,
1621
entity: Entity,
1622
_table_row: TableRow,
1623
) -> Option<Self::Item<'w, 's>> {
1624
let (entities, archetypes) = *fetch;
1625
// SAFETY: `fetch` must be called with an entity that exists in the world
1626
let location = unsafe { entities.get_spawned(entity).debug_checked_unwrap() };
1627
// SAFETY: The assigned archetype for a living entity must always be valid.
1628
Some(unsafe { archetypes.get(location.archetype_id).debug_checked_unwrap() })
1629
}
1630
1631
fn iter_access(_state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
1632
iter::empty()
1633
}
1634
}
1635
1636
// SAFETY: access is read only
1637
unsafe impl ReadOnlyQueryData for &Archetype {}
1638
1639
impl ReleaseStateQueryData for &Archetype {
1640
fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
1641
item
1642
}
1643
}
1644
1645
impl ArchetypeQueryData for &Archetype {}
1646
1647
/// The [`WorldQuery::Fetch`] type for `& T`.
1648
pub struct ReadFetch<'w, T: Component> {
1649
components: StorageSwitch<
1650
T,
1651
// T::STORAGE_TYPE = StorageType::Table
1652
Option<ThinSlicePtr<'w, UnsafeCell<T>>>,
1653
// T::STORAGE_TYPE = StorageType::SparseSet
1654
Option<&'w ComponentSparseSet>,
1655
>,
1656
}
1657
1658
impl<T: Component> Clone for ReadFetch<'_, T> {
1659
fn clone(&self) -> Self {
1660
*self
1661
}
1662
}
1663
1664
impl<T: Component> Copy for ReadFetch<'_, T> {}
1665
1666
// SAFETY:
1667
// `fetch` accesses a single component in a readonly way.
1668
// This is sound because `update_component_access` adds read access for that component and panic when appropriate.
1669
// `update_component_access` adds a `With` filter for a component.
1670
// This is sound because `matches_component_set` returns whether the set contains that component.
1671
unsafe impl<T: Component> WorldQuery for &T {
1672
type Fetch<'w> = ReadFetch<'w, T>;
1673
type State = ComponentId;
1674
1675
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
1676
fetch
1677
}
1678
1679
#[inline]
1680
unsafe fn init_fetch<'w, 's>(
1681
world: UnsafeWorldCell<'w>,
1682
&component_id: &ComponentId,
1683
_last_run: Tick,
1684
_this_run: Tick,
1685
) -> ReadFetch<'w, T> {
1686
ReadFetch {
1687
components: StorageSwitch::new(
1688
|| None,
1689
|| {
1690
// SAFETY: The underlying type associated with `component_id` is `T`,
1691
// which we are allowed to access since we registered it in `update_component_access`.
1692
// Note that we do not actually access any components in this function, we just get a shared
1693
// reference to the sparse set, which is used to access the components in `Self::fetch`.
1694
unsafe { world.storages().sparse_sets.get(component_id) }
1695
},
1696
),
1697
}
1698
}
1699
1700
const IS_DENSE: bool = {
1701
match T::STORAGE_TYPE {
1702
StorageType::Table => true,
1703
StorageType::SparseSet => false,
1704
}
1705
};
1706
1707
#[inline]
1708
unsafe fn set_archetype<'w>(
1709
fetch: &mut ReadFetch<'w, T>,
1710
component_id: &ComponentId,
1711
_archetype: &'w Archetype,
1712
table: &'w Table,
1713
) {
1714
if Self::IS_DENSE {
1715
// SAFETY: `set_archetype`'s safety rules are a super set of the `set_table`'s ones.
1716
unsafe {
1717
Self::set_table(fetch, component_id, table);
1718
}
1719
}
1720
}
1721
1722
#[inline]
1723
unsafe fn set_table<'w>(
1724
fetch: &mut ReadFetch<'w, T>,
1725
&component_id: &ComponentId,
1726
table: &'w Table,
1727
) {
1728
let table_data = Some(
1729
table
1730
.get_data_slice_for(component_id)
1731
.debug_checked_unwrap()
1732
.into(),
1733
);
1734
// SAFETY: set_table is only called when T::STORAGE_TYPE = StorageType::Table
1735
unsafe { fetch.components.set_table(table_data) };
1736
}
1737
1738
fn update_component_access(&component_id: &ComponentId, access: &mut FilteredAccess) {
1739
assert!(
1740
!access.access().has_component_write(component_id),
1741
"&{} conflicts with a previous access in this query. Shared access cannot coincide with exclusive access.",
1742
DebugName::type_name::<T>(),
1743
);
1744
access.add_component_read(component_id);
1745
}
1746
1747
fn init_state(world: &mut World) -> ComponentId {
1748
world.register_component::<T>()
1749
}
1750
1751
fn get_state(components: &Components) -> Option<Self::State> {
1752
components.component_id::<T>()
1753
}
1754
1755
fn matches_component_set(
1756
&state: &ComponentId,
1757
set_contains_id: &impl Fn(ComponentId) -> bool,
1758
) -> bool {
1759
set_contains_id(state)
1760
}
1761
}
1762
1763
// SAFETY: `Self` is the same as `Self::ReadOnly`
1764
unsafe impl<T: Component> QueryData for &T {
1765
const IS_READ_ONLY: bool = true;
1766
const IS_ARCHETYPAL: bool = true;
1767
type ReadOnly = Self;
1768
type Item<'w, 's> = &'w T;
1769
1770
fn shrink<'wlong: 'wshort, 'wshort, 's>(
1771
item: Self::Item<'wlong, 's>,
1772
) -> Self::Item<'wshort, 's> {
1773
item
1774
}
1775
1776
#[inline(always)]
1777
unsafe fn fetch<'w, 's>(
1778
_state: &'s Self::State,
1779
fetch: &mut Self::Fetch<'w>,
1780
entity: Entity,
1781
table_row: TableRow,
1782
) -> Option<Self::Item<'w, 's>> {
1783
Some(fetch.components.extract(
1784
|table| {
1785
// SAFETY: set_table was previously called
1786
let table = unsafe { table.debug_checked_unwrap() };
1787
// SAFETY: Caller ensures `table_row` is in range.
1788
let item = unsafe { table.get_unchecked(table_row.index()) };
1789
item.deref()
1790
},
1791
|sparse_set| {
1792
// SAFETY: Caller ensures `entity` is in range.
1793
let item = unsafe {
1794
sparse_set
1795
.debug_checked_unwrap()
1796
.get(entity)
1797
.debug_checked_unwrap()
1798
};
1799
item.deref()
1800
},
1801
))
1802
}
1803
1804
fn iter_access(state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
1805
iter::once(EcsAccessType::Component(EcsAccessLevel::Read(*state)))
1806
}
1807
}
1808
1809
impl<T: Component> ContiguousQueryData for &T {
1810
type Contiguous<'w, 's> = &'w [T];
1811
1812
unsafe fn fetch_contiguous<'w, 's>(
1813
_state: &'s Self::State,
1814
fetch: &mut Self::Fetch<'w>,
1815
entities: &'w [Entity],
1816
) -> Self::Contiguous<'w, 's> {
1817
fetch.components.extract(
1818
|table| {
1819
// SAFETY: The caller ensures `set_table` was previously called
1820
let table = unsafe { table.debug_checked_unwrap() };
1821
// SAFETY:
1822
// - `table` is `entities.len()` long
1823
// - `UnsafeCell<T>` has the same layout as `T`
1824
unsafe { table.cast().as_slice_unchecked(entities.len()) }
1825
},
1826
|_| {
1827
#[cfg(debug_assertions)]
1828
unreachable!();
1829
// SAFETY: The caller ensures query is dense
1830
#[cfg(not(debug_assertions))]
1831
core::hint::unreachable_unchecked();
1832
},
1833
)
1834
}
1835
}
1836
1837
// SAFETY: access is read only
1838
unsafe impl<T: Component> ReadOnlyQueryData for &T {}
1839
1840
impl<T: Component> ReleaseStateQueryData for &T {
1841
fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
1842
item
1843
}
1844
}
1845
1846
impl<T: Component> ArchetypeQueryData for &T {}
1847
1848
#[doc(hidden)]
1849
pub struct RefFetch<'w, T: Component> {
1850
components: StorageSwitch<
1851
T,
1852
// T::STORAGE_TYPE = StorageType::Table
1853
Option<(
1854
ThinSlicePtr<'w, UnsafeCell<T>>,
1855
ThinSlicePtr<'w, UnsafeCell<Tick>>,
1856
ThinSlicePtr<'w, UnsafeCell<Tick>>,
1857
MaybeLocation<ThinSlicePtr<'w, UnsafeCell<&'static Location<'static>>>>,
1858
)>,
1859
// T::STORAGE_TYPE = StorageType::SparseSet
1860
// Can be `None` when the component has never been inserted
1861
Option<&'w ComponentSparseSet>,
1862
>,
1863
last_run: Tick,
1864
this_run: Tick,
1865
}
1866
1867
impl<T: Component> Clone for RefFetch<'_, T> {
1868
fn clone(&self) -> Self {
1869
*self
1870
}
1871
}
1872
1873
impl<T: Component> Copy for RefFetch<'_, T> {}
1874
1875
// SAFETY:
1876
// `fetch` accesses a single component in a readonly way.
1877
// This is sound because `update_component_access` adds read access for that component and panic when appropriate.
1878
// `update_component_access` adds a `With` filter for a component.
1879
// This is sound because `matches_component_set` returns whether the set contains that component.
1880
unsafe impl<'__w, T: Component> WorldQuery for Ref<'__w, T> {
1881
type Fetch<'w> = RefFetch<'w, T>;
1882
type State = ComponentId;
1883
1884
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
1885
fetch
1886
}
1887
1888
#[inline]
1889
unsafe fn init_fetch<'w, 's>(
1890
world: UnsafeWorldCell<'w>,
1891
&component_id: &ComponentId,
1892
last_run: Tick,
1893
this_run: Tick,
1894
) -> RefFetch<'w, T> {
1895
RefFetch {
1896
components: StorageSwitch::new(
1897
|| None,
1898
|| {
1899
// SAFETY: The underlying type associated with `component_id` is `T`,
1900
// which we are allowed to access since we registered it in `update_component_access`.
1901
// Note that we do not actually access any components in this function, we just get a shared
1902
// reference to the sparse set, which is used to access the components in `Self::fetch`.
1903
unsafe { world.storages().sparse_sets.get(component_id) }
1904
},
1905
),
1906
last_run,
1907
this_run,
1908
}
1909
}
1910
1911
const IS_DENSE: bool = {
1912
match T::STORAGE_TYPE {
1913
StorageType::Table => true,
1914
StorageType::SparseSet => false,
1915
}
1916
};
1917
1918
#[inline]
1919
unsafe fn set_archetype<'w>(
1920
fetch: &mut RefFetch<'w, T>,
1921
component_id: &ComponentId,
1922
_archetype: &'w Archetype,
1923
table: &'w Table,
1924
) {
1925
if Self::IS_DENSE {
1926
// SAFETY: `set_archetype`'s safety rules are a super set of the `set_table`'s ones.
1927
unsafe {
1928
Self::set_table(fetch, component_id, table);
1929
}
1930
}
1931
}
1932
1933
#[inline]
1934
unsafe fn set_table<'w>(
1935
fetch: &mut RefFetch<'w, T>,
1936
&component_id: &ComponentId,
1937
table: &'w Table,
1938
) {
1939
let column = table.get_column(component_id).debug_checked_unwrap();
1940
let table_data = Some((
1941
column.get_data_slice(table.entity_count() as usize).into(),
1942
column
1943
.get_added_ticks_slice(table.entity_count() as usize)
1944
.into(),
1945
column
1946
.get_changed_ticks_slice(table.entity_count() as usize)
1947
.into(),
1948
column
1949
.get_changed_by_slice(table.entity_count() as usize)
1950
.map(Into::into),
1951
));
1952
// SAFETY: set_table is only called when T::STORAGE_TYPE = StorageType::Table
1953
unsafe { fetch.components.set_table(table_data) };
1954
}
1955
1956
fn update_component_access(&component_id: &ComponentId, access: &mut FilteredAccess) {
1957
assert!(
1958
!access.access().has_component_write(component_id),
1959
"&{} conflicts with a previous access in this query. Shared access cannot coincide with exclusive access.",
1960
DebugName::type_name::<T>(),
1961
);
1962
access.add_component_read(component_id);
1963
}
1964
1965
fn init_state(world: &mut World) -> ComponentId {
1966
world.register_component::<T>()
1967
}
1968
1969
fn get_state(components: &Components) -> Option<Self::State> {
1970
components.component_id::<T>()
1971
}
1972
1973
fn matches_component_set(
1974
&state: &ComponentId,
1975
set_contains_id: &impl Fn(ComponentId) -> bool,
1976
) -> bool {
1977
set_contains_id(state)
1978
}
1979
}
1980
1981
// SAFETY: `Self` is the same as `Self::ReadOnly`
1982
unsafe impl<'__w, T: Component> QueryData for Ref<'__w, T> {
1983
const IS_READ_ONLY: bool = true;
1984
const IS_ARCHETYPAL: bool = true;
1985
type ReadOnly = Self;
1986
type Item<'w, 's> = Ref<'w, T>;
1987
1988
fn shrink<'wlong: 'wshort, 'wshort, 's>(
1989
item: Self::Item<'wlong, 's>,
1990
) -> Self::Item<'wshort, 's> {
1991
item
1992
}
1993
1994
#[inline(always)]
1995
unsafe fn fetch<'w, 's>(
1996
_state: &'s Self::State,
1997
fetch: &mut Self::Fetch<'w>,
1998
entity: Entity,
1999
table_row: TableRow,
2000
) -> Option<Self::Item<'w, 's>> {
2001
Some(fetch.components.extract(
2002
|table| {
2003
// SAFETY: set_table was previously called
2004
let (table_components, added_ticks, changed_ticks, callers) =
2005
unsafe { table.debug_checked_unwrap() };
2006
2007
// SAFETY: The caller ensures `table_row` is in range.
2008
let component = unsafe { table_components.get_unchecked(table_row.index()) };
2009
// SAFETY: The caller ensures `table_row` is in range.
2010
let added = unsafe { added_ticks.get_unchecked(table_row.index()) };
2011
// SAFETY: The caller ensures `table_row` is in range.
2012
let changed = unsafe { changed_ticks.get_unchecked(table_row.index()) };
2013
// SAFETY: The caller ensures `table_row` is in range.
2014
let caller =
2015
callers.map(|callers| unsafe { callers.get_unchecked(table_row.index()) });
2016
2017
Ref {
2018
value: component.deref(),
2019
ticks: ComponentTicksRef {
2020
added: added.deref(),
2021
changed: changed.deref(),
2022
changed_by: caller.map(|caller| caller.deref()),
2023
this_run: fetch.this_run,
2024
last_run: fetch.last_run,
2025
},
2026
}
2027
},
2028
|sparse_set| {
2029
// SAFETY: The caller ensures `entity` is in range and has the component.
2030
let (component, ticks) = unsafe {
2031
sparse_set
2032
.debug_checked_unwrap()
2033
.get_with_ticks(entity)
2034
.debug_checked_unwrap()
2035
};
2036
2037
Ref {
2038
value: component.deref(),
2039
ticks: ComponentTicksRef::from_tick_cells(
2040
ticks,
2041
fetch.last_run,
2042
fetch.this_run,
2043
),
2044
}
2045
},
2046
))
2047
}
2048
2049
fn iter_access(state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
2050
iter::once(EcsAccessType::Component(EcsAccessLevel::Read(*state)))
2051
}
2052
}
2053
2054
// SAFETY: access is read only
2055
unsafe impl<'__w, T: Component> ReadOnlyQueryData for Ref<'__w, T> {}
2056
2057
impl<T: Component> ReleaseStateQueryData for Ref<'_, T> {
2058
fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
2059
item
2060
}
2061
}
2062
2063
impl<T: Component> ArchetypeQueryData for Ref<'_, T> {}
2064
2065
impl<T: Component> ContiguousQueryData for Ref<'_, T> {
2066
type Contiguous<'w, 's> = ContiguousRef<'w, T>;
2067
2068
unsafe fn fetch_contiguous<'w, 's>(
2069
_state: &'s Self::State,
2070
fetch: &mut Self::Fetch<'w>,
2071
entities: &'w [Entity],
2072
) -> Self::Contiguous<'w, 's> {
2073
fetch.components.extract(
2074
|table| {
2075
// SAFETY: set_table was previously called
2076
let (table_components, added_ticks, changed_ticks, callers) =
2077
unsafe { table.debug_checked_unwrap() };
2078
2079
ContiguousRef {
2080
// SAFETY: `entities` has the same length as the rows in the set table.
2081
value: unsafe { table_components.cast().as_slice_unchecked(entities.len()) },
2082
// SAFETY:
2083
// - The caller ensures the permission to access ticks.
2084
// - `entities` has the same length as the rows in the set table hence the
2085
// ticks.
2086
ticks: unsafe {
2087
ContiguousComponentTicksRef::from_slice_ptrs(
2088
added_ticks,
2089
changed_ticks,
2090
callers,
2091
entities.len(),
2092
fetch.this_run,
2093
fetch.last_run,
2094
)
2095
},
2096
}
2097
},
2098
|_| {
2099
#[cfg(debug_assertions)]
2100
unreachable!();
2101
// SAFETY: the caller ensures that [`Self::set_table`] was called beforehand.
2102
#[cfg(not(debug_assertions))]
2103
core::hint::unreachable_unchecked();
2104
},
2105
)
2106
}
2107
}
2108
2109
/// The [`WorldQuery::Fetch`] type for `&mut T`.
2110
pub struct WriteFetch<'w, T: Component> {
2111
components: StorageSwitch<
2112
T,
2113
// T::STORAGE_TYPE = StorageType::Table
2114
Option<(
2115
ThinSlicePtr<'w, UnsafeCell<T>>,
2116
ThinSlicePtr<'w, UnsafeCell<Tick>>,
2117
ThinSlicePtr<'w, UnsafeCell<Tick>>,
2118
MaybeLocation<ThinSlicePtr<'w, UnsafeCell<&'static Location<'static>>>>,
2119
)>,
2120
// T::STORAGE_TYPE = StorageType::SparseSet
2121
// Can be `None` when the component has never been inserted
2122
Option<&'w ComponentSparseSet>,
2123
>,
2124
last_run: Tick,
2125
this_run: Tick,
2126
}
2127
2128
impl<T: Component> Clone for WriteFetch<'_, T> {
2129
fn clone(&self) -> Self {
2130
*self
2131
}
2132
}
2133
2134
impl<T: Component> Copy for WriteFetch<'_, T> {}
2135
2136
// SAFETY:
2137
// `fetch` accesses a single component mutably.
2138
// This is sound because `update_component_access` adds write access for that component and panic when appropriate.
2139
// `update_component_access` adds a `With` filter for a component.
2140
// This is sound because `matches_component_set` returns whether the set contains that component.
2141
unsafe impl<'__w, T: Component> WorldQuery for &'__w mut T {
2142
type Fetch<'w> = WriteFetch<'w, T>;
2143
type State = ComponentId;
2144
2145
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
2146
fetch
2147
}
2148
2149
#[inline]
2150
unsafe fn init_fetch<'w, 's>(
2151
world: UnsafeWorldCell<'w>,
2152
&component_id: &ComponentId,
2153
last_run: Tick,
2154
this_run: Tick,
2155
) -> WriteFetch<'w, T> {
2156
WriteFetch {
2157
components: StorageSwitch::new(
2158
|| None,
2159
|| {
2160
// SAFETY: The underlying type associated with `component_id` is `T`,
2161
// which we are allowed to access since we registered it in `update_component_access`.
2162
// Note that we do not actually access any components in this function, we just get a shared
2163
// reference to the sparse set, which is used to access the components in `Self::fetch`.
2164
unsafe { world.storages().sparse_sets.get(component_id) }
2165
},
2166
),
2167
last_run,
2168
this_run,
2169
}
2170
}
2171
2172
const IS_DENSE: bool = {
2173
match T::STORAGE_TYPE {
2174
StorageType::Table => true,
2175
StorageType::SparseSet => false,
2176
}
2177
};
2178
2179
#[inline]
2180
unsafe fn set_archetype<'w>(
2181
fetch: &mut WriteFetch<'w, T>,
2182
component_id: &ComponentId,
2183
_archetype: &'w Archetype,
2184
table: &'w Table,
2185
) {
2186
if Self::IS_DENSE {
2187
// SAFETY: `set_archetype`'s safety rules are a super set of the `set_table`'s ones.
2188
unsafe {
2189
Self::set_table(fetch, component_id, table);
2190
}
2191
}
2192
}
2193
2194
#[inline]
2195
unsafe fn set_table<'w>(
2196
fetch: &mut WriteFetch<'w, T>,
2197
&component_id: &ComponentId,
2198
table: &'w Table,
2199
) {
2200
let column = table.get_column(component_id).debug_checked_unwrap();
2201
let table_data = Some((
2202
column.get_data_slice(table.entity_count() as usize).into(),
2203
column
2204
.get_added_ticks_slice(table.entity_count() as usize)
2205
.into(),
2206
column
2207
.get_changed_ticks_slice(table.entity_count() as usize)
2208
.into(),
2209
column
2210
.get_changed_by_slice(table.entity_count() as usize)
2211
.map(Into::into),
2212
));
2213
// SAFETY: set_table is only called when T::STORAGE_TYPE = StorageType::Table
2214
unsafe { fetch.components.set_table(table_data) };
2215
}
2216
2217
fn update_component_access(&component_id: &ComponentId, access: &mut FilteredAccess) {
2218
assert!(
2219
!access.access().has_component_read(component_id),
2220
"&mut {} conflicts with a previous access in this query. Mutable component access must be unique.",
2221
DebugName::type_name::<T>(),
2222
);
2223
access.add_component_write(component_id);
2224
}
2225
2226
fn init_state(world: &mut World) -> ComponentId {
2227
world.register_component::<T>()
2228
}
2229
2230
fn get_state(components: &Components) -> Option<Self::State> {
2231
components.component_id::<T>()
2232
}
2233
2234
fn matches_component_set(
2235
&state: &ComponentId,
2236
set_contains_id: &impl Fn(ComponentId) -> bool,
2237
) -> bool {
2238
set_contains_id(state)
2239
}
2240
}
2241
2242
// SAFETY: access of `&T` is a subset of `&mut T`
2243
unsafe impl<'__w, T: Component<Mutability = Mutable>> QueryData for &'__w mut T {
2244
const IS_READ_ONLY: bool = false;
2245
const IS_ARCHETYPAL: bool = true;
2246
type ReadOnly = &'__w T;
2247
type Item<'w, 's> = Mut<'w, T>;
2248
2249
fn shrink<'wlong: 'wshort, 'wshort, 's>(
2250
item: Self::Item<'wlong, 's>,
2251
) -> Self::Item<'wshort, 's> {
2252
item
2253
}
2254
2255
#[inline(always)]
2256
unsafe fn fetch<'w, 's>(
2257
_state: &'s Self::State,
2258
fetch: &mut Self::Fetch<'w>,
2259
entity: Entity,
2260
table_row: TableRow,
2261
) -> Option<Self::Item<'w, 's>> {
2262
Some(fetch.components.extract(
2263
|table| {
2264
// SAFETY: set_table was previously called
2265
let (table_components, added_ticks, changed_ticks, callers) =
2266
unsafe { table.debug_checked_unwrap() };
2267
2268
// SAFETY: The caller ensures `table_row` is in range.
2269
let component = unsafe { table_components.get_unchecked(table_row.index()) };
2270
// SAFETY: The caller ensures `table_row` is in range.
2271
let added = unsafe { added_ticks.get_unchecked(table_row.index()) };
2272
// SAFETY: The caller ensures `table_row` is in range.
2273
let changed = unsafe { changed_ticks.get_unchecked(table_row.index()) };
2274
// SAFETY: The caller ensures `table_row` is in range.
2275
let caller =
2276
callers.map(|callers| unsafe { callers.get_unchecked(table_row.index()) });
2277
2278
Mut {
2279
value: component.deref_mut(),
2280
ticks: ComponentTicksMut {
2281
added: added.deref_mut(),
2282
changed: changed.deref_mut(),
2283
changed_by: caller.map(|caller| caller.deref_mut()),
2284
this_run: fetch.this_run,
2285
last_run: fetch.last_run,
2286
},
2287
}
2288
},
2289
|sparse_set| {
2290
// SAFETY: The caller ensures `entity` is in range and has the component.
2291
let (component, ticks) = unsafe {
2292
sparse_set
2293
.debug_checked_unwrap()
2294
.get_with_ticks(entity)
2295
.debug_checked_unwrap()
2296
};
2297
2298
Mut {
2299
value: component.assert_unique().deref_mut(),
2300
ticks: ComponentTicksMut::from_tick_cells(
2301
ticks,
2302
fetch.last_run,
2303
fetch.this_run,
2304
),
2305
}
2306
},
2307
))
2308
}
2309
2310
fn iter_access(state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
2311
iter::once(EcsAccessType::Component(EcsAccessLevel::Write(*state)))
2312
}
2313
}
2314
2315
impl<T: Component<Mutability = Mutable>> ReleaseStateQueryData for &mut T {
2316
fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
2317
item
2318
}
2319
}
2320
2321
impl<T: Component<Mutability = Mutable>> ArchetypeQueryData for &mut T {}
2322
2323
impl<T: Component<Mutability = Mutable>> ContiguousQueryData for &mut T {
2324
type Contiguous<'w, 's> = ContiguousMut<'w, T>;
2325
2326
unsafe fn fetch_contiguous<'w, 's>(
2327
_state: &'s Self::State,
2328
fetch: &mut Self::Fetch<'w>,
2329
entities: &'w [Entity],
2330
) -> Self::Contiguous<'w, 's> {
2331
fetch.components.extract(
2332
|table| {
2333
// SAFETY: set_table was previously called
2334
let (table_components, added_ticks, changed_ticks, callers) =
2335
unsafe { table.debug_checked_unwrap() };
2336
2337
ContiguousMut {
2338
// SAFETY: `entities` has the same length as the rows in the set table.
2339
value: unsafe { table_components.as_mut_slice_unchecked(entities.len()) },
2340
// SAFETY:
2341
// - The caller ensures the permission to access ticks.
2342
// - `entities` has the same length as the rows in the set table hence the
2343
// ticks.
2344
ticks: unsafe {
2345
ContiguousComponentTicksMut::from_slice_ptrs(
2346
added_ticks,
2347
changed_ticks,
2348
callers,
2349
entities.len(),
2350
fetch.this_run,
2351
fetch.last_run,
2352
)
2353
},
2354
}
2355
},
2356
|_| {
2357
#[cfg(debug_assertions)]
2358
unreachable!();
2359
// SAFETY: the caller ensures that [`Self::set_table`] was called beforehand.
2360
#[cfg(not(debug_assertions))]
2361
core::hint::unreachable_unchecked();
2362
},
2363
)
2364
}
2365
}
2366
2367
/// When `Mut<T>` is used in a query, it will be converted to `Ref<T>` when transformed into its read-only form, providing access to change detection methods.
2368
///
2369
/// By contrast `&mut T` will result in a `Mut<T>` item in mutable form to record mutations, but result in a bare `&T` in read-only form.
2370
//
2371
// SAFETY:
2372
// `fetch` accesses a single component mutably.
2373
// This is sound because `update_component_access` adds write access for that component and panic when appropriate.
2374
// `update_component_access` adds a `With` filter for a component.
2375
// This is sound because `matches_component_set` returns whether the set contains that component.
2376
unsafe impl<'__w, T: Component> WorldQuery for Mut<'__w, T> {
2377
type Fetch<'w> = WriteFetch<'w, T>;
2378
type State = ComponentId;
2379
2380
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
2381
fetch
2382
}
2383
2384
#[inline]
2385
// Forwarded to `&mut T`
2386
unsafe fn init_fetch<'w, 's>(
2387
world: UnsafeWorldCell<'w>,
2388
state: &ComponentId,
2389
last_run: Tick,
2390
this_run: Tick,
2391
) -> WriteFetch<'w, T> {
2392
<&mut T as WorldQuery>::init_fetch(world, state, last_run, this_run)
2393
}
2394
2395
// Forwarded to `&mut T`
2396
const IS_DENSE: bool = <&mut T as WorldQuery>::IS_DENSE;
2397
2398
#[inline]
2399
// Forwarded to `&mut T`
2400
unsafe fn set_archetype<'w>(
2401
fetch: &mut WriteFetch<'w, T>,
2402
state: &ComponentId,
2403
archetype: &'w Archetype,
2404
table: &'w Table,
2405
) {
2406
<&mut T as WorldQuery>::set_archetype(fetch, state, archetype, table);
2407
}
2408
2409
#[inline]
2410
// Forwarded to `&mut T`
2411
unsafe fn set_table<'w>(fetch: &mut WriteFetch<'w, T>, state: &ComponentId, table: &'w Table) {
2412
<&mut T as WorldQuery>::set_table(fetch, state, table);
2413
}
2414
2415
// NOT forwarded to `&mut T`
2416
fn update_component_access(&component_id: &ComponentId, access: &mut FilteredAccess) {
2417
// Update component access here instead of in `<&mut T as WorldQuery>` to avoid erroneously referencing
2418
// `&mut T` in error message.
2419
assert!(
2420
!access.access().has_component_read(component_id),
2421
"Mut<{}> conflicts with a previous access in this query. Mutable component access mut be unique.",
2422
DebugName::type_name::<T>(),
2423
);
2424
access.add_component_write(component_id);
2425
}
2426
2427
// Forwarded to `&mut T`
2428
fn init_state(world: &mut World) -> ComponentId {
2429
<&mut T as WorldQuery>::init_state(world)
2430
}
2431
2432
// Forwarded to `&mut T`
2433
fn get_state(components: &Components) -> Option<ComponentId> {
2434
<&mut T as WorldQuery>::get_state(components)
2435
}
2436
2437
// Forwarded to `&mut T`
2438
fn matches_component_set(
2439
state: &ComponentId,
2440
set_contains_id: &impl Fn(ComponentId) -> bool,
2441
) -> bool {
2442
<&mut T as WorldQuery>::matches_component_set(state, set_contains_id)
2443
}
2444
}
2445
2446
// SAFETY: access of `Ref<T>` is a subset of `Mut<T>`
2447
unsafe impl<'__w, T: Component<Mutability = Mutable>> QueryData for Mut<'__w, T> {
2448
const IS_READ_ONLY: bool = false;
2449
const IS_ARCHETYPAL: bool = true;
2450
type ReadOnly = Ref<'__w, T>;
2451
type Item<'w, 's> = Mut<'w, T>;
2452
2453
// Forwarded to `&mut T`
2454
fn shrink<'wlong: 'wshort, 'wshort, 's>(
2455
item: Self::Item<'wlong, 's>,
2456
) -> Self::Item<'wshort, 's> {
2457
<&mut T as QueryData>::shrink(item)
2458
}
2459
2460
#[inline(always)]
2461
// Forwarded to `&mut T`
2462
unsafe fn fetch<'w, 's>(
2463
state: &'s Self::State,
2464
// Rust complains about lifetime bounds not matching the trait if I directly use `WriteFetch<'w, T>` right here.
2465
// But it complains nowhere else in the entire trait implementation.
2466
fetch: &mut Self::Fetch<'w>,
2467
entity: Entity,
2468
table_row: TableRow,
2469
) -> Option<Self::Item<'w, 's>> {
2470
<&mut T as QueryData>::fetch(state, fetch, entity, table_row)
2471
}
2472
2473
fn iter_access(state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
2474
iter::once(EcsAccessType::Component(EcsAccessLevel::Write(*state)))
2475
}
2476
}
2477
2478
impl<T: Component<Mutability = Mutable>> ReleaseStateQueryData for Mut<'_, T> {
2479
fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
2480
item
2481
}
2482
}
2483
2484
impl<T: Component<Mutability = Mutable>> ArchetypeQueryData for Mut<'_, T> {}
2485
2486
impl<'__w, T: Component<Mutability = Mutable>> ContiguousQueryData for Mut<'__w, T> {
2487
type Contiguous<'w, 's> = ContiguousMut<'w, T>;
2488
2489
unsafe fn fetch_contiguous<'w, 's>(
2490
state: &'s Self::State,
2491
fetch: &mut Self::Fetch<'w>,
2492
entities: &'w [Entity],
2493
) -> Self::Contiguous<'w, 's> {
2494
<&mut T as ContiguousQueryData>::fetch_contiguous(state, fetch, entities)
2495
}
2496
}
2497
2498
#[doc(hidden)]
2499
pub struct OptionFetch<'w, T: WorldQuery> {
2500
fetch: T::Fetch<'w>,
2501
matches: bool,
2502
}
2503
2504
impl<T: WorldQuery> Clone for OptionFetch<'_, T> {
2505
fn clone(&self) -> Self {
2506
Self {
2507
fetch: self.fetch.clone(),
2508
matches: self.matches,
2509
}
2510
}
2511
}
2512
2513
// SAFETY:
2514
// `fetch` might access any components that `T` accesses.
2515
// This is sound because `update_component_access` adds the same accesses as `T`.
2516
// Filters are unchanged.
2517
unsafe impl<T: WorldQuery> WorldQuery for Option<T> {
2518
type Fetch<'w> = OptionFetch<'w, T>;
2519
type State = T::State;
2520
2521
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
2522
OptionFetch {
2523
fetch: T::shrink_fetch(fetch.fetch),
2524
matches: fetch.matches,
2525
}
2526
}
2527
2528
#[inline]
2529
unsafe fn init_fetch<'w, 's>(
2530
world: UnsafeWorldCell<'w>,
2531
state: &'s T::State,
2532
last_run: Tick,
2533
this_run: Tick,
2534
) -> OptionFetch<'w, T> {
2535
OptionFetch {
2536
// SAFETY: The invariants are upheld by the caller.
2537
fetch: unsafe { T::init_fetch(world, state, last_run, this_run) },
2538
matches: false,
2539
}
2540
}
2541
2542
const IS_DENSE: bool = T::IS_DENSE;
2543
2544
#[inline]
2545
unsafe fn set_archetype<'w, 's>(
2546
fetch: &mut OptionFetch<'w, T>,
2547
state: &'s T::State,
2548
archetype: &'w Archetype,
2549
table: &'w Table,
2550
) {
2551
fetch.matches = T::matches_component_set(state, &|id| archetype.contains(id));
2552
if fetch.matches {
2553
// SAFETY: The invariants are upheld by the caller.
2554
unsafe {
2555
T::set_archetype(&mut fetch.fetch, state, archetype, table);
2556
}
2557
}
2558
}
2559
2560
#[inline]
2561
unsafe fn set_table<'w, 's>(
2562
fetch: &mut OptionFetch<'w, T>,
2563
state: &'s T::State,
2564
table: &'w Table,
2565
) {
2566
fetch.matches = T::matches_component_set(state, &|id| table.has_column(id));
2567
if fetch.matches {
2568
// SAFETY: The invariants are upheld by the caller.
2569
unsafe {
2570
T::set_table(&mut fetch.fetch, state, table);
2571
}
2572
}
2573
}
2574
2575
fn update_component_access(state: &T::State, access: &mut FilteredAccess) {
2576
// FilteredAccess::add_[write,read] adds the component to the `with` filter.
2577
// Those methods are called on `access` in `T::update_component_access`.
2578
// But in `Option<T>`, we specifically don't filter on `T`,
2579
// since `(Option<T>, &OtherComponent)` should be a valid item, even
2580
// if `Option<T>` is `None`.
2581
//
2582
// We pass a clone of the `FilteredAccess` to `T`, and only update the `Access`
2583
// using `extend_access` so that we can apply `T`'s component_access
2584
// without updating the `with` filters of `access`.
2585
let mut intermediate = access.clone();
2586
T::update_component_access(state, &mut intermediate);
2587
access.extend_access(&intermediate);
2588
}
2589
2590
fn init_state(world: &mut World) -> T::State {
2591
T::init_state(world)
2592
}
2593
2594
fn get_state(components: &Components) -> Option<Self::State> {
2595
T::get_state(components)
2596
}
2597
2598
fn matches_component_set(
2599
_state: &T::State,
2600
_set_contains_id: &impl Fn(ComponentId) -> bool,
2601
) -> bool {
2602
true
2603
}
2604
}
2605
2606
// SAFETY: defers to soundness of `T: WorldQuery` impl
2607
unsafe impl<T: QueryData> QueryData for Option<T> {
2608
const IS_READ_ONLY: bool = T::IS_READ_ONLY;
2609
// `Option` matches all entities, even if `T` does not,
2610
// so it's always an `ArchetypeQueryData`, even for non-archetypal `T`.
2611
const IS_ARCHETYPAL: bool = true;
2612
type ReadOnly = Option<T::ReadOnly>;
2613
type Item<'w, 's> = Option<T::Item<'w, 's>>;
2614
2615
fn shrink<'wlong: 'wshort, 'wshort, 's>(
2616
item: Self::Item<'wlong, 's>,
2617
) -> Self::Item<'wshort, 's> {
2618
item.map(T::shrink)
2619
}
2620
2621
#[inline(always)]
2622
unsafe fn fetch<'w, 's>(
2623
state: &'s Self::State,
2624
fetch: &mut Self::Fetch<'w>,
2625
entity: Entity,
2626
table_row: TableRow,
2627
) -> Option<Self::Item<'w, 's>> {
2628
Some(
2629
fetch
2630
.matches
2631
// SAFETY: The invariants are upheld by the caller.
2632
.then(|| unsafe { T::fetch(state, &mut fetch.fetch, entity, table_row) })
2633
.flatten(),
2634
)
2635
}
2636
2637
fn iter_access(state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
2638
T::iter_access(state)
2639
}
2640
}
2641
2642
// SAFETY: [`OptionFetch`] is read only because `T` is read only
2643
unsafe impl<T: ReadOnlyQueryData> ReadOnlyQueryData for Option<T> {}
2644
2645
impl<T: ReleaseStateQueryData> ReleaseStateQueryData for Option<T> {
2646
fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
2647
item.map(T::release_state)
2648
}
2649
}
2650
2651
// `Option` matches all entities, even if `T` does not,
2652
// so it's always an `ArchetypeQueryData`, even for non-archetypal `T`.
2653
impl<T: QueryData> ArchetypeQueryData for Option<T> {}
2654
2655
impl<T: ContiguousQueryData> ContiguousQueryData for Option<T> {
2656
type Contiguous<'w, 's> = Option<T::Contiguous<'w, 's>>;
2657
2658
unsafe fn fetch_contiguous<'w, 's>(
2659
state: &'s Self::State,
2660
fetch: &mut Self::Fetch<'w>,
2661
entities: &'w [Entity],
2662
) -> Self::Contiguous<'w, 's> {
2663
fetch
2664
.matches
2665
// SAFETY: The invariants are upheld by the caller
2666
.then(|| unsafe { T::fetch_contiguous(state, &mut fetch.fetch, entities) })
2667
}
2668
}
2669
2670
/// Returns a bool that describes if an entity has the component `T`.
2671
///
2672
/// This can be used in a [`Query`](crate::system::Query) if you want to know whether or not entities
2673
/// have the component `T` but don't actually care about the component's value.
2674
///
2675
/// # Footguns
2676
///
2677
/// Note that a `Query<Has<T>>` will match all existing entities.
2678
/// Beware! Even if it matches all entities, it doesn't mean that `query.get(entity)`
2679
/// will always return `Ok(bool)`.
2680
///
2681
/// In the case of a non-existent entity, such as a despawned one, it will return `Err`.
2682
/// A workaround is to replace `query.get(entity).unwrap()` by
2683
/// `query.get(entity).unwrap_or_default()`.
2684
///
2685
/// # Examples
2686
///
2687
/// ```
2688
/// # use bevy_ecs::component::Component;
2689
/// # use bevy_ecs::query::Has;
2690
/// # use bevy_ecs::system::IntoSystem;
2691
/// # use bevy_ecs::system::Query;
2692
/// #
2693
/// # #[derive(Component)]
2694
/// # struct IsHungry;
2695
/// # #[derive(Component)]
2696
/// # struct Name { name: &'static str };
2697
/// #
2698
/// fn food_entity_system(query: Query<(&Name, Has<IsHungry>) >) {
2699
/// for (name, is_hungry) in &query {
2700
/// if is_hungry{
2701
/// println!("{} would like some food.", name.name);
2702
/// } else {
2703
/// println!("{} has had sufficient.", name.name);
2704
/// }
2705
/// }
2706
/// }
2707
/// # bevy_ecs::system::assert_is_system(food_entity_system);
2708
/// ```
2709
///
2710
/// ```
2711
/// # use bevy_ecs::component::Component;
2712
/// # use bevy_ecs::query::Has;
2713
/// # use bevy_ecs::system::IntoSystem;
2714
/// # use bevy_ecs::system::Query;
2715
/// #
2716
/// # #[derive(Component)]
2717
/// # struct Alpha{has_beta: bool};
2718
/// # #[derive(Component)]
2719
/// # struct Beta { has_alpha: bool };
2720
/// #
2721
/// // Unlike `Option<&T>`, `Has<T>` is compatible with `&mut T`
2722
/// // as it does not actually access any data.
2723
/// fn alphabet_entity_system(mut alphas: Query<(&mut Alpha, Has<Beta>)>, mut betas: Query<(&mut Beta, Has<Alpha>)>) {
2724
/// for (mut alpha, has_beta) in alphas.iter_mut() {
2725
/// alpha.has_beta = has_beta;
2726
/// }
2727
/// for (mut beta, has_alpha) in betas.iter_mut() {
2728
/// beta.has_alpha = has_alpha;
2729
/// }
2730
/// }
2731
/// # bevy_ecs::system::assert_is_system(alphabet_entity_system);
2732
/// ```
2733
pub struct Has<T>(PhantomData<T>);
2734
2735
impl<T> core::fmt::Debug for Has<T> {
2736
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
2737
write!(f, "Has<{}>", DebugName::type_name::<T>())
2738
}
2739
}
2740
2741
// SAFETY:
2742
// `update_component_access` does nothing.
2743
// This is sound because `fetch` does not access components.
2744
unsafe impl<T: Component> WorldQuery for Has<T> {
2745
type Fetch<'w> = bool;
2746
type State = ComponentId;
2747
2748
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
2749
fetch
2750
}
2751
2752
#[inline]
2753
unsafe fn init_fetch<'w, 's>(
2754
_world: UnsafeWorldCell<'w>,
2755
_state: &'s Self::State,
2756
_last_run: Tick,
2757
_this_run: Tick,
2758
) -> Self::Fetch<'w> {
2759
false
2760
}
2761
2762
const IS_DENSE: bool = {
2763
match T::STORAGE_TYPE {
2764
StorageType::Table => true,
2765
StorageType::SparseSet => false,
2766
}
2767
};
2768
2769
#[inline]
2770
unsafe fn set_archetype<'w, 's>(
2771
fetch: &mut Self::Fetch<'w>,
2772
state: &'s Self::State,
2773
archetype: &'w Archetype,
2774
_table: &Table,
2775
) {
2776
*fetch = archetype.contains(*state);
2777
}
2778
2779
#[inline]
2780
unsafe fn set_table<'w, 's>(
2781
fetch: &mut Self::Fetch<'w>,
2782
state: &'s Self::State,
2783
table: &'w Table,
2784
) {
2785
*fetch = table.has_column(*state);
2786
}
2787
2788
fn update_component_access(&component_id: &Self::State, access: &mut FilteredAccess) {
2789
access.access_mut().add_archetypal(component_id);
2790
}
2791
2792
fn init_state(world: &mut World) -> ComponentId {
2793
world.register_component::<T>()
2794
}
2795
2796
fn get_state(components: &Components) -> Option<Self::State> {
2797
components.component_id::<T>()
2798
}
2799
2800
fn matches_component_set(
2801
_state: &Self::State,
2802
_set_contains_id: &impl Fn(ComponentId) -> bool,
2803
) -> bool {
2804
// `Has<T>` always matches
2805
true
2806
}
2807
}
2808
2809
// SAFETY: `Self` is the same as `Self::ReadOnly`
2810
unsafe impl<T: Component> QueryData for Has<T> {
2811
const IS_READ_ONLY: bool = true;
2812
const IS_ARCHETYPAL: bool = true;
2813
type ReadOnly = Self;
2814
type Item<'w, 's> = bool;
2815
2816
fn shrink<'wlong: 'wshort, 'wshort, 's>(
2817
item: Self::Item<'wlong, 's>,
2818
) -> Self::Item<'wshort, 's> {
2819
item
2820
}
2821
2822
#[inline(always)]
2823
unsafe fn fetch<'w, 's>(
2824
_state: &'s Self::State,
2825
fetch: &mut Self::Fetch<'w>,
2826
_entity: Entity,
2827
_table_row: TableRow,
2828
) -> Option<Self::Item<'w, 's>> {
2829
Some(*fetch)
2830
}
2831
2832
fn iter_access(_state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
2833
iter::empty()
2834
}
2835
}
2836
2837
// SAFETY: [`Has`] is read only
2838
unsafe impl<T: Component> ReadOnlyQueryData for Has<T> {}
2839
2840
impl<T: Component> ReleaseStateQueryData for Has<T> {
2841
fn release_state<'w>(item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
2842
item
2843
}
2844
}
2845
2846
impl<T: Component> ArchetypeQueryData for Has<T> {}
2847
2848
impl<T: Component> ContiguousQueryData for Has<T> {
2849
type Contiguous<'w, 's> = bool;
2850
2851
unsafe fn fetch_contiguous<'w, 's>(
2852
_state: &'s Self::State,
2853
fetch: &mut Self::Fetch<'w>,
2854
_entities: &'w [Entity],
2855
) -> Self::Contiguous<'w, 's> {
2856
*fetch
2857
}
2858
}
2859
2860
/// The `AnyOf` query parameter fetches entities with any of the component types included in T.
2861
///
2862
/// `Query<AnyOf<(&A, &B, &mut C)>>` is equivalent to `Query<(Option<&A>, Option<&B>, Option<&mut C>), Or<(With<A>, With<B>, With<C>)>>`.
2863
/// Each of the components in `T` is returned as an `Option`, as with `Option<A>` queries.
2864
/// Entities are guaranteed to have at least one of the components in `T`.
2865
pub struct AnyOf<T>(PhantomData<T>);
2866
2867
macro_rules! impl_tuple_query_data {
2868
($(#[$meta:meta])* $(($name: ident, $item: ident, $state: ident)),*) => {
2869
#[expect(
2870
clippy::allow_attributes,
2871
reason = "This is a tuple-related macro; as such the lints below may not always apply."
2872
)]
2873
#[allow(
2874
non_snake_case,
2875
reason = "The names of some variables are provided by the macro's caller, not by us."
2876
)]
2877
#[allow(
2878
unused_variables,
2879
reason = "Zero-length tuples won't use any of the parameters."
2880
)]
2881
#[allow(
2882
clippy::unused_unit,
2883
reason = "Zero-length tuples will generate some function bodies equivalent to `()`; however, this macro is meant for all applicable tuples, and as such it makes no sense to rewrite it just for that case."
2884
)]
2885
$(#[$meta])*
2886
// SAFETY: defers to soundness `$name: WorldQuery` impl
2887
unsafe impl<$($name: QueryData),*> QueryData for ($($name,)*) {
2888
const IS_READ_ONLY: bool = true $(&& $name::IS_READ_ONLY)*;
2889
const IS_ARCHETYPAL: bool = true $(&& $name::IS_ARCHETYPAL)*;
2890
type ReadOnly = ($($name::ReadOnly,)*);
2891
type Item<'w, 's> = ($($name::Item<'w, 's>,)*);
2892
2893
fn shrink<'wlong: 'wshort, 'wshort, 's>(item: Self::Item<'wlong, 's>) -> Self::Item<'wshort, 's> {
2894
let ($($name,)*) = item;
2895
($(
2896
$name::shrink($name),
2897
)*)
2898
}
2899
2900
#[inline]
2901
fn provide_extra_access(
2902
state: &mut Self::State,
2903
access: &mut Access,
2904
available_access: &Access,
2905
) {
2906
let ($($name,)*) = state;
2907
$($name::provide_extra_access($name, access, available_access);)*
2908
}
2909
2910
#[inline(always)]
2911
unsafe fn fetch<'w, 's>(
2912
state: &'s Self::State,
2913
fetch: &mut Self::Fetch<'w>,
2914
entity: Entity,
2915
table_row: TableRow
2916
) -> Option<Self::Item<'w, 's>> {
2917
let ($($state,)*) = state;
2918
let ($($name,)*) = fetch;
2919
// SAFETY: The invariants are upheld by the caller.
2920
Some(($(unsafe { $name::fetch($state, $name, entity, table_row) }?,)*))
2921
}
2922
2923
fn iter_access(state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
2924
let ($($name,)*) = state;
2925
iter::empty()$(.chain($name::iter_access($name)))*
2926
}
2927
}
2928
2929
$(#[$meta])*
2930
// SAFETY: each item in the tuple is read only
2931
unsafe impl<$($name: ReadOnlyQueryData),*> ReadOnlyQueryData for ($($name,)*) {}
2932
2933
#[expect(
2934
clippy::allow_attributes,
2935
reason = "This is a tuple-related macro; as such the lints below may not always apply."
2936
)]
2937
#[allow(
2938
clippy::unused_unit,
2939
reason = "Zero-length tuples will generate some function bodies equivalent to `()`; however, this macro is meant for all applicable tuples, and as such it makes no sense to rewrite it just for that case."
2940
)]
2941
$(#[$meta])*
2942
impl<$($name: ReleaseStateQueryData),*> ReleaseStateQueryData for ($($name,)*) {
2943
fn release_state<'w>(($($item,)*): Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
2944
($($name::release_state($item),)*)
2945
}
2946
}
2947
2948
$(#[$meta])*
2949
impl<$($name: ArchetypeQueryData),*> ArchetypeQueryData for ($($name,)*) {}
2950
2951
#[expect(
2952
clippy::allow_attributes,
2953
reason = "This is a tuple-related macro; as such the lints below may not always apply."
2954
)]
2955
#[allow(
2956
non_snake_case,
2957
reason = "The names of some variables are provided by the macro's caller, not by us."
2958
)]
2959
#[allow(
2960
unused_variables,
2961
reason = "Zero-length tuples won't use any of the parameters."
2962
)]
2963
#[allow(
2964
clippy::unused_unit,
2965
reason = "Zero-length tuples will generate some function bodies equivalent to `()`; however, this macro is meant for all applicable tuples, and as such it makes no sense to rewrite it just for that case."
2966
)]
2967
$(#[$meta])*
2968
impl<$($name: ContiguousQueryData),*> ContiguousQueryData for ($($name,)*) {
2969
type Contiguous<'w, 's> = ($($name::Contiguous::<'w, 's>,)*);
2970
2971
unsafe fn fetch_contiguous<'w, 's>(
2972
state: &'s Self::State,
2973
fetch: &mut Self::Fetch<'w>,
2974
entities: &'w [Entity],
2975
) -> Self::Contiguous<'w, 's> {
2976
let ($($state,)*) = state;
2977
let ($($name,)*) = fetch;
2978
// SAFETY: The invariants are upheld by the caller.
2979
($(unsafe {$name::fetch_contiguous($state, $name, entities)},)*)
2980
}
2981
}
2982
};
2983
}
2984
2985
macro_rules! impl_anytuple_fetch {
2986
($(#[$meta:meta])* $(($name: ident, $state: ident, $item: ident)),*) => {
2987
$(#[$meta])*
2988
#[expect(
2989
clippy::allow_attributes,
2990
reason = "This is a tuple-related macro; as such the lints below may not always apply."
2991
)]
2992
#[allow(
2993
non_snake_case,
2994
reason = "The names of some variables are provided by the macro's caller, not by us."
2995
)]
2996
#[allow(
2997
unused_variables,
2998
reason = "Zero-length tuples won't use any of the parameters."
2999
)]
3000
#[allow(
3001
clippy::unused_unit,
3002
reason = "Zero-length tuples will generate some function bodies equivalent to `()`; however, this macro is meant for all applicable tuples, and as such it makes no sense to rewrite it just for that case."
3003
)]
3004
// SAFETY:
3005
// `fetch` accesses are a subset of the subqueries' accesses
3006
// This is sound because `update_component_access` adds accesses according to the implementations of all the subqueries.
3007
// `update_component_access` replaces the filters with a disjunction where every element is a conjunction of the previous filters and the filters of one of the subqueries.
3008
// This is sound because `matches_component_set` returns a disjunction of the results of the subqueries' implementations.
3009
unsafe impl<$($name: WorldQuery),*> WorldQuery for AnyOf<($($name,)*)> {
3010
type Fetch<'w> = ($(($name::Fetch<'w>, bool),)*);
3011
type State = ($($name::State,)*);
3012
3013
fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
3014
let ($($name,)*) = fetch;
3015
($(
3016
($name::shrink_fetch($name.0), $name.1),
3017
)*)
3018
}
3019
3020
#[inline]
3021
unsafe fn init_fetch<'w, 's>(_world: UnsafeWorldCell<'w>, state: &'s Self::State, _last_run: Tick, _this_run: Tick) -> Self::Fetch<'w> {
3022
let ($($name,)*) = state;
3023
// SAFETY: The invariants are upheld by the caller.
3024
($(( unsafe { $name::init_fetch(_world, $name, _last_run, _this_run) }, false),)*)
3025
}
3026
3027
const IS_DENSE: bool = true $(&& $name::IS_DENSE)*;
3028
3029
#[inline]
3030
unsafe fn set_archetype<'w, 's>(
3031
_fetch: &mut Self::Fetch<'w>,
3032
_state: &'s Self::State,
3033
_archetype: &'w Archetype,
3034
_table: &'w Table
3035
) {
3036
let ($($name,)*) = _fetch;
3037
let ($($state,)*) = _state;
3038
$(
3039
$name.1 = $name::matches_component_set($state, &|id| _archetype.contains(id));
3040
if $name.1 {
3041
// SAFETY: The invariants are upheld by the caller.
3042
unsafe { $name::set_archetype(&mut $name.0, $state, _archetype, _table); }
3043
}
3044
)*
3045
}
3046
3047
#[inline]
3048
unsafe fn set_table<'w, 's>(_fetch: &mut Self::Fetch<'w>, _state: &'s Self::State, _table: &'w Table) {
3049
let ($($name,)*) = _fetch;
3050
let ($($state,)*) = _state;
3051
$(
3052
$name.1 = $name::matches_component_set($state, &|id| _table.has_column(id));
3053
if $name.1 {
3054
// SAFETY: The invariants are required to be upheld by the caller.
3055
unsafe { $name::set_table(&mut $name.0, $state, _table); }
3056
}
3057
)*
3058
}
3059
3060
fn update_component_access(state: &Self::State, access: &mut FilteredAccess) {
3061
// update the filters (Or<(With<$name>,)>)
3062
let ($($name,)*) = state;
3063
3064
let mut _new_access = FilteredAccess::matches_nothing();
3065
3066
$(
3067
// Create an intermediate because `access`'s value needs to be preserved
3068
// for the next query data, and `_new_access` has to be modified only by `append_or` to it,
3069
// which only updates the `filter_sets`, not the `access`.
3070
let mut intermediate = access.clone();
3071
$name::update_component_access($name, &mut intermediate);
3072
_new_access.append_or(&intermediate);
3073
)*
3074
3075
// Of the accumulated `_new_access` we only care about the filter sets, not the access.
3076
access.filter_sets = _new_access.filter_sets;
3077
3078
// For the access we instead delegate to a tuple of `Option`s.
3079
// This has essentially the same semantics of `AnyOf`, except that it doesn't
3080
// require at least one of them to be `Some`.
3081
// We however solve this by setting explicitly the `filter_sets` above.
3082
// Also note that Option<T> updates the `access` but not the `filter_sets`.
3083
<($(Option<$name>,)*)>::update_component_access(state, access);
3084
3085
}
3086
fn init_state(world: &mut World) -> Self::State {
3087
($($name::init_state(world),)*)
3088
}
3089
fn get_state(components: &Components) -> Option<Self::State> {
3090
Some(($($name::get_state(components)?,)*))
3091
}
3092
3093
fn matches_component_set(_state: &Self::State, _set_contains_id: &impl Fn(ComponentId) -> bool) -> bool {
3094
let ($($name,)*) = _state;
3095
false $(|| $name::matches_component_set($name, _set_contains_id))*
3096
}
3097
}
3098
3099
#[expect(
3100
clippy::allow_attributes,
3101
reason = "This is a tuple-related macro; as such the lints below may not always apply."
3102
)]
3103
#[allow(
3104
non_snake_case,
3105
reason = "The names of some variables are provided by the macro's caller, not by us."
3106
)]
3107
#[allow(
3108
unused_variables,
3109
reason = "Zero-length tuples won't use any of the parameters."
3110
)]
3111
#[allow(
3112
clippy::unused_unit,
3113
reason = "Zero-length tuples will generate some function bodies equivalent to `()`; however, this macro is meant for all applicable tuples, and as such it makes no sense to rewrite it just for that case."
3114
)]
3115
$(#[$meta])*
3116
// SAFETY: defers to soundness of `$name: WorldQuery` impl
3117
unsafe impl<$($name: QueryData),*> QueryData for AnyOf<($($name,)*)> {
3118
const IS_READ_ONLY: bool = true $(&& $name::IS_READ_ONLY)*;
3119
const IS_ARCHETYPAL: bool = true $(&& $name::IS_ARCHETYPAL)*;
3120
type ReadOnly = AnyOf<($($name::ReadOnly,)*)>;
3121
type Item<'w, 's> = ($(Option<$name::Item<'w, 's>>,)*);
3122
3123
fn shrink<'wlong: 'wshort, 'wshort, 's>(item: Self::Item<'wlong, 's>) -> Self::Item<'wshort, 's> {
3124
let ($($name,)*) = item;
3125
($(
3126
$name.map($name::shrink),
3127
)*)
3128
}
3129
3130
#[inline(always)]
3131
unsafe fn fetch<'w, 's>(
3132
_state: &'s Self::State,
3133
_fetch: &mut Self::Fetch<'w>,
3134
_entity: Entity,
3135
_table_row: TableRow
3136
) -> Option<Self::Item<'w, 's>> {
3137
let ($($name,)*) = _fetch;
3138
let ($($state,)*) = _state;
3139
let result = ($(
3140
// SAFETY: The invariants are required to be upheld by the caller.
3141
$name.1.then(|| unsafe { $name::fetch($state, &mut $name.0, _entity, _table_row) }).flatten(),
3142
)*);
3143
// If this is an archetypal query, then it is guaranteed to return `Some`,
3144
// and we can help the compiler remove branches by checking the const `IS_ARCHETYPAL` first.
3145
(Self::IS_ARCHETYPAL
3146
// We want to return `Some` if the query matches this entity,
3147
// which happens if at least one subquery returns `Some`.
3148
// So, fetch everything as usual, but if all the subqueries return `None` then return `None` instead.
3149
|| !matches!(result, ($(Option::<QueryItem<$name>>::None,)*))
3150
// If *none* of the subqueries matched the archetype, then this archetype was added in a transmute.
3151
// We must treat those as matching in order to be consistent with `size_hint` for archetypal queries,
3152
// so we treat them as matching for non-archetypal queries, as well.
3153
|| !(false $(|| $name.1)*))
3154
.then_some(result)
3155
}
3156
3157
fn iter_access(state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
3158
let ($($name,)*) = state;
3159
iter::empty()$(.chain($name::iter_access($name)))*
3160
}
3161
}
3162
3163
$(#[$meta])*
3164
// SAFETY: each item in the tuple is read only
3165
unsafe impl<$($name: ReadOnlyQueryData),*> ReadOnlyQueryData for AnyOf<($($name,)*)> {}
3166
3167
#[expect(
3168
clippy::allow_attributes,
3169
reason = "This is a tuple-related macro; as such the lints below may not always apply."
3170
)]
3171
#[allow(
3172
clippy::unused_unit,
3173
reason = "Zero-length tuples will generate some function bodies equivalent to `()`; however, this macro is meant for all applicable tuples, and as such it makes no sense to rewrite it just for that case."
3174
)]
3175
impl<$($name: ReleaseStateQueryData),*> ReleaseStateQueryData for AnyOf<($($name,)*)> {
3176
fn release_state<'w>(($($item,)*): Self::Item<'w, '_>) -> Self::Item<'w, 'static> {
3177
($($item.map(|$item| $name::release_state($item)),)*)
3178
}
3179
}
3180
3181
$(#[$meta])*
3182
impl<$($name: ArchetypeQueryData),*> ArchetypeQueryData for AnyOf<($($name,)*)> {}
3183
3184
3185
#[expect(
3186
clippy::allow_attributes,
3187
reason = "This is a tuple-related macro; as such the lints below may not always apply."
3188
)]
3189
#[allow(
3190
non_snake_case,
3191
reason = "The names of some variables are provided by the macro's caller, not by us."
3192
)]
3193
#[allow(
3194
unused_variables,
3195
reason = "Zero-length tuples won't use any of the parameters."
3196
)]
3197
#[allow(
3198
clippy::unused_unit,
3199
reason = "Zero-length tuples will generate some function bodies equivalent to `()`; however, this macro is meant for all applicable tuples, and as such it makes no sense to rewrite it just for that case."
3200
)]
3201
$(#[$meta])*
3202
impl<$($name: ContiguousQueryData),*> ContiguousQueryData for AnyOf<($($name,)*)> {
3203
type Contiguous<'w, 's> = ($(Option<$name::Contiguous<'w,'s>>,)*);
3204
3205
unsafe fn fetch_contiguous<'w, 's>(
3206
state: &'s Self::State,
3207
fetch: &mut Self::Fetch<'w>,
3208
entities: &'w [Entity],
3209
) -> Self::Contiguous<'w, 's> {
3210
let ($($name,)*) = fetch;
3211
let ($($state,)*) = state;
3212
// Matches the [`QueryData::fetch`] except it always returns Some
3213
($(
3214
// SAFETY: The invariants are upheld by the caller
3215
$name.1.then(|| unsafe { $name::fetch_contiguous($state, &mut $name.0, entities) }),
3216
)*)
3217
}
3218
}
3219
};
3220
}
3221
3222
all_tuples!(
3223
#[doc(fake_variadic)]
3224
impl_tuple_query_data,
3225
0,
3226
15,
3227
F,
3228
i,
3229
s
3230
);
3231
all_tuples!(
3232
#[doc(fake_variadic)]
3233
impl_anytuple_fetch,
3234
0,
3235
15,
3236
F,
3237
S,
3238
i
3239
);
3240
3241
/// [`WorldQuery`] used to nullify queries by turning `Query<D>` into `Query<NopWorldQuery<D>>`
3242
///
3243
/// This will rarely be useful to consumers of `bevy_ecs`.
3244
pub(crate) struct NopWorldQuery<D: QueryData>(PhantomData<D>);
3245
3246
// SAFETY:
3247
// `update_component_access` does nothing.
3248
// This is sound because `fetch` does not access components.
3249
unsafe impl<D: QueryData> WorldQuery for NopWorldQuery<D> {
3250
type Fetch<'w> = ();
3251
type State = D::State;
3252
3253
fn shrink_fetch<'wlong: 'wshort, 'wshort>(_fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
3254
}
3255
3256
#[inline(always)]
3257
unsafe fn init_fetch(
3258
_world: UnsafeWorldCell,
3259
_state: &D::State,
3260
_last_run: Tick,
3261
_this_run: Tick,
3262
) {
3263
}
3264
3265
const IS_DENSE: bool = D::IS_DENSE;
3266
3267
#[inline(always)]
3268
unsafe fn set_archetype(
3269
_fetch: &mut (),
3270
_state: &D::State,
3271
_archetype: &Archetype,
3272
_tables: &Table,
3273
) {
3274
}
3275
3276
#[inline(always)]
3277
unsafe fn set_table<'w>(_fetch: &mut (), _state: &D::State, _table: &Table) {}
3278
3279
fn update_component_access(_state: &D::State, _access: &mut FilteredAccess) {}
3280
3281
fn init_state(world: &mut World) -> Self::State {
3282
D::init_state(world)
3283
}
3284
3285
fn get_state(components: &Components) -> Option<Self::State> {
3286
D::get_state(components)
3287
}
3288
3289
fn matches_component_set(
3290
state: &Self::State,
3291
set_contains_id: &impl Fn(ComponentId) -> bool,
3292
) -> bool {
3293
D::matches_component_set(state, set_contains_id)
3294
}
3295
}
3296
3297
// SAFETY: `Self::ReadOnly` is `Self`
3298
unsafe impl<D: QueryData> QueryData for NopWorldQuery<D> {
3299
const IS_READ_ONLY: bool = true;
3300
const IS_ARCHETYPAL: bool = true;
3301
type ReadOnly = Self;
3302
type Item<'w, 's> = ();
3303
3304
fn shrink<'wlong: 'wshort, 'wshort, 's>(
3305
_item: Self::Item<'wlong, 's>,
3306
) -> Self::Item<'wshort, 's> {
3307
}
3308
3309
#[inline(always)]
3310
unsafe fn fetch<'w, 's>(
3311
_state: &'s Self::State,
3312
_fetch: &mut Self::Fetch<'w>,
3313
_entity: Entity,
3314
_table_row: TableRow,
3315
) -> Option<Self::Item<'w, 's>> {
3316
Some(())
3317
}
3318
3319
fn iter_access(_state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
3320
iter::empty()
3321
}
3322
}
3323
3324
// SAFETY: `NopFetch` never accesses any data
3325
unsafe impl<D: QueryData> ReadOnlyQueryData for NopWorldQuery<D> {}
3326
3327
impl<D: QueryData> ReleaseStateQueryData for NopWorldQuery<D> {
3328
fn release_state<'w>(_item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {}
3329
}
3330
3331
impl<D: QueryData> ArchetypeQueryData for NopWorldQuery<D> {}
3332
3333
// SAFETY:
3334
// `update_component_access` does nothing.
3335
// This is sound because `fetch` does not access components.
3336
unsafe impl<T: ?Sized> WorldQuery for PhantomData<T> {
3337
type Fetch<'w> = ();
3338
3339
type State = ();
3340
3341
fn shrink_fetch<'wlong: 'wshort, 'wshort>(_fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
3342
}
3343
3344
unsafe fn init_fetch<'w, 's>(
3345
_world: UnsafeWorldCell<'w>,
3346
_state: &'s Self::State,
3347
_last_run: Tick,
3348
_this_run: Tick,
3349
) -> Self::Fetch<'w> {
3350
}
3351
3352
// `PhantomData` does not match any components, so all components it matches
3353
// are stored in a Table (vacuous truth).
3354
const IS_DENSE: bool = true;
3355
3356
unsafe fn set_archetype<'w, 's>(
3357
_fetch: &mut Self::Fetch<'w>,
3358
_state: &'s Self::State,
3359
_archetype: &'w Archetype,
3360
_table: &'w Table,
3361
) {
3362
}
3363
3364
unsafe fn set_table<'w, 's>(
3365
_fetch: &mut Self::Fetch<'w>,
3366
_state: &'s Self::State,
3367
_table: &'w Table,
3368
) {
3369
}
3370
3371
fn update_component_access(_state: &Self::State, _access: &mut FilteredAccess) {}
3372
3373
fn init_state(_world: &mut World) -> Self::State {}
3374
3375
fn get_state(_components: &Components) -> Option<Self::State> {
3376
Some(())
3377
}
3378
3379
fn matches_component_set(
3380
_state: &Self::State,
3381
_set_contains_id: &impl Fn(ComponentId) -> bool,
3382
) -> bool {
3383
true
3384
}
3385
}
3386
3387
// SAFETY: `Self::ReadOnly` is `Self`
3388
unsafe impl<T: ?Sized> QueryData for PhantomData<T> {
3389
const IS_READ_ONLY: bool = true;
3390
const IS_ARCHETYPAL: bool = true;
3391
type ReadOnly = Self;
3392
type Item<'w, 's> = ();
3393
3394
fn shrink<'wlong: 'wshort, 'wshort, 's>(
3395
_item: Self::Item<'wlong, 's>,
3396
) -> Self::Item<'wshort, 's> {
3397
}
3398
3399
unsafe fn fetch<'w, 's>(
3400
_state: &'s Self::State,
3401
_fetch: &mut Self::Fetch<'w>,
3402
_entity: Entity,
3403
_table_row: TableRow,
3404
) -> Option<Self::Item<'w, 's>> {
3405
Some(())
3406
}
3407
3408
fn iter_access(_state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
3409
iter::empty()
3410
}
3411
}
3412
3413
// SAFETY: `PhantomData` never accesses any world data.
3414
unsafe impl<T: ?Sized> ReadOnlyQueryData for PhantomData<T> {}
3415
3416
impl<T: ?Sized> ReleaseStateQueryData for PhantomData<T> {
3417
fn release_state<'w>(_item: Self::Item<'w, '_>) -> Self::Item<'w, 'static> {}
3418
}
3419
3420
impl<T: ?Sized> ArchetypeQueryData for PhantomData<T> {}
3421
3422
/// A compile-time checked union of two different types that differs based on the
3423
/// [`StorageType`] of a given component.
3424
pub(super) union StorageSwitch<C: Component, T: Copy, S: Copy> {
3425
/// The table variant. Requires the component to be a table component.
3426
table: T,
3427
/// The sparse set variant. Requires the component to be a sparse set component.
3428
sparse_set: S,
3429
_marker: PhantomData<C>,
3430
}
3431
3432
impl<C: Component, T: Copy, S: Copy> StorageSwitch<C, T, S> {
3433
/// Creates a new [`StorageSwitch`] using the given closures to initialize
3434
/// the variant corresponding to the component's [`StorageType`].
3435
pub fn new(table: impl FnOnce() -> T, sparse_set: impl FnOnce() -> S) -> Self {
3436
match C::STORAGE_TYPE {
3437
StorageType::Table => Self { table: table() },
3438
StorageType::SparseSet => Self {
3439
sparse_set: sparse_set(),
3440
},
3441
}
3442
}
3443
3444
/// Creates a new [`StorageSwitch`] using a table variant.
3445
///
3446
/// # Panics
3447
///
3448
/// This will panic on debug builds if `C` is not a table component.
3449
///
3450
/// # Safety
3451
///
3452
/// `C` must be a table component.
3453
#[inline]
3454
pub unsafe fn set_table(&mut self, table: T) {
3455
match C::STORAGE_TYPE {
3456
StorageType::Table => self.table = table,
3457
_ => {
3458
#[cfg(debug_assertions)]
3459
unreachable!();
3460
#[cfg(not(debug_assertions))]
3461
core::hint::unreachable_unchecked()
3462
}
3463
}
3464
}
3465
3466
/// Fetches the internal value from the variant that corresponds to the
3467
/// component's [`StorageType`].
3468
pub fn extract<R>(&self, table: impl FnOnce(T) -> R, sparse_set: impl FnOnce(S) -> R) -> R {
3469
match C::STORAGE_TYPE {
3470
StorageType::Table => table(
3471
// SAFETY: C::STORAGE_TYPE == StorageType::Table
3472
unsafe { self.table },
3473
),
3474
StorageType::SparseSet => sparse_set(
3475
// SAFETY: C::STORAGE_TYPE == StorageType::SparseSet
3476
unsafe { self.sparse_set },
3477
),
3478
}
3479
}
3480
}
3481
3482
impl<C: Component, T: Copy, S: Copy> Clone for StorageSwitch<C, T, S> {
3483
fn clone(&self) -> Self {
3484
*self
3485
}
3486
}
3487
3488
impl<C: Component, T: Copy, S: Copy> Copy for StorageSwitch<C, T, S> {}
3489
3490
#[cfg(test)]
3491
mod tests {
3492
use super::*;
3493
use crate::change_detection::DetectChanges;
3494
use crate::query::Without;
3495
use crate::system::{assert_is_system, Query};
3496
use bevy_ecs::prelude::Schedule;
3497
use bevy_ecs_macros::QueryData;
3498
3499
#[derive(Component)]
3500
pub struct A;
3501
3502
#[derive(Component)]
3503
pub struct B;
3504
3505
// Tests that each variant of struct can be used as a `WorldQuery`.
3506
#[test]
3507
fn world_query_struct_variants() {
3508
#[derive(QueryData)]
3509
pub struct NamedQuery {
3510
id: Entity,
3511
a: &'static A,
3512
}
3513
3514
#[derive(QueryData)]
3515
pub struct TupleQuery(&'static A, &'static B);
3516
3517
#[derive(QueryData)]
3518
pub struct UnitQuery;
3519
3520
fn my_system(_: Query<(NamedQuery, TupleQuery, UnitQuery)>) {}
3521
3522
assert_is_system(my_system);
3523
}
3524
3525
// Compile test for https://github.com/bevyengine/bevy/pull/8030.
3526
#[test]
3527
fn world_query_phantom_data() {
3528
#[derive(QueryData)]
3529
pub struct IgnoredQuery<Marker> {
3530
id: Entity,
3531
_marker: PhantomData<Marker>,
3532
}
3533
3534
fn ignored_system(_: Query<IgnoredQuery<()>>) {}
3535
3536
assert_is_system(ignored_system);
3537
}
3538
3539
#[test]
3540
fn derive_release_state() {
3541
struct NonReleaseQueryData;
3542
3543
// SAFETY:
3544
// `update_component_access` do nothing.
3545
// This is sound because `fetch` does not access components.
3546
unsafe impl WorldQuery for NonReleaseQueryData {
3547
type Fetch<'w> = ();
3548
type State = ();
3549
3550
fn shrink_fetch<'wlong: 'wshort, 'wshort>(
3551
_: Self::Fetch<'wlong>,
3552
) -> Self::Fetch<'wshort> {
3553
}
3554
3555
unsafe fn init_fetch<'w, 's>(
3556
_world: UnsafeWorldCell<'w>,
3557
_state: &'s Self::State,
3558
_last_run: Tick,
3559
_this_run: Tick,
3560
) -> Self::Fetch<'w> {
3561
}
3562
3563
const IS_DENSE: bool = true;
3564
3565
#[inline]
3566
unsafe fn set_archetype<'w, 's>(
3567
_fetch: &mut Self::Fetch<'w>,
3568
_state: &'s Self::State,
3569
_archetype: &'w Archetype,
3570
_table: &Table,
3571
) {
3572
}
3573
3574
#[inline]
3575
unsafe fn set_table<'w, 's>(
3576
_fetch: &mut Self::Fetch<'w>,
3577
_state: &'s Self::State,
3578
_table: &'w Table,
3579
) {
3580
}
3581
3582
fn update_component_access(_state: &Self::State, _access: &mut FilteredAccess) {}
3583
3584
fn init_state(_world: &mut World) {}
3585
3586
fn get_state(_components: &Components) -> Option<()> {
3587
Some(())
3588
}
3589
3590
fn matches_component_set(
3591
_state: &Self::State,
3592
_set_contains_id: &impl Fn(ComponentId) -> bool,
3593
) -> bool {
3594
true
3595
}
3596
}
3597
3598
// SAFETY: `Self` is the same as `Self::ReadOnly`
3599
unsafe impl QueryData for NonReleaseQueryData {
3600
type ReadOnly = Self;
3601
const IS_READ_ONLY: bool = true;
3602
const IS_ARCHETYPAL: bool = true;
3603
3604
type Item<'w, 's> = ();
3605
3606
fn shrink<'wlong: 'wshort, 'wshort, 's>(
3607
_item: Self::Item<'wlong, 's>,
3608
) -> Self::Item<'wshort, 's> {
3609
}
3610
3611
#[inline(always)]
3612
unsafe fn fetch<'w, 's>(
3613
_state: &'s Self::State,
3614
_fetch: &mut Self::Fetch<'w>,
3615
_entity: Entity,
3616
_table_row: TableRow,
3617
) -> Option<Self::Item<'w, 's>> {
3618
Some(())
3619
}
3620
3621
fn iter_access(_state: &Self::State) -> impl Iterator<Item = EcsAccessType<'_>> {
3622
iter::empty()
3623
}
3624
}
3625
3626
// SAFETY: access is read only
3627
unsafe impl ReadOnlyQueryData for NonReleaseQueryData {}
3628
3629
impl ArchetypeQueryData for NonReleaseQueryData {}
3630
3631
#[derive(QueryData)]
3632
pub struct DerivedNonReleaseRead {
3633
non_release: NonReleaseQueryData,
3634
a: &'static A,
3635
}
3636
3637
#[derive(QueryData)]
3638
#[query_data(mutable)]
3639
pub struct DerivedNonReleaseMutable {
3640
non_release: NonReleaseQueryData,
3641
a: &'static mut A,
3642
}
3643
3644
#[derive(QueryData)]
3645
pub struct DerivedReleaseRead {
3646
a: &'static A,
3647
}
3648
3649
#[derive(QueryData)]
3650
#[query_data(mutable)]
3651
pub struct DerivedReleaseMutable {
3652
a: &'static mut A,
3653
}
3654
3655
fn assert_is_release_state<Q: ReleaseStateQueryData>() {}
3656
3657
assert_is_release_state::<DerivedReleaseRead>();
3658
assert_is_release_state::<DerivedReleaseMutable>();
3659
}
3660
3661
// Ensures that each field of a `WorldQuery` struct's read-only variant
3662
// has the same visibility as its corresponding mutable field.
3663
#[test]
3664
fn read_only_field_visibility() {
3665
mod private {
3666
use super::*;
3667
3668
#[derive(QueryData)]
3669
#[query_data(mutable)]
3670
pub struct D {
3671
pub a: &'static mut A,
3672
}
3673
}
3674
3675
let _ = private::DReadOnly { a: &A };
3676
3677
fn my_system(query: Query<private::D>) {
3678
for q in &query {
3679
let _ = &q.a;
3680
}
3681
}
3682
3683
assert_is_system(my_system);
3684
}
3685
3686
// Ensures that metadata types generated by the WorldQuery macro
3687
// do not conflict with user-defined types.
3688
// Regression test for https://github.com/bevyengine/bevy/issues/8010.
3689
#[test]
3690
fn world_query_metadata_collision() {
3691
// The metadata types generated would be named `ClientState` and `ClientFetch`,
3692
// but they should rename themselves to avoid conflicts.
3693
#[derive(QueryData)]
3694
pub struct Client<S: ClientState> {
3695
pub state: &'static S,
3696
pub fetch: &'static ClientFetch,
3697
}
3698
3699
pub trait ClientState: Component {}
3700
3701
#[derive(Component)]
3702
pub struct ClientFetch;
3703
3704
#[derive(Component)]
3705
pub struct C;
3706
3707
impl ClientState for C {}
3708
3709
fn client_system(_: Query<Client<C>>) {}
3710
3711
assert_is_system(client_system);
3712
}
3713
3714
// Test that EntityRef::get_ref::<T>() returns a Ref<T> value with the correct
3715
// ticks when the EntityRef was retrieved from a Query.
3716
// See: https://github.com/bevyengine/bevy/issues/13735
3717
#[test]
3718
fn test_entity_ref_query_with_ticks() {
3719
#[derive(Component)]
3720
pub struct C;
3721
3722
fn system(query: Query<EntityRef>) {
3723
for entity_ref in &query {
3724
if let Some(c) = entity_ref.get_ref::<C>()
3725
&& !c.is_added()
3726
{
3727
panic!("Expected C to be added");
3728
}
3729
}
3730
}
3731
3732
let mut world = World::new();
3733
let mut schedule = Schedule::default();
3734
schedule.add_systems(system);
3735
world.spawn(C);
3736
3737
// reset the change ticks
3738
world.clear_trackers();
3739
3740
// we want EntityRef to use the change ticks of the system
3741
schedule.run(&mut world);
3742
}
3743
3744
#[test]
3745
fn test_contiguous_query_data() {
3746
#[derive(Component, PartialEq, Eq, Debug)]
3747
pub struct C(i32);
3748
3749
#[derive(Component, PartialEq, Eq, Debug)]
3750
pub struct D(bool);
3751
3752
let mut world = World::new();
3753
world.spawn((C(0), D(true)));
3754
world.spawn((C(1), D(false)));
3755
world.spawn(C(2));
3756
3757
let mut query = world.query::<(&C, &D)>();
3758
let mut iter = query.contiguous_iter(&world).unwrap();
3759
let c = iter.next().unwrap();
3760
assert_eq!(c.0, [C(0), C(1)].as_slice());
3761
assert_eq!(c.1, [D(true), D(false)].as_slice());
3762
assert!(iter.next().is_none());
3763
3764
let mut query = world.query::<&C>();
3765
let mut iter = query.contiguous_iter(&world).unwrap();
3766
let mut present = [false; 3];
3767
let mut len = 0;
3768
for _ in 0..2 {
3769
let c = iter.next().unwrap();
3770
for c in c {
3771
present[c.0 as usize] = true;
3772
len += 1;
3773
}
3774
}
3775
assert!(iter.next().is_none());
3776
assert_eq!(len, 3);
3777
assert_eq!(present, [true; 3]);
3778
3779
let mut query = world.query::<&mut C>();
3780
let mut iter = query.contiguous_iter_mut(&mut world).unwrap();
3781
for _ in 0..2 {
3782
let c = iter.next().unwrap();
3783
for c in c {
3784
c.0 *= 2;
3785
}
3786
}
3787
assert!(iter.next().is_none());
3788
let mut iter = query.contiguous_iter(&world).unwrap();
3789
let mut present = [false; 6];
3790
let mut len = 0;
3791
for _ in 0..2 {
3792
let c = iter.next().unwrap();
3793
for c in c {
3794
present[c.0 as usize] = true;
3795
len += 1;
3796
}
3797
}
3798
assert_eq!(present, [true, false, true, false, true, false]);
3799
assert_eq!(len, 3);
3800
3801
let mut query = world.query_filtered::<&C, Without<D>>();
3802
let mut iter = query.contiguous_iter(&world).unwrap();
3803
assert_eq!(iter.next().unwrap(), &[C(4)]);
3804
assert!(iter.next().is_none());
3805
}
3806
3807
#[test]
3808
fn sparse_set_contiguous_query() {
3809
#[derive(Component, Debug, PartialEq, Eq)]
3810
#[component(storage = "SparseSet")]
3811
pub struct S(i32);
3812
3813
let mut world = World::new();
3814
world.spawn(S(0));
3815
3816
let mut query = world.query::<&mut S>();
3817
let iter = query.contiguous_iter_mut(&mut world);
3818
assert!(iter.is_none());
3819
}
3820
3821
#[test]
3822
fn any_of_contiguous_test() {
3823
#[derive(Component, Debug, Clone, Copy)]
3824
pub struct C(i32);
3825
3826
#[derive(Component, Debug, Clone, Copy)]
3827
pub struct D(i32);
3828
3829
let mut world = World::new();
3830
world.spawn((C(0), D(1)));
3831
world.spawn(C(2));
3832
world.spawn(D(3));
3833
world.spawn(());
3834
3835
let mut query = world.query::<AnyOf<(&C, &D)>>();
3836
let iter = query.contiguous_iter(&world).unwrap();
3837
let mut present = [false; 4];
3838
3839
for (c, d) in iter {
3840
assert!(c.is_some() || d.is_some());
3841
let c = c.unwrap_or_default();
3842
let d = d.unwrap_or_default();
3843
for i in 0..c.len().max(d.len()) {
3844
let c = c.get(i).cloned();
3845
let d = d.get(i).cloned();
3846
if let Some(C(c)) = c {
3847
assert!(!present[c as usize]);
3848
present[c as usize] = true;
3849
}
3850
if let Some(D(d)) = d {
3851
assert!(!present[d as usize]);
3852
present[d as usize] = true;
3853
}
3854
}
3855
}
3856
3857
assert_eq!(present, [true; 4]);
3858
}
3859
3860
#[test]
3861
fn option_contiguous_test() {
3862
#[derive(Component, Clone, Copy)]
3863
struct C(i32);
3864
3865
#[derive(Component, Clone, Copy)]
3866
struct D(i32);
3867
3868
let mut world = World::new();
3869
world.spawn((C(0), D(1)));
3870
world.spawn(D(2));
3871
world.spawn(C(3));
3872
3873
let mut query = world.query::<(Option<&C>, &D)>();
3874
let iter = query.contiguous_iter(&world).unwrap();
3875
let mut present = [false; 3];
3876
3877
for (c, d) in iter {
3878
let c = c.unwrap_or_default();
3879
for i in 0..d.len() {
3880
let c = c.get(i).cloned();
3881
let D(d) = d[i];
3882
if let Some(C(c)) = c {
3883
assert!(!present[c as usize]);
3884
present[c as usize] = true;
3885
}
3886
assert!(!present[d as usize]);
3887
present[d as usize] = true;
3888
}
3889
}
3890
3891
assert_eq!(present, [true; 3]);
3892
}
3893
}
3894
3895