bevy_ecs/query/
filter.rs

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