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