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