bevy_ecs/query/
filter.rs

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