Skip to main content

bevy_ecs/query/
filter.rs

1use crate::{
2    archetype::Archetype,
3    change_detection::Tick,
4    component::{Component, ComponentId, Components, StorageType},
5    entity::{Entities, Entity},
6    query::{DebugCheckedUnwrap, FilteredAccess, FilteredAccessSet, StorageSwitch, WorldQuery},
7    storage::{ComponentSparseSet, Table, TableRow},
8    world::{unsafe_world_cell::UnsafeWorldCell, World},
9};
10use bevy_ptr::{ThinSlicePtr, UnsafeCellDeref};
11use bevy_utils::prelude::DebugName;
12use core::{cell::UnsafeCell, marker::PhantomData};
13use variadics_please::all_tuples;
14
15/// Types that filter the results of a [`Query`].
16///
17/// There are many types that natively implement this trait:
18/// - **Component filters.**
19///   [`With`] and [`Without`] filters can be applied to check if the queried entity does or does not contain a particular component.
20/// - **Change detection filters.**
21///   [`Added`] and [`Changed`] filters can be applied to detect component changes to an entity.
22/// - **Spawned filter.**
23///   [`Spawned`] filter can be applied to check if the queried entity was spawned recently.
24/// - **`QueryFilter` tuples.**
25///   If every element of a tuple implements `QueryFilter`, then the tuple itself also implements the same trait.
26///   This enables a single `Query` to filter over multiple conditions.
27///   Due to the current lack of variadic generics in Rust, the trait has been implemented for tuples from 0 to 15 elements,
28///   but nesting of tuples allows infinite `QueryFilter`s.
29/// - **Filter disjunction operator.**
30///   By default, tuples compose query filters in such a way that all conditions must be satisfied to generate a query item for a given entity.
31///   Wrapping a tuple inside an [`Or`] operator will relax the requirement to just one condition.
32///
33/// Implementing the trait manually can allow for a fundamentally new type of behavior.
34///
35/// Query design can be easily structured by deriving `QueryFilter` for custom types.
36/// Despite the added complexity, this approach has several advantages over using `QueryFilter` tuples.
37/// The most relevant improvements are:
38///
39/// - Reusability across multiple systems.
40/// - Filters can be composed together to create a more complex filter.
41///
42/// This trait can only be derived for structs if each field also implements `QueryFilter`.
43///
44/// ```
45/// # use bevy_ecs::prelude::*;
46/// # use bevy_ecs::{query::QueryFilter, component::Component};
47/// #
48/// # #[derive(Component)]
49/// # struct ComponentA;
50/// # #[derive(Component)]
51/// # struct ComponentB;
52/// # #[derive(Component)]
53/// # struct ComponentC;
54/// # #[derive(Component)]
55/// # struct ComponentD;
56/// # #[derive(Component)]
57/// # struct ComponentE;
58/// #
59/// #[derive(QueryFilter)]
60/// struct MyFilter<T: Component, P: Component> {
61///     // Field names are not relevant, since they are never manually accessed.
62///     with_a: With<ComponentA>,
63///     or_filter: Or<(With<ComponentC>, Added<ComponentB>)>,
64///     generic_tuple: (With<T>, Without<P>),
65/// }
66///
67/// fn my_system(query: Query<Entity, MyFilter<ComponentD, ComponentE>>) {
68///     // ...
69/// }
70/// # bevy_ecs::system::assert_is_system(my_system);
71/// ```
72///
73/// [`Query`]: crate::system::Query
74///
75/// # Safety
76///
77/// The [`WorldQuery`] implementation must not take any mutable access.
78/// This is the same safety requirement as [`ReadOnlyQueryData`](crate::query::ReadOnlyQueryData).
79#[diagnostic::on_unimplemented(
80    message = "`{Self}` is not a valid `Query` filter",
81    label = "invalid `Query` filter",
82    note = "a `QueryFilter` typically uses a combination of `With<T>` and `Without<T>` statements"
83)]
84pub unsafe trait QueryFilter: WorldQuery {
85    /// Returns true if (and only if) this Filter relies strictly on archetypes to limit which
86    /// components are accessed by the Query.
87    ///
88    /// This enables optimizations for [`QueryIter`](`crate::query::QueryIter`) that rely on knowing exactly how
89    /// many elements are being iterated (such as `Iterator::collect()`).
90    ///
91    /// If this is `true`, then [`QueryFilter::filter_fetch`] must always return true.
92    const IS_ARCHETYPAL: bool;
93
94    /// Returns true if the provided [`Entity`] and [`TableRow`] should be included in the query results.
95    /// If false, the entity will be skipped.
96    ///
97    /// Note that this is called after already restricting the matched [`Table`]s and [`Archetype`]s to the
98    /// ones that are compatible with the Filter's access.
99    ///
100    /// Implementors of this method will generally either have a trivial `true` body (required for archetypal filters),
101    /// or access the necessary data within this function to make the final decision on filter inclusion.
102    ///
103    /// # Safety
104    ///
105    /// Must always be called _after_ [`WorldQuery::set_table`] or [`WorldQuery::set_archetype`]. `entity` and
106    /// `table_row` must be in the range of the current table and archetype.
107    unsafe fn filter_fetch(
108        state: &Self::State,
109        fetch: &mut Self::Fetch<'_>,
110        entity: Entity,
111        table_row: TableRow,
112    ) -> bool;
113}
114
115/// Filter that selects entities with a component `T`.
116///
117/// This can be used in a [`Query`](crate::system::Query) if entities are required to have the
118/// component `T` but you don't actually care about components value.
119///
120/// This is the negation of [`Without`].
121///
122/// # Examples
123///
124/// ```
125/// # use bevy_ecs::component::Component;
126/// # use bevy_ecs::query::With;
127/// # use bevy_ecs::system::IntoSystem;
128/// # use bevy_ecs::system::Query;
129/// #
130/// # #[derive(Component)]
131/// # struct IsBeautiful;
132/// # #[derive(Component)]
133/// # struct Name { name: &'static str };
134/// #
135/// fn compliment_entity_system(query: Query<&Name, With<IsBeautiful>>) {
136///     for name in &query {
137///         println!("{} is looking lovely today!", name.name);
138///     }
139/// }
140/// # bevy_ecs::system::assert_is_system(compliment_entity_system);
141/// ```
142pub struct With<T>(PhantomData<T>);
143
144// SAFETY:
145// `update_component_access` does not add any accesses.
146// This is sound because [`QueryFilter::filter_fetch`] does not access any components.
147// `update_component_access` adds a `With` filter for `T`.
148// This is sound because `matches_component_set` returns whether the set contains the component.
149unsafe impl<T: Component> WorldQuery for With<T> {
150    type Fetch<'w> = ();
151    type State = ComponentId;
152
153    fn shrink_fetch<'wlong: 'wshort, 'wshort>(_: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {}
154
155    #[inline]
156    unsafe fn init_fetch(
157        _world: UnsafeWorldCell,
158        _state: &ComponentId,
159        _last_run: Tick,
160        _this_run: Tick,
161    ) {
162    }
163
164    const IS_DENSE: bool = {
165        match T::STORAGE_TYPE {
166            StorageType::Table => true,
167            StorageType::SparseSet => false,
168        }
169    };
170
171    #[inline]
172    unsafe fn set_archetype(
173        _fetch: &mut (),
174        _state: &ComponentId,
175        _archetype: &Archetype,
176        _table: &Table,
177    ) {
178    }
179
180    #[inline]
181    unsafe fn set_table(_fetch: &mut (), _state: &ComponentId, _table: &Table) {}
182
183    #[inline]
184    fn update_component_access(&id: &ComponentId, access: &mut FilteredAccess) {
185        access.and_with(id);
186    }
187
188    fn init_nested_access(
189        _state: &Self::State,
190        _system_name: Option<&str>,
191        _component_access_set: &mut FilteredAccessSet,
192        _world: UnsafeWorldCell,
193    ) {
194    }
195
196    fn init_state(world: &mut World) -> ComponentId {
197        world.register_component::<T>()
198    }
199
200    fn get_state(components: &Components) -> Option<Self::State> {
201        components.component_id::<T>()
202    }
203
204    fn matches_component_set(
205        &id: &ComponentId,
206        set_contains_id: &impl Fn(ComponentId) -> bool,
207    ) -> bool {
208        set_contains_id(id)
209    }
210
211    fn update_archetypes(_state: &mut Self::State, _world: UnsafeWorldCell) {}
212}
213
214// SAFETY: WorldQuery impl performs no access at all
215unsafe impl<T: Component> QueryFilter for With<T> {
216    const IS_ARCHETYPAL: bool = true;
217
218    #[inline(always)]
219    unsafe fn filter_fetch(
220        _state: &Self::State,
221        _fetch: &mut Self::Fetch<'_>,
222        _entity: Entity,
223        _table_row: TableRow,
224    ) -> bool {
225        true
226    }
227}
228
229/// Filter that selects entities without a component `T`.
230///
231/// This is the negation of [`With`].
232///
233/// # Examples
234///
235/// ```
236/// # use bevy_ecs::component::Component;
237/// # use bevy_ecs::query::Without;
238/// # use bevy_ecs::system::IntoSystem;
239/// # use bevy_ecs::system::Query;
240/// #
241/// # #[derive(Component)]
242/// # struct Permit;
243/// # #[derive(Component)]
244/// # struct Name { name: &'static str };
245/// #
246/// fn no_permit_system(query: Query<&Name, Without<Permit>>) {
247///     for name in &query{
248///         println!("{} has no permit!", name.name);
249///     }
250/// }
251/// # bevy_ecs::system::assert_is_system(no_permit_system);
252/// ```
253pub struct Without<T>(PhantomData<T>);
254
255// SAFETY:
256// `update_component_access` does not add any accesses.
257// This is sound because [`QueryFilter::filter_fetch`] does not access any components.
258// `update_component_access` adds a `Without` filter for `T`.
259// This is sound because `matches_component_set` returns whether the set does not contain the component.
260unsafe impl<T: Component> WorldQuery for Without<T> {
261    type Fetch<'w> = ();
262    type State = ComponentId;
263
264    fn shrink_fetch<'wlong: 'wshort, 'wshort>(_: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {}
265
266    #[inline]
267    unsafe fn init_fetch(
268        _world: UnsafeWorldCell,
269        _state: &ComponentId,
270        _last_run: Tick,
271        _this_run: Tick,
272    ) {
273    }
274
275    const IS_DENSE: bool = {
276        match T::STORAGE_TYPE {
277            StorageType::Table => true,
278            StorageType::SparseSet => false,
279        }
280    };
281
282    #[inline]
283    unsafe fn set_archetype(
284        _fetch: &mut (),
285        _state: &ComponentId,
286        _archetype: &Archetype,
287        _table: &Table,
288    ) {
289    }
290
291    #[inline]
292    unsafe fn set_table(_fetch: &mut (), _state: &Self::State, _table: &Table) {}
293
294    #[inline]
295    fn update_component_access(&id: &ComponentId, access: &mut FilteredAccess) {
296        access.and_without(id);
297    }
298
299    fn init_nested_access(
300        _state: &Self::State,
301        _system_name: Option<&str>,
302        _component_access_set: &mut FilteredAccessSet,
303        _world: UnsafeWorldCell,
304    ) {
305    }
306
307    fn init_state(world: &mut World) -> ComponentId {
308        world.register_component::<T>()
309    }
310
311    fn get_state(components: &Components) -> Option<Self::State> {
312        components.component_id::<T>()
313    }
314
315    fn matches_component_set(
316        &id: &ComponentId,
317        set_contains_id: &impl Fn(ComponentId) -> bool,
318    ) -> bool {
319        !set_contains_id(id)
320    }
321
322    fn update_archetypes(_state: &mut Self::State, _world: UnsafeWorldCell) {}
323}
324
325// SAFETY: WorldQuery impl performs no access at all
326unsafe impl<T: Component> QueryFilter for Without<T> {
327    const IS_ARCHETYPAL: bool = true;
328
329    #[inline(always)]
330    unsafe fn filter_fetch(
331        _state: &Self::State,
332        _fetch: &mut Self::Fetch<'_>,
333        _entity: Entity,
334        _table_row: TableRow,
335    ) -> bool {
336        true
337    }
338}
339
340/// A filter that tests if any of the given filters apply.
341///
342/// This is useful for example if a system with multiple components in a query only wants to run
343/// when one or more of the components have changed.
344///
345/// The `And` equivalent to this filter is a [`prim@tuple`] testing that all the contained filters
346/// apply instead.
347///
348/// # Examples
349///
350/// ```
351/// # use bevy_ecs::component::Component;
352/// # use bevy_ecs::entity::Entity;
353/// # use bevy_ecs::query::Changed;
354/// # use bevy_ecs::query::Or;
355/// # use bevy_ecs::system::IntoSystem;
356/// # use bevy_ecs::system::Query;
357/// #
358/// # #[derive(Component, Debug)]
359/// # struct Color {};
360/// # #[derive(Component)]
361/// # struct Node {};
362/// #
363/// fn print_cool_entity_system(query: Query<Entity, Or<(Changed<Color>, Changed<Node>)>>) {
364///     for entity in &query {
365///         println!("Entity {} got a new style or color", entity);
366///     }
367/// }
368/// # bevy_ecs::system::assert_is_system(print_cool_entity_system);
369/// ```
370pub struct Or<T>(PhantomData<T>);
371
372#[doc(hidden)]
373pub struct OrFetch<'w, T: WorldQuery> {
374    fetch: T::Fetch<'w>,
375    matches: bool,
376}
377
378impl<T: WorldQuery> Clone for OrFetch<'_, T> {
379    fn clone(&self) -> Self {
380        Self {
381            fetch: self.fetch.clone(),
382            matches: self.matches,
383        }
384    }
385}
386
387macro_rules! impl_or_query_filter {
388    ($(#[$meta:meta])* $(($filter: ident, $state: ident)),*) => {
389        $(#[$meta])*
390        #[expect(
391            clippy::allow_attributes,
392            reason = "This is a tuple-related macro; as such the lints below may not always apply."
393        )]
394        #[allow(
395            non_snake_case,
396            reason = "The names of some variables are provided by the macro's caller, not by us."
397        )]
398        #[allow(
399            unused_variables,
400            reason = "Zero-length tuples won't use any of the parameters."
401        )]
402        #[allow(
403            clippy::unused_unit,
404            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."
405        )]
406        // SAFETY:
407        // [`QueryFilter::filter_fetch`] accesses are a subset of the subqueries' accesses
408        // This is sound because `update_component_access` adds accesses according to the implementations of all the subqueries.
409        // `update_component_access` replace the filters with a disjunction where every element is a conjunction of the previous filters and the filters of one of the subqueries.
410        // This is sound because `matches_component_set` returns a disjunction of the results of the subqueries' implementations.
411        unsafe impl<$($filter: QueryFilter),*> WorldQuery for Or<($($filter,)*)> {
412            type Fetch<'w> = ($(OrFetch<'w, $filter>,)*);
413            type State = ($($filter::State,)*);
414
415            fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
416                let ($($filter,)*) = fetch;
417                ($(
418                    OrFetch {
419                        fetch: $filter::shrink_fetch($filter.fetch),
420                        matches: $filter.matches
421                    },
422                )*)
423            }
424
425            const IS_DENSE: bool = true $(&& $filter::IS_DENSE)*;
426
427            #[inline]
428            unsafe fn init_fetch<'w, 's>(world: UnsafeWorldCell<'w>, state: &'s Self::State, last_run: Tick, this_run: Tick) -> Self::Fetch<'w> {
429                let ($($filter,)*) = state;
430                ($(OrFetch {
431                    // SAFETY: The invariants are upheld by the caller.
432                    fetch: unsafe { $filter::init_fetch(world, $filter, last_run, this_run) },
433                    matches: false,
434                },)*)
435            }
436
437            #[inline]
438            unsafe fn set_table<'w, 's>(fetch: &mut Self::Fetch<'w>, state: &'s Self::State, table: &'w Table) {
439                // If this is an archetypal query, then it is guaranteed to match all entities,
440                // so `filter_fetch` will ignore `$filter.matches` and we don't need to initialize it.
441                if Self::IS_ARCHETYPAL {
442                    return;
443                }
444                let ($($filter,)*) = fetch;
445                let ($($state,)*) = state;
446                $(
447                    $filter.matches = $filter::matches_component_set($state, &|id| table.has_column(id));
448                    if $filter.matches {
449                        // SAFETY: The invariants are upheld by the caller.
450                        unsafe { $filter::set_table(&mut $filter.fetch, $state, table); }
451                    }
452                )*
453            }
454
455            #[inline]
456            unsafe fn set_archetype<'w, 's>(
457                fetch: &mut Self::Fetch<'w>,
458                state: &'s Self::State,
459                archetype: &'w Archetype,
460                table: &'w Table
461            ) {
462                // If this is an archetypal query, then it is guaranteed to match all entities,
463                // so `filter_fetch` will ignore `$filter.matches` and we don't need to initialize it.
464                if Self::IS_ARCHETYPAL {
465                    return;
466                }
467                let ($($filter,)*) = fetch;
468                let ($($state,)*) = &state;
469                $(
470                    $filter.matches = $filter::matches_component_set($state, &|id| archetype.contains(id));
471                    if $filter.matches {
472                        // SAFETY: The invariants are upheld by the caller.
473                       unsafe { $filter::set_archetype(&mut $filter.fetch, $state, archetype, table); }
474                    }
475                )*
476            }
477
478            fn update_component_access(state: &Self::State, access: &mut FilteredAccess) {
479                let ($($filter,)*) = state;
480
481                let mut new_access = FilteredAccess::matches_nothing();
482
483                $(
484                    // Create an intermediate because `access`'s value needs to be preserved
485                    // for the next filter, and `_new_access` has to be modified only by `append_or` to it.
486                    let mut intermediate = access.clone();
487                    $filter::update_component_access($filter, &mut intermediate);
488                    new_access.append_or(&intermediate);
489                    // Also extend the accesses required to compute the filter. This is required because
490                    // otherwise a `Query<(), Or<(Changed<Foo>,)>` won't conflict with `Query<&mut Foo>`.
491                    new_access.extend_access(&intermediate);
492                )*
493
494                // The required components remain the same as the original `access`.
495                new_access.required = core::mem::take(&mut access.required);
496
497                *access = new_access;
498            }
499
500            fn init_nested_access(
501                state: &Self::State,
502                _system_name: Option<&str>,
503                _component_access_set: &mut FilteredAccessSet,
504                _world: UnsafeWorldCell,
505            ) {
506                let ($($state,)*) = state;
507                $($filter::init_nested_access($state, _system_name, _component_access_set, _world);)*
508            }
509
510            fn init_state(world: &mut World) -> Self::State {
511                ($($filter::init_state(world),)*)
512            }
513
514            fn get_state(components: &Components) -> Option<Self::State> {
515                Some(($($filter::get_state(components)?,)*))
516            }
517
518            fn matches_component_set(state: &Self::State, set_contains_id: &impl Fn(ComponentId) -> bool) -> bool {
519                let ($($filter,)*) = state;
520                false $(|| $filter::matches_component_set($filter, set_contains_id))*
521            }
522
523            fn update_archetypes(state: &mut Self::State, _world: UnsafeWorldCell) {
524                let ($($filter,)*) = state;
525                $($filter::update_archetypes($filter, _world);)*
526            }
527        }
528
529        #[expect(
530            clippy::allow_attributes,
531            reason = "This is a tuple-related macro; as such the lints below may not always apply."
532        )]
533        #[allow(
534            non_snake_case,
535            reason = "The names of some variables are provided by the macro's caller, not by us."
536        )]
537        #[allow(
538            unused_variables,
539            reason = "Zero-length tuples won't use any of the parameters."
540        )]
541        $(#[$meta])*
542        // SAFETY: This only performs access that subqueries perform, and they impl `QueryFilter` and so perform no mutable access.
543        unsafe impl<$($filter: QueryFilter),*> QueryFilter for Or<($($filter,)*)> {
544            const IS_ARCHETYPAL: bool = true $(&& $filter::IS_ARCHETYPAL)*;
545
546            #[inline(always)]
547            unsafe fn filter_fetch(
548                state: &Self::State,
549                fetch: &mut Self::Fetch<'_>,
550                entity: Entity,
551                table_row: TableRow
552            ) -> bool {
553                let ($($state,)*) = state;
554                let ($($filter,)*) = fetch;
555                // If this is an archetypal query, then it is guaranteed to return true,
556                // and we can help the compiler remove branches by checking the const `IS_ARCHETYPAL` first.
557                (Self::IS_ARCHETYPAL
558                    // SAFETY: The invariants are upheld by the caller.
559                    $(|| ($filter.matches && unsafe { $filter::filter_fetch($state, &mut $filter.fetch, entity, table_row) }))*
560                    // If *none* of the subqueries matched the archetype, then this archetype was added in a transmute.
561                    // We must treat those as matching in order to be consistent with `size_hint` for archetypal queries,
562                    // so we treat them as matching for non-archetypal queries, as well.
563                    || !(false $(|| $filter.matches)*))
564            }
565        }
566    };
567}
568
569macro_rules! impl_tuple_query_filter {
570    ($(#[$meta:meta])* $(($name: ident, $state: ident)),*) => {
571        #[expect(
572            clippy::allow_attributes,
573            reason = "This is a tuple-related macro; as such the lints below may not always apply."
574        )]
575        #[allow(
576            non_snake_case,
577            reason = "The names of some variables are provided by the macro's caller, not by us."
578        )]
579        #[allow(
580            unused_variables,
581            reason = "Zero-length tuples won't use any of the parameters."
582        )]
583        $(#[$meta])*
584        // SAFETY: This only performs access that subqueries perform, and they impl `QueryFilter` and so perform no mutable access.
585        unsafe impl<$($name: QueryFilter),*> QueryFilter for ($($name,)*) {
586            const IS_ARCHETYPAL: bool = true $(&& $name::IS_ARCHETYPAL)*;
587
588            #[inline(always)]
589            unsafe fn filter_fetch(
590                state: &Self::State,
591                fetch: &mut Self::Fetch<'_>,
592                entity: Entity,
593                table_row: TableRow
594            ) -> bool {
595                let ($($state,)*) = state;
596                let ($($name,)*) = fetch;
597                // SAFETY: The invariants are upheld by the caller.
598                true $(&& unsafe { $name::filter_fetch($state, $name, entity, table_row) })*
599            }
600        }
601    };
602}
603
604all_tuples!(
605    #[doc(fake_variadic)]
606    impl_tuple_query_filter,
607    0,
608    15,
609    F,
610    S
611);
612all_tuples!(
613    #[doc(fake_variadic)]
614    impl_or_query_filter,
615    0,
616    15,
617    F,
618    S
619);
620
621/// Allows a query to contain entities with the component `T`, bypassing [`DefaultQueryFilters`].
622///
623/// [`DefaultQueryFilters`]: crate::entity_disabling::DefaultQueryFilters
624pub struct Allow<T>(PhantomData<T>);
625
626// SAFETY:
627// `update_component_access` does not add any accesses.
628// This is sound because [`QueryFilter::filter_fetch`] does not access any components.
629// `update_component_access` adds an archetypal filter for `T`.
630// This is sound because it doesn't affect the query
631unsafe impl<T: Component> WorldQuery for Allow<T> {
632    type Fetch<'w> = ();
633    type State = ComponentId;
634
635    fn shrink_fetch<'wlong: 'wshort, 'wshort>(_: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {}
636
637    #[inline]
638    unsafe fn init_fetch(_: UnsafeWorldCell, _: &ComponentId, _: Tick, _: Tick) {}
639
640    // Even if the component is sparse, this implementation doesn't do anything with it
641    const IS_DENSE: bool = true;
642
643    #[inline]
644    unsafe fn set_archetype(_: &mut (), _: &ComponentId, _: &Archetype, _: &Table) {}
645
646    #[inline]
647    unsafe fn set_table(_: &mut (), _: &ComponentId, _: &Table) {}
648
649    #[inline]
650    fn update_component_access(&id: &ComponentId, access: &mut FilteredAccess) {
651        access.access_mut().add_archetypal(id);
652    }
653
654    fn init_nested_access(
655        _state: &Self::State,
656        _system_name: Option<&str>,
657        _component_access_set: &mut FilteredAccessSet,
658        _world: UnsafeWorldCell,
659    ) {
660    }
661
662    fn init_state(world: &mut World) -> ComponentId {
663        world.register_component::<T>()
664    }
665
666    fn get_state(components: &Components) -> Option<Self::State> {
667        components.component_id::<T>()
668    }
669
670    fn matches_component_set(_: &ComponentId, _: &impl Fn(ComponentId) -> bool) -> bool {
671        // Allow<T> always matches
672        true
673    }
674
675    fn update_archetypes(_state: &mut Self::State, _world: UnsafeWorldCell) {}
676}
677
678// SAFETY: WorldQuery impl performs no access at all
679unsafe impl<T: Component> QueryFilter for Allow<T> {
680    const IS_ARCHETYPAL: bool = true;
681
682    #[inline(always)]
683    unsafe fn filter_fetch(
684        _: &Self::State,
685        _: &mut Self::Fetch<'_>,
686        _: Entity,
687        _: TableRow,
688    ) -> bool {
689        true
690    }
691}
692
693/// A filter on a component that only retains results the first time after they have been added.
694///
695/// A common use for this filter is one-time initialization.
696///
697/// To retain all results without filtering but still check whether they were added after the
698/// system last ran, use [`Ref<T>`](crate::change_detection::Ref).
699///
700/// **Note** that this includes changes that happened before the first time this `Query` was run.
701///
702/// # Deferred
703///
704/// Note, that entity modifications issued with [`Commands`](crate::system::Commands)
705/// are visible only after deferred operations are applied, typically after the system
706/// that queued them.
707///
708/// # Time complexity
709///
710/// `Added` is not [`ArchetypeFilter`], which practically means that
711/// if the query (with `T` component filter) matches a million entities,
712/// `Added<T>` filter will iterate over all of them even if none of them were just added.
713///
714/// For example, these two systems are roughly equivalent in terms of performance:
715///
716/// ```
717/// # use bevy_ecs::change_detection::{DetectChanges, Ref};
718/// # use bevy_ecs::entity::Entity;
719/// # use bevy_ecs::query::Added;
720/// # use bevy_ecs::system::Query;
721/// # use bevy_ecs_macros::Component;
722/// # #[derive(Component)]
723/// # struct MyComponent;
724/// # #[derive(Component)]
725/// # struct Transform;
726///
727/// fn system1(q: Query<&MyComponent, Added<Transform>>) {
728///     for item in &q { /* component added */ }
729/// }
730///
731/// fn system2(q: Query<(&MyComponent, Ref<Transform>)>) {
732///     for item in &q {
733///         if item.1.is_added() { /* component added */ }
734///     }
735/// }
736/// ```
737///
738/// # Examples
739///
740/// ```
741/// # use bevy_ecs::component::Component;
742/// # use bevy_ecs::query::Added;
743/// # use bevy_ecs::system::IntoSystem;
744/// # use bevy_ecs::system::Query;
745/// #
746/// # #[derive(Component, Debug)]
747/// # struct Name {};
748///
749/// fn print_add_name_component(query: Query<&Name, Added<Name>>) {
750///     for name in &query {
751///         println!("Named entity created: {:?}", name)
752///     }
753/// }
754///
755/// # bevy_ecs::system::assert_is_system(print_add_name_component);
756/// ```
757pub struct Added<T>(PhantomData<T>);
758
759#[doc(hidden)]
760pub struct AddedFetch<'w, T: Component> {
761    ticks: StorageSwitch<
762        T,
763        // T::STORAGE_TYPE = StorageType::Table
764        Option<ThinSlicePtr<'w, UnsafeCell<Tick>>>,
765        // T::STORAGE_TYPE = StorageType::SparseSet
766        // Can be `None` when the component has never been inserted
767        Option<&'w ComponentSparseSet>,
768    >,
769    last_run: Tick,
770    this_run: Tick,
771}
772
773impl<T: Component> Clone for AddedFetch<'_, T> {
774    fn clone(&self) -> Self {
775        Self {
776            ticks: self.ticks,
777            last_run: self.last_run,
778            this_run: self.this_run,
779        }
780    }
781}
782
783// SAFETY:
784// [`QueryFilter::filter_fetch`] accesses a single component in a readonly way.
785// This is sound because `update_component_access` adds read access for that component and panics when appropriate.
786// `update_component_access` adds a `With` filter for a component.
787// This is sound because `matches_component_set` returns whether the set contains that component.
788unsafe impl<T: Component> WorldQuery for Added<T> {
789    type Fetch<'w> = AddedFetch<'w, T>;
790    type State = ComponentId;
791
792    fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
793        fetch
794    }
795
796    #[inline]
797    unsafe fn init_fetch<'w, 's>(
798        world: UnsafeWorldCell<'w>,
799        &id: &'s ComponentId,
800        last_run: Tick,
801        this_run: Tick,
802    ) -> Self::Fetch<'w> {
803        Self::Fetch::<'w> {
804            ticks: StorageSwitch::new(
805                || None,
806                || {
807                    // SAFETY: The underlying type associated with `component_id` is `T`,
808                    // which we are allowed to access since we registered it in `update_component_access`.
809                    // Note that we do not actually access any components' ticks in this function, we just get a shared
810                    // reference to the sparse set, which is used to access the components' ticks in `Self::fetch`.
811                    unsafe { world.storages().sparse_sets.get(id) }
812                },
813            ),
814            last_run,
815            this_run,
816        }
817    }
818
819    const IS_DENSE: bool = {
820        match T::STORAGE_TYPE {
821            StorageType::Table => true,
822            StorageType::SparseSet => false,
823        }
824    };
825
826    #[inline]
827    unsafe fn set_archetype<'w, 's>(
828        fetch: &mut Self::Fetch<'w>,
829        component_id: &'s ComponentId,
830        _archetype: &'w Archetype,
831        table: &'w Table,
832    ) {
833        if Self::IS_DENSE {
834            // SAFETY: `set_archetype`'s safety rules are a super set of the `set_table`'s ones.
835            unsafe {
836                Self::set_table(fetch, component_id, table);
837            }
838        }
839    }
840
841    #[inline]
842    unsafe fn set_table<'w, 's>(
843        fetch: &mut Self::Fetch<'w>,
844        &component_id: &'s ComponentId,
845        table: &'w Table,
846    ) {
847        let table_ticks = Some(
848            table
849                .get_added_ticks_slice_for(component_id)
850                .debug_checked_unwrap()
851                .into(),
852        );
853        // SAFETY: set_table is only called when T::STORAGE_TYPE = StorageType::Table
854        unsafe { fetch.ticks.set_table(table_ticks) };
855    }
856
857    #[inline]
858    fn update_component_access(&id: &ComponentId, access: &mut FilteredAccess) {
859        if access.access().has_write(id) {
860            panic!("$state_name<{}> conflicts with a previous access in this query. Shared access cannot coincide with exclusive access.", DebugName::type_name::<T>());
861        }
862        access.add_read(id);
863    }
864
865    fn init_nested_access(
866        _state: &Self::State,
867        _system_name: Option<&str>,
868        _component_access_set: &mut FilteredAccessSet,
869        _world: UnsafeWorldCell,
870    ) {
871    }
872
873    fn init_state(world: &mut World) -> ComponentId {
874        world.register_component::<T>()
875    }
876
877    fn get_state(components: &Components) -> Option<ComponentId> {
878        components.component_id::<T>()
879    }
880
881    fn matches_component_set(
882        &id: &ComponentId,
883        set_contains_id: &impl Fn(ComponentId) -> bool,
884    ) -> bool {
885        set_contains_id(id)
886    }
887
888    fn update_archetypes(_state: &mut Self::State, _world: UnsafeWorldCell) {}
889}
890
891// SAFETY: WorldQuery impl performs only read access on ticks
892unsafe impl<T: Component> QueryFilter for Added<T> {
893    const IS_ARCHETYPAL: bool = false;
894    #[inline(always)]
895    unsafe fn filter_fetch(
896        _state: &Self::State,
897        fetch: &mut Self::Fetch<'_>,
898        entity: Entity,
899        table_row: TableRow,
900    ) -> bool {
901        // SAFETY: The invariants are upheld by the caller.
902        fetch.ticks.extract(
903            |table| {
904                // SAFETY: set_table was previously called
905                let table = unsafe { table.debug_checked_unwrap() };
906                // SAFETY: The caller ensures `table_row` is in range.
907                let tick = unsafe { table.get_unchecked(table_row.index()) };
908
909                tick.deref().is_newer_than(fetch.last_run, fetch.this_run)
910            },
911            |sparse_set| {
912                // SAFETY: The caller ensures `entity` is in range.
913                let tick = unsafe {
914                    sparse_set
915                        .debug_checked_unwrap()
916                        .get_added_tick(entity)
917                        .debug_checked_unwrap()
918                };
919
920                tick.deref().is_newer_than(fetch.last_run, fetch.this_run)
921            },
922        )
923    }
924}
925
926/// A filter on a component that only retains results the first time after they have been added or mutably dereferenced.
927///
928/// A common use for this filter is avoiding redundant work when values have not changed.
929///
930/// **Note** that simply *mutably dereferencing* a component is considered a change ([`DerefMut`](std::ops::DerefMut)).
931/// Bevy does not compare components to their previous values.
932///
933/// To retain all results without filtering but still check whether they were changed after the
934/// system last ran, use [`Ref<T>`](crate::change_detection::Ref).
935///
936/// **Note** that this includes changes that happened before the first time this `Query` was run.
937///
938/// # Deferred
939///
940/// Note, that entity modifications issued with [`Commands`](crate::system::Commands)
941/// (like entity creation or entity component addition or removal) are visible only
942/// after deferred operations are applied, typically after the system that queued them.
943///
944/// # Time complexity
945///
946/// `Changed` is not [`ArchetypeFilter`], which practically means that
947/// if query (with `T` component filter) matches million entities,
948/// `Changed<T>` filter will iterate over all of them even if none of them were changed.
949///
950/// For example, these two systems are roughly equivalent in terms of performance:
951///
952/// ```
953/// # use bevy_ecs::change_detection::DetectChanges;
954/// # use bevy_ecs::entity::Entity;
955/// # use bevy_ecs::query::Changed;
956/// # use bevy_ecs::system::Query;
957/// # use bevy_ecs::world::Ref;
958/// # use bevy_ecs_macros::Component;
959/// # #[derive(Component)]
960/// # struct MyComponent;
961/// # #[derive(Component)]
962/// # struct Transform;
963///
964/// fn system1(q: Query<&MyComponent, Changed<Transform>>) {
965///     for item in &q { /* component changed */ }
966/// }
967///
968/// fn system2(q: Query<(&MyComponent, Ref<Transform>)>) {
969///     for item in &q {
970///         if item.1.is_changed() { /* component changed */ }
971///     }
972/// }
973/// ```
974///
975/// # Examples
976///
977/// ```
978/// # use bevy_ecs::component::Component;
979/// # use bevy_ecs::query::Changed;
980/// # use bevy_ecs::system::IntoSystem;
981/// # use bevy_ecs::system::Query;
982/// #
983/// # #[derive(Component, Debug)]
984/// # struct Name {};
985/// # #[derive(Component)]
986/// # struct Transform {};
987///
988/// fn print_moving_objects_system(query: Query<&Name, Changed<Transform>>) {
989///     for name in &query {
990///         println!("Entity Moved: {:?}", name);
991///     }
992/// }
993///
994/// # bevy_ecs::system::assert_is_system(print_moving_objects_system);
995/// ```
996pub struct Changed<T>(PhantomData<T>);
997
998#[doc(hidden)]
999pub struct ChangedFetch<'w, T: Component> {
1000    ticks: StorageSwitch<
1001        T,
1002        Option<ThinSlicePtr<'w, UnsafeCell<Tick>>>,
1003        // Can be `None` when the component has never been inserted
1004        Option<&'w ComponentSparseSet>,
1005    >,
1006    last_run: Tick,
1007    this_run: Tick,
1008}
1009
1010impl<T: Component> Clone for ChangedFetch<'_, T> {
1011    fn clone(&self) -> Self {
1012        Self {
1013            ticks: self.ticks,
1014            last_run: self.last_run,
1015            this_run: self.this_run,
1016        }
1017    }
1018}
1019
1020// SAFETY:
1021// `fetch` accesses a single component in a readonly way.
1022// This is sound because `update_component_access` add read access for that component and panics when appropriate.
1023// `update_component_access` adds a `With` filter for a component.
1024// This is sound because `matches_component_set` returns whether the set contains that component.
1025unsafe impl<T: Component> WorldQuery for Changed<T> {
1026    type Fetch<'w> = ChangedFetch<'w, T>;
1027    type State = ComponentId;
1028
1029    fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
1030        fetch
1031    }
1032
1033    #[inline]
1034    unsafe fn init_fetch<'w, 's>(
1035        world: UnsafeWorldCell<'w>,
1036        &id: &'s ComponentId,
1037        last_run: Tick,
1038        this_run: Tick,
1039    ) -> Self::Fetch<'w> {
1040        Self::Fetch::<'w> {
1041            ticks: StorageSwitch::new(
1042                || None,
1043                || {
1044                    // SAFETY: The underlying type associated with `component_id` is `T`,
1045                    // which we are allowed to access since we registered it in `update_component_access`.
1046                    // Note that we do not actually access any components' ticks in this function, we just get a shared
1047                    // reference to the sparse set, which is used to access the components' ticks in `Self::fetch`.
1048                    unsafe { world.storages().sparse_sets.get(id) }
1049                },
1050            ),
1051            last_run,
1052            this_run,
1053        }
1054    }
1055
1056    const IS_DENSE: bool = {
1057        match T::STORAGE_TYPE {
1058            StorageType::Table => true,
1059            StorageType::SparseSet => false,
1060        }
1061    };
1062
1063    #[inline]
1064    unsafe fn set_archetype<'w, 's>(
1065        fetch: &mut Self::Fetch<'w>,
1066        component_id: &'s ComponentId,
1067        _archetype: &'w Archetype,
1068        table: &'w Table,
1069    ) {
1070        if Self::IS_DENSE {
1071            // SAFETY: `set_archetype`'s safety rules are a super set of the `set_table`'s ones.
1072            unsafe {
1073                Self::set_table(fetch, component_id, table);
1074            }
1075        }
1076    }
1077
1078    #[inline]
1079    unsafe fn set_table<'w, 's>(
1080        fetch: &mut Self::Fetch<'w>,
1081        &component_id: &'s ComponentId,
1082        table: &'w Table,
1083    ) {
1084        let table_ticks = Some(
1085            table
1086                .get_changed_ticks_slice_for(component_id)
1087                .debug_checked_unwrap()
1088                .into(),
1089        );
1090        // SAFETY: set_table is only called when T::STORAGE_TYPE = StorageType::Table
1091        unsafe { fetch.ticks.set_table(table_ticks) };
1092    }
1093
1094    #[inline]
1095    fn update_component_access(&id: &ComponentId, access: &mut FilteredAccess) {
1096        if access.access().has_write(id) {
1097            panic!("$state_name<{}> conflicts with a previous access in this query. Shared access cannot coincide with exclusive access.", DebugName::type_name::<T>());
1098        }
1099        access.add_read(id);
1100    }
1101
1102    fn init_nested_access(
1103        _state: &Self::State,
1104        _system_name: Option<&str>,
1105        _component_access_set: &mut FilteredAccessSet,
1106        _world: UnsafeWorldCell,
1107    ) {
1108    }
1109
1110    fn init_state(world: &mut World) -> ComponentId {
1111        world.register_component::<T>()
1112    }
1113
1114    fn get_state(components: &Components) -> Option<ComponentId> {
1115        components.component_id::<T>()
1116    }
1117
1118    fn matches_component_set(
1119        &id: &ComponentId,
1120        set_contains_id: &impl Fn(ComponentId) -> bool,
1121    ) -> bool {
1122        set_contains_id(id)
1123    }
1124
1125    fn update_archetypes(_state: &mut Self::State, _world: UnsafeWorldCell) {}
1126}
1127
1128// SAFETY: WorldQuery impl performs only read access on ticks
1129unsafe impl<T: Component> QueryFilter for Changed<T> {
1130    const IS_ARCHETYPAL: bool = false;
1131
1132    #[inline(always)]
1133    unsafe fn filter_fetch(
1134        _state: &Self::State,
1135        fetch: &mut Self::Fetch<'_>,
1136        entity: Entity,
1137        table_row: TableRow,
1138    ) -> bool {
1139        // SAFETY: The invariants are upheld by the caller.
1140        fetch.ticks.extract(
1141            |table| {
1142                // SAFETY: set_table was previously called
1143                let table = unsafe { table.debug_checked_unwrap() };
1144                // SAFETY: The caller ensures `table_row` is in range.
1145                let tick = unsafe { table.get_unchecked(table_row.index()) };
1146
1147                tick.deref().is_newer_than(fetch.last_run, fetch.this_run)
1148            },
1149            |sparse_set| {
1150                // SAFETY: The caller ensures `entity` is in range.
1151                let tick = unsafe {
1152                    sparse_set
1153                        .debug_checked_unwrap()
1154                        .get_changed_tick(entity)
1155                        .debug_checked_unwrap()
1156                };
1157
1158                tick.deref().is_newer_than(fetch.last_run, fetch.this_run)
1159            },
1160        )
1161    }
1162}
1163
1164/// A filter that only retains results the first time after the entity has been spawned.
1165///
1166/// A common use for this filter is one-time initialization.
1167///
1168/// To retain all results without filtering but still check whether they were spawned after the
1169/// system last ran, use [`SpawnDetails`](crate::query::SpawnDetails) instead.
1170///
1171/// **Note** that this includes entities that spawned before the first time this Query was run.
1172///
1173/// # Deferred
1174///
1175/// Note, that entity spawns issued with [`Commands`](crate::system::Commands)
1176/// are visible only after deferred operations are applied, typically after the
1177/// system that queued them.
1178///
1179/// # Time complexity
1180///
1181/// `Spawned` is not [`ArchetypeFilter`], which practically means that if query matches million
1182/// entities, `Spawned` filter will iterate over all of them even if none of them were spawned.
1183///
1184/// For example, these two systems are roughly equivalent in terms of performance:
1185///
1186/// ```
1187/// # use bevy_ecs::entity::Entity;
1188/// # use bevy_ecs::system::Query;
1189/// # use bevy_ecs::query::Spawned;
1190/// # use bevy_ecs::query::SpawnDetails;
1191///
1192/// fn system1(query: Query<Entity, Spawned>) {
1193///     for entity in &query { /* entity spawned */ }
1194/// }
1195///
1196/// fn system2(query: Query<(Entity, SpawnDetails)>) {
1197///     for (entity, spawned) in &query {
1198///         if spawned.is_spawned() { /* entity spawned */ }
1199///     }
1200/// }
1201/// ```
1202///
1203/// # Examples
1204///
1205/// ```
1206/// # use bevy_ecs::component::Component;
1207/// # use bevy_ecs::query::Spawned;
1208/// # use bevy_ecs::system::IntoSystem;
1209/// # use bevy_ecs::system::Query;
1210/// #
1211/// # #[derive(Component, Debug)]
1212/// # struct Name {};
1213///
1214/// fn print_spawning_entities(query: Query<&Name, Spawned>) {
1215///     for name in &query {
1216///         println!("Entity spawned: {:?}", name);
1217///     }
1218/// }
1219///
1220/// # bevy_ecs::system::assert_is_system(print_spawning_entities);
1221/// ```
1222pub struct Spawned;
1223
1224#[doc(hidden)]
1225#[derive(Clone)]
1226pub struct SpawnedFetch<'w> {
1227    entities: &'w Entities,
1228    last_run: Tick,
1229    this_run: Tick,
1230}
1231
1232// SAFETY: WorldQuery impl accesses no components or component ticks
1233unsafe impl WorldQuery for Spawned {
1234    type Fetch<'w> = SpawnedFetch<'w>;
1235    type State = ();
1236
1237    fn shrink_fetch<'wlong: 'wshort, 'wshort>(fetch: Self::Fetch<'wlong>) -> Self::Fetch<'wshort> {
1238        fetch
1239    }
1240
1241    #[inline]
1242    unsafe fn init_fetch<'w, 's>(
1243        world: UnsafeWorldCell<'w>,
1244        _state: &'s (),
1245        last_run: Tick,
1246        this_run: Tick,
1247    ) -> Self::Fetch<'w> {
1248        SpawnedFetch {
1249            entities: world.entities(),
1250            last_run,
1251            this_run,
1252        }
1253    }
1254
1255    const IS_DENSE: bool = true;
1256
1257    #[inline]
1258    unsafe fn set_archetype<'w, 's>(
1259        _fetch: &mut Self::Fetch<'w>,
1260        _state: &'s (),
1261        _archetype: &'w Archetype,
1262        _table: &'w Table,
1263    ) {
1264    }
1265
1266    #[inline]
1267    unsafe fn set_table<'w, 's>(_fetch: &mut Self::Fetch<'w>, _state: &'s (), _table: &'w Table) {}
1268
1269    #[inline]
1270    fn update_component_access(_state: &(), _access: &mut FilteredAccess) {}
1271
1272    fn init_nested_access(
1273        _state: &Self::State,
1274        _system_name: Option<&str>,
1275        _component_access_set: &mut FilteredAccessSet,
1276        _world: UnsafeWorldCell,
1277    ) {
1278    }
1279
1280    fn init_state(_world: &mut World) {}
1281
1282    fn get_state(_components: &Components) -> Option<()> {
1283        Some(())
1284    }
1285
1286    fn matches_component_set(_state: &(), _set_contains_id: &impl Fn(ComponentId) -> bool) -> bool {
1287        true
1288    }
1289
1290    fn update_archetypes(_state: &mut Self::State, _world: UnsafeWorldCell) {}
1291}
1292
1293// SAFETY: WorldQuery impl accesses no components or component ticks
1294unsafe impl QueryFilter for Spawned {
1295    const IS_ARCHETYPAL: bool = false;
1296
1297    #[inline(always)]
1298    unsafe fn filter_fetch(
1299        _state: &Self::State,
1300        fetch: &mut Self::Fetch<'_>,
1301        entity: Entity,
1302        _table_row: TableRow,
1303    ) -> bool {
1304        // SAFETY: only living entities are queried
1305        let spawned = unsafe {
1306            fetch
1307                .entities
1308                .entity_get_spawned_or_despawned_unchecked(entity)
1309                .1
1310        };
1311        spawned.is_newer_than(fetch.last_run, fetch.this_run)
1312    }
1313}
1314
1315/// A marker trait to indicate that the filter works at an archetype level.
1316///
1317/// This is needed to:
1318/// - implement [`ExactSizeIterator`] for [`QueryIter`](crate::query::QueryIter) that contains archetype-level filters.
1319/// - ensure table filtering for [`QueryContiguousIter`](crate::query::QueryContiguousIter).
1320///
1321/// The trait must only be implemented for filters where its corresponding [`QueryFilter::IS_ARCHETYPAL`]
1322/// is [`prim@true`]. As such, only the [`With`] and [`Without`] filters can implement the trait.
1323/// [Tuples](prim@tuple) and [`Or`] filters are automatically implemented with the trait only if its containing types
1324/// also implement the same trait.
1325///
1326/// [`Added`], [`Changed`] and [`Spawned`] work with entities, and therefore are not archetypal. As such
1327/// they do not implement [`ArchetypeFilter`].
1328#[diagnostic::on_unimplemented(
1329    message = "`{Self}` is not a valid `Query` filter based on archetype information",
1330    label = "invalid `Query` filter",
1331    note = "an `ArchetypeFilter` typically uses a combination of `With<T>` and `Without<T>` statements"
1332)]
1333pub trait ArchetypeFilter: QueryFilter {}
1334
1335impl<T: Component> ArchetypeFilter for With<T> {}
1336
1337impl<T: Component> ArchetypeFilter for Without<T> {}
1338
1339macro_rules! impl_archetype_filter_tuple {
1340    ($(#[$meta:meta])* $($filter: ident),*) => {
1341        $(#[$meta])*
1342        impl<$($filter: ArchetypeFilter),*> ArchetypeFilter for ($($filter,)*) {}
1343    };
1344}
1345
1346macro_rules! impl_archetype_or_filter_tuple {
1347    ($(#[$meta:meta])* $($filter: ident),*) => {
1348        $(#[$meta])*
1349        impl<$($filter: ArchetypeFilter),*> ArchetypeFilter for Or<($($filter,)*)> {}
1350    };
1351}
1352
1353all_tuples!(
1354    #[doc(fake_variadic)]
1355    impl_archetype_filter_tuple,
1356    0,
1357    15,
1358    F
1359);
1360
1361all_tuples!(
1362    #[doc(fake_variadic)]
1363    impl_archetype_or_filter_tuple,
1364    0,
1365    15,
1366    F
1367);