Skip to main content

bevy_ecs/system/
system_param.rs

1#![expect(
2    unsafe_op_in_unsafe_fn,
3    reason = "See #11590. To be removed once all applicable unsafe code has an unsafe block with a safety comment."
4)]
5
6pub use crate::change_detection::{NonSend, NonSendMut, Res, ResMut};
7use crate::{
8    archetype::Archetypes,
9    bundle::Bundles,
10    change_detection::{ComponentTicksMut, ComponentTicksRef, Tick},
11    component::{ComponentId, Components, Mutable},
12    entity::{Entities, EntityAllocator},
13    query::{
14        Access, FilteredAccess, FilteredAccessSet, IterQueryData, QueryData, QueryFilter,
15        QuerySingleError, QueryState, ReadOnlyQueryData,
16    },
17    resource::{Resource, IS_RESOURCE},
18    system::{Query, Single, SystemMeta},
19    world::{
20        unsafe_world_cell::UnsafeWorldCell, DeferredWorld, FilteredResources, FilteredResourcesMut,
21        FromWorld, World,
22    },
23};
24use alloc::{borrow::Cow, boxed::Box, vec::Vec};
25pub use bevy_ecs_macros::SystemParam;
26use bevy_platform::cell::SyncCell;
27use bevy_ptr::UnsafeCellDeref;
28use bevy_utils::prelude::DebugName;
29use core::{
30    any::Any,
31    fmt::{Debug, Display},
32    marker::PhantomData,
33    ops::{Deref, DerefMut},
34};
35use smallvec::SmallVec;
36use thiserror::Error;
37
38use super::Populated;
39use variadics_please::{all_tuples, all_tuples_enumerated};
40
41/// A parameter that can be used in a [`System`](super::System).
42///
43/// # Derive
44///
45/// This trait can be derived with the [`derive@super::SystemParam`] macro.
46/// This macro only works if each field on the derived struct implements [`SystemParam`].
47/// Note: There are additional requirements on the field types.
48/// See the *Generic `SystemParam`s* section for details and workarounds of the probable
49/// cause if this derive causes an error to be emitted.
50///
51/// Derived `SystemParam` structs may have two lifetimes: `'w` for data stored in the [`World`],
52/// and `'s` for data stored in the parameter's state.
53///
54/// The following list shows the most common [`SystemParam`]s and which lifetime they require
55///
56/// ```
57/// # use bevy_ecs::prelude::*;
58/// # #[derive(Component)]
59/// # struct SomeComponent;
60/// # #[derive(Resource)]
61/// # struct SomeResource;
62/// # #[derive(Message)]
63/// # struct SomeMessage;
64/// # #[derive(Resource)]
65/// # struct SomeOtherResource;
66/// # use bevy_ecs::system::SystemParam;
67/// # #[derive(SystemParam)]
68/// # struct ParamsExample<'w, 's> {
69/// #    query:
70/// Query<'w, 's, Entity>,
71/// #    query2:
72/// Query<'w, 's, &'static SomeComponent>,
73/// #    res:
74/// Res<'w, SomeResource>,
75/// #    res_mut:
76/// ResMut<'w, SomeOtherResource>,
77/// #    local:
78/// Local<'s, u8>,
79/// #    commands:
80/// Commands<'w, 's>,
81/// #    message_reader:
82/// MessageReader<'w, 's, SomeMessage>,
83/// #    message_writer:
84/// MessageWriter<'w, SomeMessage>
85/// # }
86/// ```
87/// ## `PhantomData`
88///
89/// [`PhantomData`] is a special type of `SystemParam` that does nothing.
90/// This is useful for constraining generic types or lifetimes.
91///
92/// # Example
93///
94/// ```
95/// # use bevy_ecs::prelude::*;
96/// # #[derive(Resource)]
97/// # struct SomeResource;
98/// use std::marker::PhantomData;
99/// use bevy_ecs::system::SystemParam;
100///
101/// #[derive(SystemParam)]
102/// struct MyParam<'w, Marker: 'static> {
103///     foo: Res<'w, SomeResource>,
104///     marker: PhantomData<Marker>,
105/// }
106///
107/// fn my_system<T: 'static>(param: MyParam<T>) {
108///     // Access the resource through `param.foo`
109/// }
110///
111/// # bevy_ecs::system::assert_is_system(my_system::<()>);
112/// ```
113///
114/// # Generic `SystemParam`s
115///
116/// When using the derive macro, you may see an error in the form of:
117///
118/// ```text
119/// expected ... [ParamType]
120/// found associated type `<[ParamType] as SystemParam>::Item<'_, '_>`
121/// ```
122/// where `[ParamType]` is the type of one of your fields.
123/// To solve this error, you can wrap the field of type `[ParamType]` with [`StaticSystemParam`]
124/// (i.e. `StaticSystemParam<[ParamType]>`).
125///
126/// ## Details
127///
128/// The derive macro requires that the [`SystemParam`] implementation of
129/// each field `F`'s [`Item`](`SystemParam::Item`)'s is itself `F`
130/// (ignoring lifetimes for simplicity).
131/// This assumption is due to type inference reasons, so that the derived [`SystemParam`] can be
132/// used as an argument to a function system.
133/// If the compiler cannot validate this property for `[ParamType]`, it will error in the form shown above.
134///
135/// This will most commonly occur when working with `SystemParam`s generically, as the requirement
136/// has not been proven to the compiler.
137///
138/// ## Custom Validation Messages
139///
140/// When using the derive macro, any [`SystemParamValidationError`]s will be propagated from the sub-parameters.
141/// If you want to override the error message, add a `#[system_param(validation_message = "New message")]` attribute to the parameter.
142///
143/// ```
144/// # use bevy_ecs::prelude::*;
145/// # #[derive(Resource)]
146/// # struct SomeResource;
147/// # use bevy_ecs::system::SystemParam;
148/// #
149/// #[derive(SystemParam)]
150/// struct MyParam<'w> {
151///     #[system_param(validation_message = "Custom Message")]
152///     foo: Res<'w, SomeResource>,
153/// }
154///
155/// let mut world = World::new();
156/// let err = world.run_system_cached(|param: MyParam| {}).unwrap_err();
157/// let expected = "Parameter `MyParam::foo` failed validation: Custom Message";
158/// # #[cfg(feature="Trace")] // Without debug_utils/debug enabled MyParam::foo is stripped and breaks the assert
159/// assert!(err.to_string().contains(expected));
160/// ```
161///
162/// ## Builders
163///
164/// If you want to use a [`SystemParamBuilder`](crate::system::SystemParamBuilder) with a derived [`SystemParam`] implementation,
165/// add a `#[system_param(builder)]` attribute to the struct.
166/// This will generate a builder struct whose name is the param struct suffixed with `Builder`.
167/// The builder will not be `pub`, so you may want to expose a method that returns an `impl SystemParamBuilder<T>`.
168///
169/// ```
170/// mod custom_param {
171/// #     use bevy_ecs::{
172/// #         prelude::*,
173/// #         system::{LocalBuilder, QueryParamBuilder, SystemParam},
174/// #     };
175/// #
176///     #[derive(SystemParam)]
177///     #[system_param(builder)]
178///     pub struct CustomParam<'w, 's> {
179///         query: Query<'w, 's, ()>,
180///         local: Local<'s, usize>,
181///     }
182///
183///     impl<'w, 's> CustomParam<'w, 's> {
184///         pub fn builder(
185///             local: usize,
186///             query: impl FnOnce(&mut QueryBuilder<()>),
187///         ) -> impl SystemParamBuilder<Self> {
188///             CustomParamBuilder {
189///                 local: LocalBuilder(local),
190///                 query: QueryParamBuilder::new(query),
191///             }
192///         }
193///     }
194/// }
195///
196/// use custom_param::CustomParam;
197///
198/// # use bevy_ecs::prelude::*;
199/// # #[derive(Component)]
200/// # struct A;
201/// #
202/// # let mut world = World::new();
203/// #
204/// let system = (CustomParam::builder(100, |builder| {
205///     builder.with::<A>();
206/// }),)
207///     .build_state(&mut world)
208///     .build_system(|param: CustomParam| {});
209/// ```
210///
211/// # Safety
212///
213/// The implementor must ensure the following is true.
214/// - [`SystemParam::init_access`] correctly registers all [`World`] accesses used
215///   by [`SystemParam::get_param`] with the provided [`system_meta`](SystemMeta).
216/// - None of the world accesses may conflict with any prior accesses registered
217///   on `system_meta`.
218pub unsafe trait SystemParam: Sized {
219    /// Used to store data which persists across invocations of a system.
220    type State: Send + Sync + 'static;
221
222    /// The item type returned when constructing this system param.
223    /// The value of this associated type should be `Self`, instantiated with new lifetimes.
224    ///
225    /// You could think of [`SystemParam::Item<'w, 's>`] as being an *operation* that changes the lifetimes bound to `Self`.
226    type Item<'world, 'state>: SystemParam<State = Self::State>;
227
228    /// Creates a new instance of this param's [`State`](SystemParam::State).
229    fn init_state(world: &mut World) -> Self::State;
230
231    /// Registers any [`World`] access used by this [`SystemParam`].
232    ///
233    /// This method must panic if the access would conflict with any existing access in the [`FilteredAccessSet`].
234    fn init_access(
235        state: &Self::State,
236        system_meta: &mut SystemMeta,
237        component_access_set: &mut FilteredAccessSet,
238        world: &mut World,
239    );
240
241    /// Applies any deferred mutations stored in this [`SystemParam`]'s state.
242    /// This is used to apply [`Commands`] during [`ApplyDeferred`](crate::prelude::ApplyDeferred).
243    ///
244    /// [`Commands`]: crate::prelude::Commands
245    #[inline]
246    #[expect(
247        unused_variables,
248        reason = "The parameters here are intentionally unused by the default implementation; however, putting underscores here will result in the underscores being copied by rust-analyzer's tab completion."
249    )]
250    fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World) {}
251
252    /// Queues any deferred mutations to be applied at the next [`ApplyDeferred`](crate::prelude::ApplyDeferred).
253    #[inline]
254    #[expect(
255        unused_variables,
256        reason = "The parameters here are intentionally unused by the default implementation; however, putting underscores here will result in the underscores being copied by rust-analyzer's tab completion."
257    )]
258    fn queue(state: &mut Self::State, system_meta: &SystemMeta, world: DeferredWorld) {}
259
260    /// Creates a parameter to be passed into a [`SystemParamFunction`](super::SystemParamFunction).
261    ///
262    /// This method also validates that the param can be acquired. If validation fails,
263    /// an appropriate [`SystemParamValidationError`] should be returned.
264    /// Systems will convert this to a [`RunSystemError`](super::RunSystemError),
265    /// and the built-in executors will ignore any "skipped" validation results,
266    /// but pass any "invalid" results to the fallback error handler defined in [`bevy_ecs::error`].
267    ///
268    /// For nested [`SystemParam`]s validation will fail if any
269    /// delegated validation fails.
270    ///
271    /// # Safety
272    ///
273    /// - The passed [`UnsafeWorldCell`] must have access to any world data registered
274    ///   in [`init_access`](SystemParam::init_access).
275    /// - [`SystemParam::init_access`] must not request conflicting access.
276    ///   If `Self` is `ReadOnlySystemParam`, the access is read-only and can never conflict.
277    ///   Otherwise, [`SystemParam::init_access`] must be called to ensure it does not panic.
278    /// - `world` must be the same [`World`] that was used to initialize [`state`](SystemParam::init_state).
279    unsafe fn get_param<'world, 'state>(
280        state: &'state mut Self::State,
281        system_meta: &SystemMeta,
282        world: UnsafeWorldCell<'world>,
283        change_tick: Tick,
284    ) -> Result<Self::Item<'world, 'state>, SystemParamValidationError>;
285}
286
287/// A [`SystemParam`] that only reads a given [`World`].
288///
289/// # Safety
290/// This must only be implemented for [`SystemParam`] impls that exclusively read the World passed in to [`SystemParam::get_param`]
291pub unsafe trait ReadOnlySystemParam: SystemParam {}
292
293/// Shorthand way of accessing the associated type [`SystemParam::Item`] for a given [`SystemParam`].
294pub type SystemParamItem<'w, 's, P> = <P as SystemParam>::Item<'w, 's>;
295
296// SAFETY: QueryState is constrained to read-only fetches, so it only reads World.
297unsafe impl<'w, 's, D: ReadOnlyQueryData + 'static, F: QueryFilter + 'static> ReadOnlySystemParam
298    for Query<'w, 's, D, F>
299{
300}
301
302// SAFETY: Relevant query ComponentId access is applied to SystemMeta. If
303// this Query conflicts with any prior access, a panic will occur.
304unsafe impl<D: QueryData + 'static, F: QueryFilter + 'static> SystemParam for Query<'_, '_, D, F> {
305    type State = QueryState<D, F>;
306    type Item<'w, 's> = Query<'w, 's, D, F>;
307
308    fn init_state(world: &mut World) -> Self::State {
309        // SAFETY: `SystemParam::init_access` calls `QueryState::init_access`,
310        // `SystemParam::init_access` must be called before `SystemParam::get_param`,
311        // and we only call methods on the `QueryState` in `get_param`.
312        unsafe { QueryState::new_unchecked(world) }
313    }
314
315    fn init_access(
316        state: &Self::State,
317        system_meta: &mut SystemMeta,
318        component_access_set: &mut FilteredAccessSet,
319        world: &mut World,
320    ) {
321        state.init_access(Some(system_meta.name()), component_access_set, world.into());
322    }
323
324    #[inline]
325    unsafe fn get_param<'w, 's>(
326        state: &'s mut Self::State,
327        system_meta: &SystemMeta,
328        world: UnsafeWorldCell<'w>,
329        change_tick: Tick,
330    ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
331        // SAFETY: We have registered all of the query's world accesses,
332        // so the caller ensures that `world` has permission to access any
333        // world data that the query needs.
334        // The caller ensures the world matches the one used in init_state.
335        Ok(unsafe { state.query_unchecked_with_ticks(world, system_meta.last_run, change_tick) })
336    }
337}
338
339// SAFETY: Relevant query ComponentId access is applied to SystemMeta. If
340// this Query conflicts with any prior access, a panic will occur.
341unsafe impl<'a, 'b, D: IterQueryData + 'static, F: QueryFilter + 'static> SystemParam
342    for Single<'a, 'b, D, F>
343{
344    type State = QueryState<D, F>;
345    type Item<'w, 's> = Single<'w, 's, D, F>;
346
347    fn init_state(world: &mut World) -> Self::State {
348        Query::init_state(world)
349    }
350
351    fn init_access(
352        state: &Self::State,
353        system_meta: &mut SystemMeta,
354        component_access_set: &mut FilteredAccessSet,
355        world: &mut World,
356    ) {
357        Query::init_access(state, system_meta, component_access_set, world);
358    }
359
360    #[inline]
361    unsafe fn get_param<'w, 's>(
362        state: &'s mut Self::State,
363        system_meta: &SystemMeta,
364        world: UnsafeWorldCell<'w>,
365        change_tick: Tick,
366    ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
367        // SAFETY: State ensures that the components it accesses are not accessible somewhere elsewhere.
368        // The caller ensures the world matches the one used in init_state.
369        let query =
370            unsafe { state.query_unchecked_with_ticks(world, system_meta.last_run, change_tick) };
371        match query.single_inner() {
372            Ok(single) => Ok(Single {
373                item: single,
374                _filter: PhantomData,
375            }),
376            Err(QuerySingleError::NoEntities(_)) => Err(
377                SystemParamValidationError::skipped::<Self>("No matching entities"),
378            ),
379            Err(QuerySingleError::MultipleEntities(_)) => Err(
380                SystemParamValidationError::skipped::<Self>("Multiple matching entities"),
381            ),
382        }
383    }
384}
385
386// SAFETY: QueryState is constrained to read-only fetches, so it only reads World.
387unsafe impl<'a, 'b, D: ReadOnlyQueryData + 'static, F: QueryFilter + 'static> ReadOnlySystemParam
388    for Single<'a, 'b, D, F>
389{
390}
391
392// SAFETY: Relevant query ComponentId access is applied to SystemMeta. If
393// this Query conflicts with any prior access, a panic will occur.
394unsafe impl<D: QueryData + 'static, F: QueryFilter + 'static> SystemParam
395    for Populated<'_, '_, D, F>
396{
397    type State = QueryState<D, F>;
398    type Item<'w, 's> = Populated<'w, 's, D, F>;
399
400    fn init_state(world: &mut World) -> Self::State {
401        Query::init_state(world)
402    }
403
404    fn init_access(
405        state: &Self::State,
406        system_meta: &mut SystemMeta,
407        component_access_set: &mut FilteredAccessSet,
408        world: &mut World,
409    ) {
410        Query::init_access(state, system_meta, component_access_set, world);
411    }
412
413    #[inline]
414    unsafe fn get_param<'w, 's>(
415        state: &'s mut Self::State,
416        system_meta: &SystemMeta,
417        world: UnsafeWorldCell<'w>,
418        change_tick: Tick,
419    ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
420        // SAFETY: Delegate to existing `SystemParam` implementations.
421        let query = unsafe { Query::get_param(state, system_meta, world, change_tick) }?;
422        if query.is_empty() {
423            Err(SystemParamValidationError::skipped::<Self>(
424                "No matching entities",
425            ))
426        } else {
427            Ok(Populated(query))
428        }
429    }
430}
431
432// SAFETY: QueryState is constrained to read-only fetches, so it only reads World.
433unsafe impl<'w, 's, D: ReadOnlyQueryData + 'static, F: QueryFilter + 'static> ReadOnlySystemParam
434    for Populated<'w, 's, D, F>
435{
436}
437
438/// A collection of potentially conflicting [`SystemParam`]s allowed by disjoint access.
439///
440/// Allows systems to safely access and interact with up to 8 mutually exclusive [`SystemParam`]s, such as
441/// two queries that reference the same mutable data or an event reader and writer of the same type.
442///
443/// Each individual [`SystemParam`] can be accessed by using the functions `p0()`, `p1()`, ..., `p7()`,
444/// according to the order they are defined in the `ParamSet`. This ensures that there's either
445/// only one mutable reference to a parameter at a time or any number of immutable references.
446///
447/// # Examples
448///
449/// The following system mutably accesses the same component two times,
450/// which is not allowed due to rust's mutability rules.
451///
452/// ```should_panic
453/// # use bevy_ecs::prelude::*;
454/// #
455/// # #[derive(Component)]
456/// # struct Health;
457/// #
458/// # #[derive(Component)]
459/// # struct Enemy;
460/// #
461/// # #[derive(Component)]
462/// # struct Ally;
463/// #
464/// // This will panic at runtime when the system gets initialized.
465/// fn bad_system(
466///     mut enemies: Query<&mut Health, With<Enemy>>,
467///     mut allies: Query<&mut Health, With<Ally>>,
468/// ) {
469///     // ...
470/// }
471/// #
472/// # let mut bad_system_system = IntoSystem::into_system(bad_system);
473/// # let mut world = World::new();
474/// # bad_system_system.initialize(&mut world);
475/// # bad_system_system.run((), &mut world);
476/// ```
477///
478/// Conflicting `SystemParam`s like these can be placed in a `ParamSet`,
479/// which leverages the borrow checker to ensure that only one of the contained parameters are accessed at a given time.
480///
481/// ```
482/// # use bevy_ecs::prelude::*;
483/// #
484/// # #[derive(Component)]
485/// # struct Health;
486/// #
487/// # #[derive(Component)]
488/// # struct Enemy;
489/// #
490/// # #[derive(Component)]
491/// # struct Ally;
492/// #
493/// // Given the following system
494/// fn fancy_system(
495///     mut set: ParamSet<(
496///         Query<&mut Health, With<Enemy>>,
497///         Query<&mut Health, With<Ally>>,
498///     )>
499/// ) {
500///     // This will access the first `SystemParam`.
501///     for mut health in set.p0().iter_mut() {
502///         // Do your fancy stuff here...
503///     }
504///
505///     // The second `SystemParam`.
506///     // This would fail to compile if the previous parameter was still borrowed.
507///     for mut health in set.p1().iter_mut() {
508///         // Do even fancier stuff here...
509///     }
510/// }
511/// # bevy_ecs::system::assert_is_system(fancy_system);
512/// ```
513///
514/// Of course, `ParamSet`s can be used with any kind of `SystemParam`, not just [queries](Query).
515///
516/// ```
517/// # use bevy_ecs::prelude::*;
518/// #
519/// # #[derive(Message)]
520/// # struct MyMessage;
521/// # impl MyMessage {
522/// #   pub fn new() -> Self { Self }
523/// # }
524/// fn message_system(
525///     mut set: ParamSet<(
526///         // PROBLEM: `MessageReader` and `MessageWriter` cannot be used together normally,
527///         // because they both need access to the same message queue.
528///         // SOLUTION: `ParamSet` allows these conflicting parameters to be used safely
529///         // by ensuring only one is accessed at a time.
530///         // Note that a better solution here is to use `MessageMutator`,
531///         // which both reads and writes messages with a single parameter.
532///         MessageReader<MyMessage>,
533///         MessageWriter<MyMessage>,
534///         // PROBLEM: `&World` needs read access to everything, which conflicts with
535///         // any mutable access in the same system.
536///         // SOLUTION: `ParamSet` ensures `&World` is only accessed when we're not
537///         // using the other mutable parameters.
538///         &World,
539///     )>,
540/// ) {
541///     for message in set.p0().read() {
542///         // ...
543///         # let _message = message;
544///     }
545///     set.p1().write(MyMessage::new());
546///
547///     let entities = set.p2().entities();
548///     // ...
549///     # let _entities = entities;
550/// }
551/// # bevy_ecs::system::assert_is_system(message_system);
552/// ```
553pub struct ParamSet<'w, 's, T: SystemParam> {
554    param_states: &'s mut T::State,
555    world: UnsafeWorldCell<'w>,
556    system_meta: SystemMeta,
557    change_tick: Tick,
558}
559
560macro_rules! impl_param_set {
561    ($(($index: tt, $param: ident, $fn_name: ident)),*) => {
562        // SAFETY: All parameters are constrained to ReadOnlySystemParam, so World is only read
563        unsafe impl<'w, 's, $($param,)*> ReadOnlySystemParam for ParamSet<'w, 's, ($($param,)*)>
564        where $($param: ReadOnlySystemParam,)*
565        { }
566
567        // SAFETY: Relevant parameter ComponentId access is applied to SystemMeta. If any ParamState conflicts
568        // with any prior access, a panic will occur.
569        unsafe impl<'_w, '_s, $($param: SystemParam,)*> SystemParam for ParamSet<'_w, '_s, ($($param,)*)>
570        {
571            type State = ($($param::State,)*);
572            type Item<'w, 's> = ParamSet<'w, 's, ($($param,)*)>;
573
574            #[expect(
575                clippy::allow_attributes,
576                reason = "This is inside a macro meant for tuples; as such, `non_snake_case` won't always lint."
577            )]
578            #[allow(
579                non_snake_case,
580                reason = "Certain variable names are provided by the caller, not by us."
581            )]
582            fn init_state(world: &mut World) -> Self::State {
583                ($($param::init_state(world),)*)
584            }
585
586            #[expect(
587                clippy::allow_attributes,
588                reason = "This is inside a macro meant for tuples; as such, `non_snake_case` won't always lint."
589            )]
590            #[allow(
591                non_snake_case,
592                reason = "Certain variable names are provided by the caller, not by us."
593            )]
594            fn init_access(state: &Self::State, system_meta: &mut SystemMeta, component_access_set: &mut FilteredAccessSet, world: &mut World) {
595                let ($($param,)*) = state;
596                $(
597                    // Call `init_access` on a clone of the original access set to check for conflicts
598                    let component_access_set_clone = &mut component_access_set.clone();
599                    $param::init_access($param, system_meta, component_access_set_clone, world);
600                )*
601                $(
602                    // Pretend to add the param to the system alone to gather the new access,
603                    // then merge its access into the system.
604                    let mut access_set = FilteredAccessSet::new();
605                    $param::init_access($param, system_meta, &mut access_set, world);
606                    component_access_set.extend(access_set);
607                )*
608            }
609
610            fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World) {
611                <($($param,)*) as SystemParam>::apply(state, system_meta, world);
612            }
613
614            fn queue(state: &mut Self::State, system_meta: &SystemMeta, mut world: DeferredWorld) {
615                <($($param,)*) as SystemParam>::queue(state, system_meta, world.reborrow());
616            }
617
618            #[inline]
619            unsafe fn get_param<'w, 's>(
620                state: &'s mut Self::State,
621                system_meta: &SystemMeta,
622                world: UnsafeWorldCell<'w>,
623                change_tick: Tick,
624            ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
625                // Validate each sub-param eagerly so that the system is correctly
626                // skipped by the executor when any sub-param is unavailable.
627                // PERF: the sub-params will be fetched again lazily when accessed through
628                // the ParamSet, but this is no worse than the previous
629                // validate_param + get_param pattern.
630                $(
631                    // SAFETY: Upheld by caller.
632                    drop(unsafe { $param::get_param(&mut state.$index, system_meta, world, change_tick) }?);
633                )*
634
635                Ok(ParamSet {
636                    param_states: state,
637                    system_meta: system_meta.clone(),
638                    world,
639                    change_tick,
640                })
641            }
642        }
643
644        impl<'w, 's, $($param: SystemParam,)*> ParamSet<'w, 's, ($($param,)*)>
645        {
646            $(
647                /// Gets exclusive access to the parameter at index
648                #[doc = stringify!($index)]
649                /// in this [`ParamSet`].
650                /// No other parameters may be accessed while this one is active.
651                pub fn $fn_name<'a>(&'a mut self) -> SystemParamItem<'a, 'a, $param> {
652                    // SAFETY: systems run without conflicts with other systems.
653                    // Conflicting params in ParamSet are not accessible at the same time
654                    // ParamSets are guaranteed to not conflict with other SystemParams
655                    unsafe {
656                        $param::get_param(&mut self.param_states.$index, &self.system_meta, self.world, self.change_tick)
657                    }
658                    .unwrap_or_else(|err| panic!("ParamSet parameter validation failed: {err}"))
659                }
660            )*
661        }
662    }
663}
664
665all_tuples_enumerated!(impl_param_set, 1, 8, P, p);
666
667// SAFETY: Res only reads a single World resource
668unsafe impl<'a, T: Resource> ReadOnlySystemParam for Res<'a, T> {}
669
670// SAFETY: Res ComponentId access is applied to SystemMeta. If this Res
671// conflicts with any prior access, a panic will occur.
672unsafe impl<'a, T: Resource> SystemParam for Res<'a, T> {
673    type State = ComponentId;
674    type Item<'w, 's> = Res<'w, T>;
675
676    fn init_state(world: &mut World) -> Self::State {
677        world.components_registrator().register_component::<T>()
678    }
679
680    fn init_access(
681        &component_id: &Self::State,
682        system_meta: &mut SystemMeta,
683        component_access_set: &mut FilteredAccessSet,
684        world: &mut World,
685    ) {
686        let mut filter = FilteredAccess::default();
687        filter.add_read(component_id);
688        filter.and_with(IS_RESOURCE);
689
690        let conflicts = component_access_set.get_conflicts_single(&filter);
691        if conflicts.is_empty() {
692            component_access_set.add(filter);
693            return;
694        }
695
696        let mut accesses = conflicts.format_conflict_list(world.as_unsafe_world_cell());
697        // Access list may be empty (if access to all components requested)
698        if !accesses.is_empty() {
699            accesses.push(' ');
700        }
701        panic!("error[B0002]: Res<{}> in system {} conflicts with a previous system parameter. Consider removing the duplicate access using `Without<IsResource>` to create disjoint Queries or merging conflicting Queries into a `ParamSet`. See: https://bevy.org/learn/errors/b0002", DebugName::type_name::<T>(), system_meta.name);
702    }
703
704    #[inline]
705    unsafe fn get_param<'w, 's>(
706        &mut component_id: &'s mut Self::State,
707        system_meta: &SystemMeta,
708        world: UnsafeWorldCell<'w>,
709        change_tick: Tick,
710    ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
711        let (ptr, ticks) = world.get_resource_with_ticks(component_id).ok_or_else(|| {
712            SystemParamValidationError::invalid::<Self>("Resource does not exist")
713        })?;
714        Ok(Res {
715            value: ptr.deref(),
716            ticks: ComponentTicksRef {
717                added: ticks.added.deref(),
718                changed: ticks.changed.deref(),
719                changed_by: ticks.changed_by.map(|changed_by| changed_by.deref()),
720                last_run: system_meta.last_run,
721                this_run: change_tick,
722            },
723        })
724    }
725}
726
727// SAFETY: Res ComponentId access is applied to SystemMeta. If this Res
728// conflicts with any prior access, a panic will occur.
729unsafe impl<'a, T: Resource<Mutability = Mutable>> SystemParam for ResMut<'a, T> {
730    type State = ComponentId;
731    type Item<'w, 's> = ResMut<'w, T>;
732
733    fn init_state(world: &mut World) -> Self::State {
734        world.components_registrator().register_component::<T>()
735    }
736
737    fn init_access(
738        &component_id: &Self::State,
739        system_meta: &mut SystemMeta,
740        component_access_set: &mut FilteredAccessSet,
741        world: &mut World,
742    ) {
743        let mut filter = FilteredAccess::default();
744        filter.add_write(component_id);
745        filter.and_with(IS_RESOURCE);
746
747        let conflicts = component_access_set.get_conflicts_single(&filter);
748        if conflicts.is_empty() {
749            component_access_set.add(filter);
750            return;
751        }
752
753        let mut accesses = conflicts.format_conflict_list(world.as_unsafe_world_cell());
754        // Access list may be empty (if access to all components requested)
755        if !accesses.is_empty() {
756            accesses.push(' ');
757        }
758        panic!("error[B0002]: ResMut<{}> in system {} conflicts with a previous system parameter. Consider removing the duplicate access or using `Without<IsResource>` to create disjoint Queries or merging conflicting Queries into a `ParamSet`. See: https://bevy.org/learn/errors/b0002", DebugName::type_name::<T>(), system_meta.name);
759    }
760
761    #[inline]
762    unsafe fn get_param<'w, 's>(
763        &mut component_id: &'s mut Self::State,
764        system_meta: &SystemMeta,
765        world: UnsafeWorldCell<'w>,
766        change_tick: Tick,
767    ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
768        let value = world.get_resource_mut_by_id(component_id).ok_or_else(|| {
769            SystemParamValidationError::invalid::<Self>("Resource does not exist")
770        })?;
771        Ok(ResMut {
772            value: value.value.deref_mut::<T>(),
773            ticks: ComponentTicksMut {
774                added: value.ticks.added,
775                changed: value.ticks.changed,
776                changed_by: value.ticks.changed_by,
777                last_run: system_meta.last_run,
778                this_run: change_tick,
779            },
780        })
781    }
782}
783
784// SAFETY: only reads world
785unsafe impl<'w> ReadOnlySystemParam for &'w World {}
786
787// SAFETY: `read_all` access is set and conflicts result in a panic
788unsafe impl SystemParam for &'_ World {
789    type State = ();
790    type Item<'w, 's> = &'w World;
791
792    fn init_state(_world: &mut World) -> Self::State {}
793
794    fn init_access(
795        _state: &Self::State,
796        _system_meta: &mut SystemMeta,
797        component_access_set: &mut FilteredAccessSet,
798        _world: &mut World,
799    ) {
800        let mut filtered_access = FilteredAccess::default();
801
802        filtered_access.read_all();
803        if !component_access_set
804            .get_conflicts_single(&filtered_access)
805            .is_empty()
806        {
807            panic!("&World conflicts with a previous mutable system parameter. Allowing this would break Rust's mutability rules");
808        }
809        component_access_set.add(filtered_access);
810    }
811
812    #[inline]
813    unsafe fn get_param<'w, 's>(
814        _state: &'s mut Self::State,
815        _system_meta: &SystemMeta,
816        world: UnsafeWorldCell<'w>,
817        _change_tick: Tick,
818    ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
819        // SAFETY: Read-only access to the entire world was registered in `init_state`.
820        Ok(unsafe { world.world() })
821    }
822}
823
824// SAFETY: `DeferredWorld` can read all components and resources but cannot be used to gain any other mutable references.
825unsafe impl<'w> SystemParam for DeferredWorld<'w> {
826    type State = ();
827    type Item<'world, 'state> = DeferredWorld<'world>;
828
829    fn init_state(_world: &mut World) -> Self::State {}
830
831    fn init_access(
832        _state: &Self::State,
833        system_meta: &mut SystemMeta,
834        component_access_set: &mut FilteredAccessSet,
835        _world: &mut World,
836    ) {
837        assert!(
838            !component_access_set.combined_access().has_any_read(),
839            "DeferredWorld in system {} conflicts with a previous access.",
840            system_meta.name,
841        );
842        component_access_set.write_all();
843    }
844
845    unsafe fn get_param<'world, 'state>(
846        _state: &'state mut Self::State,
847        _system_meta: &SystemMeta,
848        world: UnsafeWorldCell<'world>,
849        _change_tick: Tick,
850    ) -> Result<Self::Item<'world, 'state>, SystemParamValidationError> {
851        // SAFETY: Upheld by caller
852        Ok(unsafe { world.into_deferred() })
853    }
854}
855
856/// A [`SystemParam`] that provides a system-private value of `T` that persists across system calls.
857///
858/// The initial value is created by calling `T`'s [`FromWorld::from_world`] (or [`Default::default`] if `T: Default`).
859///
860/// A local may only be accessed by the system itself and is therefore not visible to other systems.
861/// If two or more systems specify the same local type each will have their own unique local.
862/// If multiple [`SystemParam`]s within the same system each specify the same local type
863/// each will get their own distinct data storage.
864///
865/// The supplied lifetime parameter is the [`SystemParam`]s `'s` lifetime.
866///
867/// # Examples
868///
869/// ```
870/// # use bevy_ecs::prelude::*;
871/// # let world = &mut World::default();
872/// fn counter(mut count: Local<u32>) -> u32 {
873///     *count += 1;
874///     *count
875/// }
876/// let mut counter_system = IntoSystem::into_system(counter);
877/// counter_system.initialize(world);
878///
879/// // Counter is initialized to u32's default value of 0, and increases to 1 on first run.
880/// assert_eq!(counter_system.run((), world).unwrap(), 1);
881/// // Counter gets the same value and increases to 2 on its second call.
882/// assert_eq!(counter_system.run((), world).unwrap(), 2);
883/// ```
884///
885/// A simple way to set a different default value for a local is by wrapping the value with an Option.
886///
887/// ```
888/// # use bevy_ecs::prelude::*;
889/// # let world = &mut World::default();
890/// fn counter_from_10(mut count: Local<Option<u32>>) -> u32 {
891///     let count = count.get_or_insert(10);
892///     *count += 1;
893///     *count
894/// }
895/// let mut counter_system = IntoSystem::into_system(counter_from_10);
896/// counter_system.initialize(world);
897///
898/// // Counter is initialized at 10, and increases to 11 on first run.
899/// assert_eq!(counter_system.run((), world).unwrap(), 11);
900/// // Counter is only increased by 1 on subsequent runs.
901/// assert_eq!(counter_system.run((), world).unwrap(), 12);
902/// ```
903///
904/// A system can have multiple `Local` values with the same type, each with distinct values.
905///
906/// ```
907/// # use bevy_ecs::prelude::*;
908/// # let world = &mut World::default();
909/// fn double_counter(mut count: Local<u32>, mut double_count: Local<u32>) -> (u32, u32) {
910///     *count += 1;
911///     *double_count += 2;
912///     (*count, *double_count)
913/// }
914/// let mut counter_system = IntoSystem::into_system(double_counter);
915/// counter_system.initialize(world);
916///
917/// assert_eq!(counter_system.run((), world).unwrap(), (1, 2));
918/// assert_eq!(counter_system.run((), world).unwrap(), (2, 4));
919/// ```
920///
921/// This example shows that two systems using the same type for their own `Local` get distinct locals.
922///
923/// ```
924/// # use bevy_ecs::prelude::*;
925/// # let world = &mut World::default();
926/// fn write_to_local(mut local: Local<usize>) {
927///     *local = 42;
928/// }
929/// fn read_from_local(local: Local<usize>) -> usize {
930///     *local
931/// }
932/// let mut write_system = IntoSystem::into_system(write_to_local);
933/// let mut read_system = IntoSystem::into_system(read_from_local);
934/// write_system.initialize(world);
935/// read_system.initialize(world);
936///
937/// assert_eq!(read_system.run((), world).unwrap(), 0);
938/// write_system.run((), world);
939/// // The read local is still 0 due to the locals not being shared.
940/// assert_eq!(read_system.run((), world).unwrap(), 0);
941/// ```
942///
943/// You can use a `Local` to avoid reallocating memory every system call.
944///
945/// ```
946/// # use bevy_ecs::prelude::*;
947/// fn some_system(mut vec: Local<Vec<u32>>) {
948///     // Do your regular system logic, using the vec, as normal.
949///
950///     // At end of function, clear the vec's contents so its empty for next system call.
951///     // If it's possible the capacity could get too large, you may want to check and resize that as well.
952///     vec.clear();
953/// }
954/// ```
955///
956/// N.B. A [`Local`]s value cannot be read or written to outside of the containing system.
957/// To add configuration to a system, convert a capturing closure into the system instead:
958///
959/// ```
960/// # use bevy_ecs::prelude::*;
961/// # use bevy_ecs::system::assert_is_system;
962/// struct Config(u32);
963/// #[derive(Resource)]
964/// struct MyU32Wrapper(u32);
965/// fn reset_to_system(value: Config) -> impl FnMut(ResMut<MyU32Wrapper>) {
966///     move |mut val| val.0 = value.0
967/// }
968///
969/// // .add_systems(reset_to_system(my_config))
970/// # assert_is_system(reset_to_system(Config(10)));
971/// ```
972#[derive(Debug)]
973pub struct Local<'s, T: FromWorld + Send + 'static>(pub(crate) &'s mut T);
974
975// SAFETY: Local only accesses internal state
976unsafe impl<'s, T: FromWorld + Send + 'static> ReadOnlySystemParam for Local<'s, T> {}
977
978impl<'s, T: FromWorld + Send + 'static> Deref for Local<'s, T> {
979    type Target = T;
980
981    #[inline]
982    fn deref(&self) -> &Self::Target {
983        self.0
984    }
985}
986
987impl<'s, T: FromWorld + Send + 'static> DerefMut for Local<'s, T> {
988    #[inline]
989    fn deref_mut(&mut self) -> &mut Self::Target {
990        self.0
991    }
992}
993
994impl<'s, 'a, T: FromWorld + Send + 'static> IntoIterator for &'a Local<'s, T>
995where
996    &'a T: IntoIterator,
997{
998    type Item = <&'a T as IntoIterator>::Item;
999    type IntoIter = <&'a T as IntoIterator>::IntoIter;
1000
1001    fn into_iter(self) -> Self::IntoIter {
1002        self.0.into_iter()
1003    }
1004}
1005
1006impl<'s, 'a, T: FromWorld + Send + 'static> IntoIterator for &'a mut Local<'s, T>
1007where
1008    &'a mut T: IntoIterator,
1009{
1010    type Item = <&'a mut T as IntoIterator>::Item;
1011    type IntoIter = <&'a mut T as IntoIterator>::IntoIter;
1012
1013    fn into_iter(self) -> Self::IntoIter {
1014        self.0.into_iter()
1015    }
1016}
1017
1018// SAFETY: only local state is accessed
1019unsafe impl<'a, T: FromWorld + Send + 'static> SystemParam for Local<'a, T> {
1020    type State = SyncCell<T>;
1021    type Item<'w, 's> = Local<'s, T>;
1022
1023    fn init_state(world: &mut World) -> Self::State {
1024        SyncCell::new(T::from_world(world))
1025    }
1026
1027    fn init_access(
1028        _state: &Self::State,
1029        _system_meta: &mut SystemMeta,
1030        _component_access_set: &mut FilteredAccessSet,
1031        _world: &mut World,
1032    ) {
1033    }
1034
1035    #[inline]
1036    unsafe fn get_param<'w, 's>(
1037        state: &'s mut Self::State,
1038        _system_meta: &SystemMeta,
1039        _world: UnsafeWorldCell<'w>,
1040        _change_tick: Tick,
1041    ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
1042        Ok(Local(state.get()))
1043    }
1044}
1045
1046/// Types that can be used with [`Deferred<T>`] in systems.
1047/// This allows storing system-local data which is used to defer [`World`] mutations.
1048///
1049/// Types that implement `SystemBuffer` should take care to perform as many
1050/// computations up-front as possible. Buffers cannot be applied in parallel,
1051/// so you should try to minimize the time spent in [`SystemBuffer::apply`].
1052pub trait SystemBuffer: FromWorld + Send + 'static {
1053    /// Applies any deferred mutations to the [`World`].
1054    fn apply(&mut self, system_meta: &SystemMeta, world: &mut World) {
1055        self.queue(system_meta, world.into());
1056    }
1057    /// Queues any deferred mutations to be applied at the next [`ApplyDeferred`](crate::prelude::ApplyDeferred).
1058    ///
1059    /// To queue structural changes to [`DeferredWorld`], a command queue of the [`DeferredWorld`]
1060    /// should be used via [`commands`](crate::world::DeferredWorld::commands).
1061    fn queue(&mut self, _system_meta: &SystemMeta, _world: DeferredWorld);
1062}
1063
1064/// A [`SystemParam`] that stores a buffer which gets applied to the [`World`] during
1065/// [`ApplyDeferred`](crate::schedule::ApplyDeferred).
1066/// This is used internally by [`Commands`] to defer `World` mutations.
1067///
1068/// [`Commands`]: crate::system::Commands
1069///
1070/// # Examples
1071///
1072/// By using this type to defer mutations, you can avoid mutable `World` access within
1073/// a system, which allows it to run in parallel with more systems.
1074///
1075/// Note that deferring mutations is *not* free, and should only be used if
1076/// the gains in parallelization outweigh the time it takes to apply deferred mutations.
1077/// In general, [`Deferred`] should only be used for mutations that are infrequent,
1078/// or which otherwise take up a small portion of a system's run-time.
1079///
1080/// ```
1081/// # use bevy_ecs::prelude::*;
1082/// # use bevy_ecs::world::DeferredWorld;
1083/// // Tracks whether or not there is a threat the player should be aware of.
1084/// #[derive(Resource, Default)]
1085/// pub struct Alarm(bool);
1086///
1087/// #[derive(Component)]
1088/// pub struct Settlement {
1089///     // ...
1090/// }
1091///
1092/// // A threat from inside the settlement.
1093/// #[derive(Component)]
1094/// pub struct Criminal;
1095///
1096/// // A threat from outside the settlement.
1097/// #[derive(Component)]
1098/// pub struct Monster;
1099///
1100/// # impl Criminal { pub fn is_threat(&self, _: &Settlement) -> bool { true } }
1101///
1102/// use bevy_ecs::system::{Deferred, SystemBuffer, SystemMeta};
1103///
1104/// // Uses deferred mutations to allow signaling the alarm from multiple systems in parallel.
1105/// #[derive(Resource, Default)]
1106/// struct AlarmFlag(bool);
1107///
1108/// impl AlarmFlag {
1109///     /// Sounds the alarm the next time buffers are applied via ApplyDeferred.
1110///     pub fn flag(&mut self) {
1111///         self.0 = true;
1112///     }
1113/// }
1114///
1115/// impl SystemBuffer for AlarmFlag {
1116///     // When `AlarmFlag` is used in a system, this function will get
1117///     // called the next time buffers are applied via ApplyDeferred.
1118///     fn queue(&mut self, system_meta: &SystemMeta, mut world: DeferredWorld) {
1119///         if self.0 {
1120///             world.resource_mut::<Alarm>().0 = true;
1121///             self.0 = false;
1122///         }
1123///     }
1124/// }
1125///
1126/// // Sound the alarm if there are any criminals who pose a threat.
1127/// fn alert_criminal(
1128///     settlement: Single<&Settlement>,
1129///     criminals: Query<&Criminal>,
1130///     mut alarm: Deferred<AlarmFlag>
1131/// ) {
1132///     for criminal in &criminals {
1133///         // Only sound the alarm if the criminal is a threat.
1134///         // For this example, assume that this check is expensive to run.
1135///         // Since the majority of this system's run-time is dominated
1136///         // by calling `is_threat()`, we defer sounding the alarm to
1137///         // allow this system to run in parallel with other alarm systems.
1138///         if criminal.is_threat(*settlement) {
1139///             alarm.flag();
1140///         }
1141///     }
1142/// }
1143///
1144/// // Sound the alarm if there is a monster.
1145/// fn alert_monster(
1146///     monsters: Query<&Monster>,
1147///     mut alarm: ResMut<Alarm>
1148/// ) {
1149///     if monsters.iter().next().is_some() {
1150///         // Since this system does nothing except for sounding the alarm,
1151///         // it would be pointless to defer it, so we sound the alarm directly.
1152///         alarm.0 = true;
1153///     }
1154/// }
1155///
1156/// let mut world = World::new();
1157/// world.init_resource::<Alarm>();
1158/// world.spawn(Settlement {
1159///     // ...
1160/// });
1161///
1162/// let mut schedule = Schedule::default();
1163/// // These two systems have no conflicts and will run in parallel.
1164/// schedule.add_systems((alert_criminal, alert_monster));
1165///
1166/// // There are no criminals or monsters, so the alarm is not sounded.
1167/// schedule.run(&mut world);
1168/// assert_eq!(world.resource::<Alarm>().0, false);
1169///
1170/// // Spawn a monster, which will cause the alarm to be sounded.
1171/// let m_id = world.spawn(Monster).id();
1172/// schedule.run(&mut world);
1173/// assert_eq!(world.resource::<Alarm>().0, true);
1174///
1175/// // Remove the monster and reset the alarm.
1176/// world.entity_mut(m_id).despawn();
1177/// world.resource_mut::<Alarm>().0 = false;
1178///
1179/// // Spawn a criminal, which will cause the alarm to be sounded.
1180/// world.spawn(Criminal);
1181/// schedule.run(&mut world);
1182/// assert_eq!(world.resource::<Alarm>().0, true);
1183/// ```
1184pub struct Deferred<'a, T: SystemBuffer>(pub(crate) &'a mut T);
1185
1186impl<'a, T: SystemBuffer> Deref for Deferred<'a, T> {
1187    type Target = T;
1188    #[inline]
1189    fn deref(&self) -> &Self::Target {
1190        self.0
1191    }
1192}
1193
1194impl<'a, T: SystemBuffer> DerefMut for Deferred<'a, T> {
1195    #[inline]
1196    fn deref_mut(&mut self) -> &mut Self::Target {
1197        self.0
1198    }
1199}
1200
1201impl<T: SystemBuffer> Deferred<'_, T> {
1202    /// Returns a [`Deferred<T>`] with a smaller lifetime.
1203    /// This is useful if you have `&mut Deferred<T>` but need `Deferred<T>`.
1204    pub fn reborrow(&mut self) -> Deferred<'_, T> {
1205        Deferred(self.0)
1206    }
1207}
1208
1209// SAFETY: Only local state is accessed.
1210unsafe impl<T: SystemBuffer> ReadOnlySystemParam for Deferred<'_, T> {}
1211
1212// SAFETY: Only local state is accessed.
1213unsafe impl<T: SystemBuffer> SystemParam for Deferred<'_, T> {
1214    type State = SyncCell<T>;
1215    type Item<'w, 's> = Deferred<'s, T>;
1216
1217    #[track_caller]
1218    fn init_state(world: &mut World) -> Self::State {
1219        SyncCell::new(T::from_world(world))
1220    }
1221
1222    fn init_access(
1223        _state: &Self::State,
1224        system_meta: &mut SystemMeta,
1225        _component_access_set: &mut FilteredAccessSet,
1226        _world: &mut World,
1227    ) {
1228        system_meta.set_has_deferred();
1229    }
1230
1231    fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World) {
1232        state.get().apply(system_meta, world);
1233    }
1234
1235    fn queue(state: &mut Self::State, system_meta: &SystemMeta, world: DeferredWorld) {
1236        state.get().queue(system_meta, world);
1237    }
1238
1239    #[inline]
1240    unsafe fn get_param<'w, 's>(
1241        state: &'s mut Self::State,
1242        _system_meta: &SystemMeta,
1243        _world: UnsafeWorldCell<'w>,
1244        _change_tick: Tick,
1245    ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
1246        Ok(Deferred(state.get()))
1247    }
1248}
1249
1250/// A dummy type to tell the executor to run the system exclusively.
1251pub struct ExclusiveMarker(PhantomData<()>);
1252
1253// SAFETY: No world access.
1254unsafe impl SystemParam for ExclusiveMarker {
1255    type State = ();
1256    type Item<'w, 's> = Self;
1257
1258    #[inline]
1259    fn init_state(_world: &mut World) -> Self::State {}
1260
1261    fn init_access(
1262        _state: &Self::State,
1263        system_meta: &mut SystemMeta,
1264        _component_access_set: &mut FilteredAccessSet,
1265        _world: &mut World,
1266    ) {
1267        system_meta.set_exclusive();
1268    }
1269
1270    #[inline]
1271    unsafe fn get_param<'world, 'state>(
1272        _state: &'state mut Self::State,
1273        _system_meta: &SystemMeta,
1274        _world: UnsafeWorldCell<'world>,
1275        _change_tick: Tick,
1276    ) -> Result<Self::Item<'world, 'state>, SystemParamValidationError> {
1277        Ok(Self(PhantomData))
1278    }
1279}
1280
1281// SAFETY: Does not read any world state
1282unsafe impl ReadOnlySystemParam for ExclusiveMarker {}
1283
1284/// A dummy type that is [`!Send`](Send), to force systems to run on the main thread.
1285pub struct NonSendMarker(PhantomData<*mut ()>);
1286
1287// SAFETY: No world access.
1288unsafe impl SystemParam for NonSendMarker {
1289    type State = ();
1290    type Item<'w, 's> = Self;
1291
1292    #[inline]
1293    fn init_state(_world: &mut World) -> Self::State {}
1294
1295    fn init_access(
1296        _state: &Self::State,
1297        system_meta: &mut SystemMeta,
1298        _component_access_set: &mut FilteredAccessSet,
1299        _world: &mut World,
1300    ) {
1301        system_meta.set_non_send();
1302    }
1303
1304    #[inline]
1305    unsafe fn get_param<'world, 'state>(
1306        _state: &'state mut Self::State,
1307        _system_meta: &SystemMeta,
1308        _world: UnsafeWorldCell<'world>,
1309        _change_tick: Tick,
1310    ) -> Result<Self::Item<'world, 'state>, SystemParamValidationError> {
1311        Ok(Self(PhantomData))
1312    }
1313}
1314
1315// SAFETY: Does not read any world state
1316unsafe impl ReadOnlySystemParam for NonSendMarker {}
1317
1318// SAFETY: Only reads a single World non-send resource
1319unsafe impl<'w, T> ReadOnlySystemParam for NonSend<'w, T> {}
1320
1321// SAFETY: NonSendComponentId access is applied to SystemMeta. If this
1322// NonSend conflicts with any prior access, a panic will occur.
1323unsafe impl<'a, T: 'static> SystemParam for NonSend<'a, T> {
1324    type State = ComponentId;
1325    type Item<'w, 's> = NonSend<'w, T>;
1326
1327    fn init_state(world: &mut World) -> Self::State {
1328        world.components_registrator().register_non_send::<T>()
1329    }
1330
1331    fn init_access(
1332        &component_id: &Self::State,
1333        system_meta: &mut SystemMeta,
1334        component_access_set: &mut FilteredAccessSet,
1335        _world: &mut World,
1336    ) {
1337        system_meta.set_non_send();
1338
1339        let combined_access = component_access_set.combined_access();
1340        assert!(
1341            !combined_access.has_write(component_id),
1342            "error[B0002]: NonSend<{}> in system {} conflicts with a previous mutable resource access ({0}). Consider removing the duplicate access. See: https://bevy.org/learn/errors/b0002",
1343            DebugName::type_name::<T>(),
1344            system_meta.name,
1345        );
1346        component_access_set.add_unfiltered_component_read(component_id);
1347    }
1348
1349    #[inline]
1350    unsafe fn get_param<'w, 's>(
1351        &mut component_id: &'s mut Self::State,
1352        system_meta: &SystemMeta,
1353        world: UnsafeWorldCell<'w>,
1354        change_tick: Tick,
1355    ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
1356        let (ptr, ticks) = world.get_non_send_with_ticks(component_id).ok_or_else(|| {
1357            SystemParamValidationError::invalid::<Self>("Non-send data not found")
1358        })?;
1359        Ok(NonSend {
1360            value: ptr.deref(),
1361            ticks: ComponentTicksRef::from_tick_cells(ticks, system_meta.last_run, change_tick),
1362        })
1363    }
1364}
1365
1366// SAFETY: NonSendMut ComponentId access is applied to SystemMeta. If this
1367// NonSendMut conflicts with any prior access, a panic will occur.
1368unsafe impl<'a, T: 'static> SystemParam for NonSendMut<'a, T> {
1369    type State = ComponentId;
1370    type Item<'w, 's> = NonSendMut<'w, T>;
1371
1372    fn init_state(world: &mut World) -> Self::State {
1373        world.components_registrator().register_non_send::<T>()
1374    }
1375
1376    fn init_access(
1377        &component_id: &Self::State,
1378        system_meta: &mut SystemMeta,
1379        component_access_set: &mut FilteredAccessSet,
1380        _world: &mut World,
1381    ) {
1382        system_meta.set_non_send();
1383
1384        let combined_access = component_access_set.combined_access();
1385        if combined_access.has_write(component_id) {
1386            panic!(
1387                "error[B0002]: NonSendMut<{}> in system {} conflicts with a previous mutable resource access ({0}). Consider removing the duplicate access. See: https://bevy.org/learn/errors/b0002",
1388                DebugName::type_name::<T>(), system_meta.name);
1389        } else if combined_access.has_read(component_id) {
1390            panic!(
1391                "error[B0002]: NonSendMut<{}> in system {} conflicts with a previous immutable resource access ({0}). Consider removing the duplicate access. See: https://bevy.org/learn/errors/b0002",
1392                DebugName::type_name::<T>(), system_meta.name);
1393        }
1394        component_access_set.add_unfiltered_component_write(component_id);
1395    }
1396
1397    #[inline]
1398    unsafe fn get_param<'w, 's>(
1399        &mut component_id: &'s mut Self::State,
1400        system_meta: &SystemMeta,
1401        world: UnsafeWorldCell<'w>,
1402        change_tick: Tick,
1403    ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
1404        let (ptr, ticks) = world.get_non_send_with_ticks(component_id).ok_or_else(|| {
1405            SystemParamValidationError::invalid::<Self>("Non-send data not found")
1406        })?;
1407        Ok(NonSendMut {
1408            value: ptr.assert_unique().deref_mut(),
1409            ticks: ComponentTicksMut::from_tick_cells(ticks, system_meta.last_run, change_tick),
1410        })
1411    }
1412}
1413
1414// SAFETY: Only reads World archetypes
1415unsafe impl<'a> ReadOnlySystemParam for &'a Archetypes {}
1416
1417// SAFETY: no component value access
1418unsafe impl<'a> SystemParam for &'a Archetypes {
1419    type State = ();
1420    type Item<'w, 's> = &'w Archetypes;
1421
1422    fn init_state(_world: &mut World) -> Self::State {}
1423
1424    fn init_access(
1425        _state: &Self::State,
1426        _system_meta: &mut SystemMeta,
1427        _component_access_set: &mut FilteredAccessSet,
1428        _world: &mut World,
1429    ) {
1430    }
1431
1432    #[inline]
1433    unsafe fn get_param<'w, 's>(
1434        _state: &'s mut Self::State,
1435        _system_meta: &SystemMeta,
1436        world: UnsafeWorldCell<'w>,
1437        _change_tick: Tick,
1438    ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
1439        Ok(world.archetypes())
1440    }
1441}
1442
1443// SAFETY: Only reads World components
1444unsafe impl<'a> ReadOnlySystemParam for &'a Components {}
1445
1446// SAFETY: no component value access
1447unsafe impl<'a> SystemParam for &'a Components {
1448    type State = ();
1449    type Item<'w, 's> = &'w Components;
1450
1451    fn init_state(_world: &mut World) -> Self::State {}
1452
1453    fn init_access(
1454        _state: &Self::State,
1455        _system_meta: &mut SystemMeta,
1456        _component_access_set: &mut FilteredAccessSet,
1457        _world: &mut World,
1458    ) {
1459    }
1460
1461    #[inline]
1462    unsafe fn get_param<'w, 's>(
1463        _state: &'s mut Self::State,
1464        _system_meta: &SystemMeta,
1465        world: UnsafeWorldCell<'w>,
1466        _change_tick: Tick,
1467    ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
1468        Ok(world.components())
1469    }
1470}
1471
1472// SAFETY: Only reads World entities
1473unsafe impl<'a> ReadOnlySystemParam for &'a Entities {}
1474
1475// SAFETY: no component value access
1476unsafe impl<'a> SystemParam for &'a Entities {
1477    type State = ();
1478    type Item<'w, 's> = &'w Entities;
1479
1480    fn init_state(_world: &mut World) -> Self::State {}
1481
1482    fn init_access(
1483        _state: &Self::State,
1484        _system_meta: &mut SystemMeta,
1485        _component_access_set: &mut FilteredAccessSet,
1486        _world: &mut World,
1487    ) {
1488    }
1489
1490    #[inline]
1491    unsafe fn get_param<'w, 's>(
1492        _state: &'s mut Self::State,
1493        _system_meta: &SystemMeta,
1494        world: UnsafeWorldCell<'w>,
1495        _change_tick: Tick,
1496    ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
1497        Ok(world.entities())
1498    }
1499}
1500
1501// SAFETY: Only reads World entities
1502unsafe impl<'a> ReadOnlySystemParam for &'a EntityAllocator {}
1503
1504// SAFETY: no component value access
1505unsafe impl<'a> SystemParam for &'a EntityAllocator {
1506    type State = ();
1507    type Item<'w, 's> = &'w EntityAllocator;
1508
1509    fn init_state(_world: &mut World) -> Self::State {}
1510
1511    fn init_access(
1512        _state: &Self::State,
1513        _system_meta: &mut SystemMeta,
1514        _component_access_set: &mut FilteredAccessSet,
1515        _world: &mut World,
1516    ) {
1517    }
1518
1519    #[inline]
1520    unsafe fn get_param<'w, 's>(
1521        _state: &'s mut Self::State,
1522        _system_meta: &SystemMeta,
1523        world: UnsafeWorldCell<'w>,
1524        _change_tick: Tick,
1525    ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
1526        Ok(world.entity_allocator())
1527    }
1528}
1529
1530// SAFETY: Only reads World bundles
1531unsafe impl<'a> ReadOnlySystemParam for &'a Bundles {}
1532
1533// SAFETY: no component value access
1534unsafe impl<'a> SystemParam for &'a Bundles {
1535    type State = ();
1536    type Item<'w, 's> = &'w Bundles;
1537
1538    fn init_state(_world: &mut World) -> Self::State {}
1539
1540    fn init_access(
1541        _state: &Self::State,
1542        _system_meta: &mut SystemMeta,
1543        _component_access_set: &mut FilteredAccessSet,
1544        _world: &mut World,
1545    ) {
1546    }
1547
1548    #[inline]
1549    unsafe fn get_param<'w, 's>(
1550        _state: &'s mut Self::State,
1551        _system_meta: &SystemMeta,
1552        world: UnsafeWorldCell<'w>,
1553        _change_tick: Tick,
1554    ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
1555        Ok(world.bundles())
1556    }
1557}
1558
1559/// A [`SystemParam`] that reads the previous and current change ticks of the system.
1560///
1561/// A system's change ticks are updated each time it runs:
1562/// - `last_run` copies the previous value of `change_tick`
1563/// - `this_run` copies the current value of [`World::read_change_tick`]
1564///
1565/// Component change ticks that are more recent than `last_run` will be detected by the system.
1566/// Those can be read by calling [`last_changed`](crate::change_detection::DetectChanges::last_changed)
1567/// on a [`Mut<T>`](crate::change_detection::Mut) or [`ResMut<T>`](ResMut).
1568#[derive(Debug, Clone, Copy)]
1569pub struct SystemChangeTick {
1570    last_run: Tick,
1571    this_run: Tick,
1572}
1573
1574impl SystemChangeTick {
1575    /// Returns the current [`World`] change tick seen by the system.
1576    #[inline]
1577    pub fn this_run(&self) -> Tick {
1578        self.this_run
1579    }
1580
1581    /// Returns the [`World`] change tick seen by the system the previous time it ran.
1582    #[inline]
1583    pub fn last_run(&self) -> Tick {
1584        self.last_run
1585    }
1586}
1587
1588// SAFETY: Only reads internal system state
1589unsafe impl ReadOnlySystemParam for SystemChangeTick {}
1590
1591// SAFETY: `SystemChangeTick` doesn't require any world access
1592unsafe impl SystemParam for SystemChangeTick {
1593    type State = ();
1594    type Item<'w, 's> = SystemChangeTick;
1595
1596    fn init_state(_world: &mut World) -> Self::State {}
1597
1598    fn init_access(
1599        _state: &Self::State,
1600        _system_meta: &mut SystemMeta,
1601        _component_access_set: &mut FilteredAccessSet,
1602        _world: &mut World,
1603    ) {
1604    }
1605
1606    #[inline]
1607    unsafe fn get_param<'w, 's>(
1608        _state: &'s mut Self::State,
1609        system_meta: &SystemMeta,
1610        _world: UnsafeWorldCell<'w>,
1611        change_tick: Tick,
1612    ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
1613        Ok(SystemChangeTick {
1614            last_run: system_meta.last_run,
1615            this_run: change_tick,
1616        })
1617    }
1618}
1619
1620// SAFETY: Delegates to `T`, which ensures the safety requirements are met
1621unsafe impl<T: SystemParam> SystemParam for Option<T> {
1622    type State = T::State;
1623
1624    type Item<'world, 'state> = Option<T::Item<'world, 'state>>;
1625
1626    fn init_state(world: &mut World) -> Self::State {
1627        T::init_state(world)
1628    }
1629
1630    fn init_access(
1631        state: &Self::State,
1632        system_meta: &mut SystemMeta,
1633        component_access_set: &mut FilteredAccessSet,
1634        world: &mut World,
1635    ) {
1636        T::init_access(state, system_meta, component_access_set, world);
1637    }
1638
1639    #[inline]
1640    unsafe fn get_param<'world, 'state>(
1641        state: &'state mut Self::State,
1642        system_meta: &SystemMeta,
1643        world: UnsafeWorldCell<'world>,
1644        change_tick: Tick,
1645    ) -> Result<Self::Item<'world, 'state>, SystemParamValidationError> {
1646        // SAFETY: Upheld by caller
1647        Ok(unsafe { T::get_param(state, system_meta, world, change_tick) }.ok())
1648    }
1649
1650    fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World) {
1651        T::apply(state, system_meta, world);
1652    }
1653
1654    fn queue(state: &mut Self::State, system_meta: &SystemMeta, world: DeferredWorld) {
1655        T::queue(state, system_meta, world);
1656    }
1657}
1658
1659// SAFETY: Delegates to `T`, which ensures the safety requirements are met
1660unsafe impl<T: ReadOnlySystemParam> ReadOnlySystemParam for Option<T> {}
1661
1662// SAFETY: Delegates to `T`, which ensures the safety requirements are met
1663unsafe impl<T: SystemParam> SystemParam for Result<T, SystemParamValidationError> {
1664    type State = T::State;
1665
1666    type Item<'world, 'state> = Result<T::Item<'world, 'state>, SystemParamValidationError>;
1667
1668    fn init_state(world: &mut World) -> Self::State {
1669        T::init_state(world)
1670    }
1671
1672    fn init_access(
1673        state: &Self::State,
1674        system_meta: &mut SystemMeta,
1675        component_access_set: &mut FilteredAccessSet,
1676        world: &mut World,
1677    ) {
1678        T::init_access(state, system_meta, component_access_set, world);
1679    }
1680
1681    #[inline]
1682    unsafe fn get_param<'world, 'state>(
1683        state: &'state mut Self::State,
1684        system_meta: &SystemMeta,
1685        world: UnsafeWorldCell<'world>,
1686        change_tick: Tick,
1687    ) -> Result<Self::Item<'world, 'state>, SystemParamValidationError> {
1688        // SAFETY: Upheld by caller
1689        Ok(unsafe { T::get_param(state, system_meta, world, change_tick) })
1690    }
1691
1692    fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World) {
1693        T::apply(state, system_meta, world);
1694    }
1695
1696    fn queue(state: &mut Self::State, system_meta: &SystemMeta, world: DeferredWorld) {
1697        T::queue(state, system_meta, world);
1698    }
1699}
1700
1701// SAFETY: Delegates to `T`, which ensures the safety requirements are met
1702unsafe impl<T: ReadOnlySystemParam> ReadOnlySystemParam for Result<T, SystemParamValidationError> {}
1703
1704/// A [`SystemParam`] that wraps another parameter and causes its system to skip instead of failing when the parameter is invalid.
1705///
1706/// # Example
1707///
1708/// ```
1709/// # use bevy_ecs::prelude::*;
1710/// # #[derive(Resource)]
1711/// # struct SomeResource;
1712/// // This system will fail if `SomeResource` is not present.
1713/// fn fails_on_missing_resource(res: Res<SomeResource>) {}
1714///
1715/// // This system will skip without error if `SomeResource` is not present.
1716/// fn skips_on_missing_resource(res: If<Res<SomeResource>>) {
1717///     // The inner parameter is available using `Deref`
1718///     let some_resource: &SomeResource = &res;
1719/// }
1720/// # bevy_ecs::system::assert_is_system(skips_on_missing_resource);
1721/// ```
1722#[derive(Debug)]
1723pub struct If<T>(pub T);
1724
1725impl<T> If<T> {
1726    /// Returns the inner `T`.
1727    ///
1728    /// The inner value is `pub`, so you can also obtain it by destructuring the parameter:
1729    ///
1730    /// ```
1731    /// # use bevy_ecs::prelude::*;
1732    /// # #[derive(Resource)]
1733    /// # struct SomeResource;
1734    /// fn skips_on_missing_resource(If(res): If<Res<SomeResource>>) {
1735    ///     let some_resource: Res<SomeResource> = res;
1736    /// }
1737    /// # bevy_ecs::system::assert_is_system(skips_on_missing_resource);
1738    /// ```
1739    pub fn into_inner(self) -> T {
1740        self.0
1741    }
1742}
1743
1744impl<T> Deref for If<T> {
1745    type Target = T;
1746    fn deref(&self) -> &Self::Target {
1747        &self.0
1748    }
1749}
1750
1751impl<T> DerefMut for If<T> {
1752    fn deref_mut(&mut self) -> &mut Self::Target {
1753        &mut self.0
1754    }
1755}
1756
1757// SAFETY: Delegates to `T`, which ensures the safety requirements are met
1758unsafe impl<T: SystemParam> SystemParam for If<T> {
1759    type State = T::State;
1760
1761    type Item<'world, 'state> = If<T::Item<'world, 'state>>;
1762
1763    fn init_state(world: &mut World) -> Self::State {
1764        T::init_state(world)
1765    }
1766
1767    fn init_access(
1768        state: &Self::State,
1769        system_meta: &mut SystemMeta,
1770        component_access_set: &mut FilteredAccessSet,
1771        world: &mut World,
1772    ) {
1773        T::init_access(state, system_meta, component_access_set, world);
1774    }
1775
1776    #[inline]
1777    unsafe fn get_param<'world, 'state>(
1778        state: &'state mut Self::State,
1779        system_meta: &SystemMeta,
1780        world: UnsafeWorldCell<'world>,
1781        change_tick: Tick,
1782    ) -> Result<Self::Item<'world, 'state>, SystemParamValidationError> {
1783        // SAFETY: Upheld by caller.
1784        unsafe { T::get_param(state, system_meta, world, change_tick) }
1785            .map(If)
1786            .map_err(|mut e| {
1787                e.skipped = true;
1788                e
1789            })
1790    }
1791
1792    fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World) {
1793        T::apply(state, system_meta, world);
1794    }
1795
1796    fn queue(state: &mut Self::State, system_meta: &SystemMeta, world: DeferredWorld) {
1797        T::queue(state, system_meta, world);
1798    }
1799}
1800
1801// SAFETY: Delegates to `T`, which ensures the safety requirements are met
1802unsafe impl<T: ReadOnlySystemParam> ReadOnlySystemParam for If<T> {}
1803
1804// SAFETY: Registers access for each element of `state`.
1805// If any one conflicts, it will panic.
1806unsafe impl<T: SystemParam> SystemParam for Vec<T> {
1807    type State = Vec<T::State>;
1808
1809    type Item<'world, 'state> = Vec<T::Item<'world, 'state>>;
1810
1811    fn init_state(_world: &mut World) -> Self::State {
1812        Vec::new()
1813    }
1814
1815    fn init_access(
1816        state: &Self::State,
1817        system_meta: &mut SystemMeta,
1818        component_access_set: &mut FilteredAccessSet,
1819        world: &mut World,
1820    ) {
1821        for state in state {
1822            T::init_access(state, system_meta, component_access_set, world);
1823        }
1824    }
1825
1826    #[inline]
1827    unsafe fn get_param<'world, 'state>(
1828        state: &'state mut Self::State,
1829        system_meta: &SystemMeta,
1830        world: UnsafeWorldCell<'world>,
1831        change_tick: Tick,
1832    ) -> Result<Self::Item<'world, 'state>, SystemParamValidationError> {
1833        state
1834            .iter_mut()
1835            // SAFETY:
1836            // - We initialized the access for each parameter in `init_access`, so the caller ensures we have access to any world data needed by each param.
1837            // - The caller ensures this was the world used to initialize our state, and we used that world to initialize parameter states
1838            .map(|state| unsafe { T::get_param(state, system_meta, world, change_tick) })
1839            .collect()
1840    }
1841
1842    fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World) {
1843        for state in state {
1844            T::apply(state, system_meta, world);
1845        }
1846    }
1847
1848    fn queue(state: &mut Self::State, system_meta: &SystemMeta, mut world: DeferredWorld) {
1849        for state in state {
1850            T::queue(state, system_meta, world.reborrow());
1851        }
1852    }
1853}
1854
1855// SAFETY: Registers access for each element of `state`.
1856// If any one conflicts with a previous parameter,
1857// the call passing a copy of the current access will panic.
1858unsafe impl<T: SystemParam> SystemParam for ParamSet<'_, '_, Vec<T>> {
1859    type State = Vec<T::State>;
1860
1861    type Item<'world, 'state> = ParamSet<'world, 'state, Vec<T>>;
1862
1863    fn init_state(_world: &mut World) -> Self::State {
1864        Vec::new()
1865    }
1866
1867    fn init_access(
1868        state: &Self::State,
1869        system_meta: &mut SystemMeta,
1870        component_access_set: &mut FilteredAccessSet,
1871        world: &mut World,
1872    ) {
1873        for state in state {
1874            // Call `init_access` on a clone of the original access set to check for conflicts
1875            let component_access_set_clone = &mut component_access_set.clone();
1876            T::init_access(state, system_meta, component_access_set_clone, world);
1877        }
1878        for state in state {
1879            // Pretend to add the param to the system alone to gather the new access,
1880            // then merge its access into the system.
1881            let mut access_set = FilteredAccessSet::new();
1882            T::init_access(state, system_meta, &mut access_set, world);
1883            component_access_set.extend(access_set);
1884        }
1885    }
1886
1887    #[inline]
1888    unsafe fn get_param<'world, 'state>(
1889        state: &'state mut Self::State,
1890        system_meta: &SystemMeta,
1891        world: UnsafeWorldCell<'world>,
1892        change_tick: Tick,
1893    ) -> Result<Self::Item<'world, 'state>, SystemParamValidationError> {
1894        // Validate each sub-param eagerly so that the system is correctly
1895        // skipped by the executor when any sub-param is unavailable.
1896        // PERF: the sub-params will be fetched again lazily when accessed through
1897        // the ParamSet, but this is no worse than the previous
1898        // validate_param + get_param pattern.
1899        for s in state.iter_mut() {
1900            // SAFETY: Upheld by caller.
1901            drop(unsafe { T::get_param(s, system_meta, world, change_tick) }?);
1902        }
1903
1904        Ok(ParamSet {
1905            param_states: state,
1906            system_meta: system_meta.clone(),
1907            world,
1908            change_tick,
1909        })
1910    }
1911
1912    fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World) {
1913        for state in state {
1914            T::apply(state, system_meta, world);
1915        }
1916    }
1917
1918    fn queue(state: &mut Self::State, system_meta: &SystemMeta, mut world: DeferredWorld) {
1919        for state in state {
1920            T::queue(state, system_meta, world.reborrow());
1921        }
1922    }
1923}
1924
1925impl<T: SystemParam> ParamSet<'_, '_, Vec<T>> {
1926    /// Accesses the parameter at the given index.
1927    /// No other parameters may be accessed while this one is active.
1928    pub fn get_mut(&mut self, index: usize) -> T::Item<'_, '_> {
1929        // SAFETY:
1930        // - We initialized the access for each parameter, so the caller ensures we have access to any world data needed by any param.
1931        //   We have mutable access to the ParamSet, so no other params in the set are active.
1932        // - The caller of `get_param` ensured that this was the world used to initialize our state, and we used that world to initialize parameter states
1933        unsafe {
1934            T::get_param(
1935                &mut self.param_states[index],
1936                &self.system_meta,
1937                self.world,
1938                self.change_tick,
1939            )
1940            .unwrap()
1941        }
1942    }
1943
1944    /// Calls a closure for each parameter in the set.
1945    pub fn for_each(&mut self, mut f: impl FnMut(T::Item<'_, '_>)) {
1946        self.param_states.iter_mut().for_each(|state| {
1947            f(
1948                // SAFETY:
1949                // - We initialized the access for each parameter, so the caller ensures we have access to any world data needed by any param.
1950                //   We have mutable access to the ParamSet, so no other params in the set are active.
1951                // - The caller of `get_param` ensured that this was the world used to initialize our state, and we used that world to initialize parameter states
1952                unsafe { T::get_param(state, &self.system_meta, self.world, self.change_tick) }
1953                    .unwrap_or_else(|err| panic!("ParamSet parameter validation failed: {err}")),
1954            );
1955        });
1956    }
1957}
1958
1959// SAFETY: Registers access for each element of `state`.
1960// If any one conflicts, it will panic.
1961unsafe impl<T: SystemParam, const N: usize> SystemParam for SmallVec<[T; N]> {
1962    type State = SmallVec<[T::State; N]>;
1963
1964    type Item<'world, 'state> = SmallVec<[T::Item<'world, 'state>; N]>;
1965
1966    fn init_state(_world: &mut World) -> Self::State {
1967        SmallVec::new()
1968    }
1969
1970    fn init_access(
1971        state: &Self::State,
1972        system_meta: &mut SystemMeta,
1973        component_access_set: &mut FilteredAccessSet,
1974        world: &mut World,
1975    ) {
1976        for state in state {
1977            T::init_access(state, system_meta, component_access_set, world);
1978        }
1979    }
1980
1981    #[inline]
1982    unsafe fn get_param<'world, 'state>(
1983        state: &'state mut Self::State,
1984        system_meta: &SystemMeta,
1985        world: UnsafeWorldCell<'world>,
1986        change_tick: Tick,
1987    ) -> Result<Self::Item<'world, 'state>, SystemParamValidationError> {
1988        state
1989            .iter_mut()
1990            // SAFETY:
1991            // - We initialized the access for each parameter in `init_access`, so the caller ensures we have access to any world data needed by each param.
1992            // - The caller ensures this was the world used to initialize our state, and we used that world to initialize parameter states
1993            .map(|state| unsafe { T::get_param(state, system_meta, world, change_tick) })
1994            .collect()
1995    }
1996
1997    fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World) {
1998        for state in state {
1999            T::apply(state, system_meta, world);
2000        }
2001    }
2002
2003    fn queue(state: &mut Self::State, system_meta: &SystemMeta, mut world: DeferredWorld) {
2004        for state in state {
2005            T::queue(state, system_meta, world.reborrow());
2006        }
2007    }
2008}
2009
2010macro_rules! impl_system_param_tuple {
2011    ($(#[$meta:meta])* $($param: ident),*) => {
2012        $(#[$meta])*
2013        // SAFETY: tuple consists only of ReadOnlySystemParams
2014        unsafe impl<$($param: ReadOnlySystemParam),*> ReadOnlySystemParam for ($($param,)*) {}
2015
2016        #[expect(
2017            clippy::allow_attributes,
2018            reason = "This is in a macro, and as such, the below lints may not always apply."
2019        )]
2020        #[allow(
2021            non_snake_case,
2022            reason = "Certain variable names are provided by the caller, not by us."
2023        )]
2024        #[allow(
2025            unused_variables,
2026            reason = "Zero-length tuples won't use some of the parameters."
2027        )]
2028        #[allow(clippy::unused_unit, reason = "Zero length tuple is unit.")]
2029        $(#[$meta])*
2030        // SAFETY: implementers of each `SystemParam` in the tuple have validated their impls
2031        unsafe impl<$($param: SystemParam),*> SystemParam for ($($param,)*) {
2032            type State = ($($param::State,)*);
2033            type Item<'w, 's> = ($($param::Item::<'w, 's>,)*);
2034
2035            #[inline]
2036            #[track_caller]
2037            fn init_state(world: &mut World) -> Self::State {
2038                ($($param::init_state(world),)*)
2039            }
2040
2041            fn init_access(state: &Self::State, _system_meta: &mut SystemMeta, _component_access_set: &mut FilteredAccessSet, _world: &mut World) {
2042                let ($($param,)*) = state;
2043                $($param::init_access($param, _system_meta, _component_access_set, _world);)*
2044            }
2045
2046            #[inline]
2047            fn apply(($($param,)*): &mut Self::State, system_meta: &SystemMeta, world: &mut World) {
2048                $($param::apply($param, system_meta, world);)*
2049            }
2050
2051            #[inline]
2052            #[allow(
2053                unused_mut,
2054                reason = "The `world` parameter is unused for zero-length tuples; however, it must be mutable for other lengths of tuples."
2055            )]
2056            fn queue(($($param,)*): &mut Self::State, system_meta: &SystemMeta, mut world: DeferredWorld) {
2057                $($param::queue($param, system_meta, world.reborrow());)*
2058            }
2059
2060            #[inline]
2061            #[track_caller]
2062            unsafe fn get_param<'w, 's>(
2063                state: &'s mut Self::State,
2064                system_meta: &SystemMeta,
2065                world: UnsafeWorldCell<'w>,
2066                change_tick: Tick,
2067            ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
2068                let ($($param,)*) = state;
2069
2070                #[allow(
2071                    unused_unsafe,
2072                    reason = "Zero-length tuples won't have any params to validate."
2073                )]
2074                // SAFETY: Upheld by caller
2075                unsafe {
2076                    #[allow(
2077                        clippy::unused_unit,
2078                        reason = "Zero-length tuples won't have any params to get."
2079                    )]
2080                    Ok(($($param::get_param($param, system_meta, world, change_tick)?,)*))
2081                }
2082            }
2083        }
2084    };
2085}
2086
2087all_tuples!(
2088    #[doc(fake_variadic)]
2089    impl_system_param_tuple,
2090    0,
2091    16,
2092    P
2093);
2094
2095/// Contains type aliases for built-in [`SystemParam`]s with `'static` lifetimes.
2096/// This makes it more convenient to refer to these types in contexts where
2097/// explicit lifetime annotations are required.
2098///
2099/// Note that this is entirely safe and tracks lifetimes correctly.
2100/// This purely exists for convenience.
2101///
2102/// You can't instantiate a static `SystemParam`, you'll always end up with
2103/// `Res<'w, T>`, `ResMut<'w, T>` or `&'w T` bound to the lifetime of the provided
2104/// `&'w World`.
2105///
2106/// [`SystemParam`]: super::SystemParam
2107pub mod lifetimeless {
2108    /// A [`Query`](super::Query) with `'static` lifetimes.
2109    pub type SQuery<D, F = ()> = super::Query<'static, 'static, D, F>;
2110    /// A shorthand for writing `&'static T`.
2111    pub type Read<T> = &'static T;
2112    /// A shorthand for writing `&'static mut T`.
2113    pub type Write<T> = &'static mut T;
2114    /// A [`Res`](super::Res) with `'static` lifetimes.
2115    pub type SRes<T> = super::Res<'static, T>;
2116    /// A [`ResMut`](super::ResMut) with `'static` lifetimes.
2117    pub type SResMut<T> = super::ResMut<'static, T>;
2118    /// [`Commands`](crate::system::Commands) with `'static` lifetimes.
2119    pub type SCommands = crate::system::Commands<'static, 'static>;
2120}
2121
2122/// A helper for using system parameters in generic contexts
2123///
2124/// This type is a [`SystemParam`] adapter which always has
2125/// `Self::Item == Self` (ignoring lifetimes for brevity),
2126/// no matter the argument [`SystemParam`] (`P`) (other than
2127/// that `P` must be `'static`)
2128///
2129/// This makes it useful for having arbitrary [`SystemParam`] type arguments
2130/// to function systems, or for generic types using the [`derive@SystemParam`]
2131/// derive:
2132///
2133/// ```
2134/// # use bevy_ecs::prelude::*;
2135/// use bevy_ecs::system::{SystemParam, StaticSystemParam};
2136/// #[derive(SystemParam)]
2137/// struct GenericParam<'w,'s, T: SystemParam + 'static> {
2138///     field: StaticSystemParam<'w, 's, T>,
2139/// }
2140/// fn do_thing_generically<T: SystemParam + 'static>(t: StaticSystemParam<T>) {}
2141///
2142/// fn check_always_is_system<T: SystemParam + 'static>(){
2143///     bevy_ecs::system::assert_is_system(do_thing_generically::<T>);
2144/// }
2145/// ```
2146/// Note that in a real case you'd generally want
2147/// additional bounds on `P`, for your use of the parameter
2148/// to have a reason to be generic.
2149///
2150/// For example, using this would allow a type to be generic over
2151/// whether a resource is accessed mutably or not, with
2152/// impls being bounded on [`P: Deref<Target=MyType>`](Deref), and
2153/// [`P: DerefMut<Target=MyType>`](DerefMut) depending on whether the
2154/// method requires mutable access or not.
2155///
2156/// The method which doesn't use this type will not compile:
2157/// ```compile_fail
2158/// # use bevy_ecs::prelude::*;
2159/// # use bevy_ecs::system::{SystemParam, StaticSystemParam};
2160///
2161/// fn do_thing_generically<T: SystemParam + 'static>(t: T) {}
2162///
2163/// #[derive(SystemParam)]
2164/// struct GenericParam<'w, 's, T: SystemParam> {
2165///     field: T,
2166///     // Use the lifetimes in this type, or they will be unbound.
2167///     phantom: std::marker::PhantomData<&'w &'s ()>
2168/// }
2169/// # fn check_always_is_system<T: SystemParam + 'static>(){
2170/// #    bevy_ecs::system::assert_is_system(do_thing_generically::<T>);
2171/// # }
2172/// ```
2173pub struct StaticSystemParam<'w, 's, P: SystemParam>(SystemParamItem<'w, 's, P>);
2174
2175impl<'w, 's, P: SystemParam> Deref for StaticSystemParam<'w, 's, P> {
2176    type Target = SystemParamItem<'w, 's, P>;
2177
2178    fn deref(&self) -> &Self::Target {
2179        &self.0
2180    }
2181}
2182
2183impl<'w, 's, P: SystemParam> DerefMut for StaticSystemParam<'w, 's, P> {
2184    fn deref_mut(&mut self) -> &mut Self::Target {
2185        &mut self.0
2186    }
2187}
2188
2189impl<'w, 's, P: SystemParam> StaticSystemParam<'w, 's, P> {
2190    /// Get the value of the parameter
2191    pub fn into_inner(self) -> SystemParamItem<'w, 's, P> {
2192        self.0
2193    }
2194}
2195
2196// SAFETY: This doesn't add any more reads, and the delegated fetch confirms it
2197unsafe impl<'w, 's, P: ReadOnlySystemParam + 'static> ReadOnlySystemParam
2198    for StaticSystemParam<'w, 's, P>
2199{
2200}
2201
2202// SAFETY: all methods are just delegated to `P`'s `SystemParam` implementation
2203unsafe impl<P: SystemParam + 'static> SystemParam for StaticSystemParam<'_, '_, P> {
2204    type State = P::State;
2205    type Item<'world, 'state> = StaticSystemParam<'world, 'state, P>;
2206
2207    fn init_state(world: &mut World) -> Self::State {
2208        P::init_state(world)
2209    }
2210
2211    fn init_access(
2212        state: &Self::State,
2213        system_meta: &mut SystemMeta,
2214        component_access_set: &mut FilteredAccessSet,
2215        world: &mut World,
2216    ) {
2217        P::init_access(state, system_meta, component_access_set, world);
2218    }
2219
2220    fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World) {
2221        P::apply(state, system_meta, world);
2222    }
2223
2224    fn queue(state: &mut Self::State, system_meta: &SystemMeta, world: DeferredWorld) {
2225        P::queue(state, system_meta, world);
2226    }
2227
2228    #[inline]
2229    unsafe fn get_param<'world, 'state>(
2230        state: &'state mut Self::State,
2231        system_meta: &SystemMeta,
2232        world: UnsafeWorldCell<'world>,
2233        change_tick: Tick,
2234    ) -> Result<Self::Item<'world, 'state>, SystemParamValidationError> {
2235        // SAFETY: Defer to the safety of P::SystemParam
2236        unsafe { P::get_param(state, system_meta, world, change_tick) }.map(StaticSystemParam)
2237    }
2238}
2239
2240// SAFETY: No world access.
2241unsafe impl<T: ?Sized> SystemParam for PhantomData<T> {
2242    type State = ();
2243    type Item<'world, 'state> = Self;
2244
2245    fn init_state(_world: &mut World) -> Self::State {}
2246
2247    fn init_access(
2248        _state: &Self::State,
2249        _system_meta: &mut SystemMeta,
2250        _component_access_set: &mut FilteredAccessSet,
2251        _world: &mut World,
2252    ) {
2253    }
2254
2255    #[inline]
2256    unsafe fn get_param<'world, 'state>(
2257        _state: &'state mut Self::State,
2258        _system_meta: &SystemMeta,
2259        _world: UnsafeWorldCell<'world>,
2260        _change_tick: Tick,
2261    ) -> Result<Self::Item<'world, 'state>, SystemParamValidationError> {
2262        Ok(PhantomData)
2263    }
2264}
2265
2266// SAFETY: No world access.
2267unsafe impl<T: ?Sized> ReadOnlySystemParam for PhantomData<T> {}
2268
2269/// A [`SystemParam`] with a type that can be configured at runtime.
2270///
2271/// To be useful, this must be configured using a [`DynParamBuilder`](crate::system::DynParamBuilder) to build the system using a [`SystemParamBuilder`](crate::prelude::SystemParamBuilder).
2272///
2273/// # Examples
2274///
2275/// ```
2276/// # use bevy_ecs::{prelude::*, system::*};
2277/// #
2278/// # #[derive(Default, Resource)]
2279/// # struct A;
2280/// #
2281/// # #[derive(Default, Resource)]
2282/// # struct B;
2283/// #
2284/// # let mut world = World::new();
2285/// # world.init_resource::<A>();
2286/// # world.init_resource::<B>();
2287/// #
2288/// // If the inner parameter doesn't require any special building, use `ParamBuilder`.
2289/// // Either specify the type parameter on `DynParamBuilder::new()` ...
2290/// let system = (DynParamBuilder::new::<Res<A>>(ParamBuilder),)
2291///     .build_state(&mut world)
2292///     .build_system(expects_res_a);
2293/// # world.run_system_once(system);
2294///
2295/// // ... or use a factory method on `ParamBuilder` that returns a specific type.
2296/// let system = (DynParamBuilder::new(ParamBuilder::resource::<A>()),)
2297///     .build_state(&mut world)
2298///     .build_system(expects_res_a);
2299/// # world.run_system_once(system);
2300///
2301/// fn expects_res_a(mut param: DynSystemParam) {
2302///     // Use the `downcast` methods to retrieve the inner parameter.
2303///     // They will return `None` if the type does not match.
2304///     assert!(param.is::<Res<A>>());
2305///     assert!(!param.is::<Res<B>>());
2306///     assert!(param.downcast_mut::<Res<B>>().is_none());
2307///     let res = param.downcast_mut::<Res<A>>().unwrap();
2308///     // The type parameter can be left out if it can be determined from use.
2309///     let res: Res<A> = param.downcast().unwrap();
2310/// }
2311///
2312/// let system = (
2313///     // If the inner parameter also requires building,
2314///     // pass the appropriate `SystemParamBuilder`.
2315///     DynParamBuilder::new(LocalBuilder(10usize)),
2316///     // `DynSystemParam` is just an ordinary `SystemParam`,
2317///     // and can be combined with other parameters as usual!
2318///     ParamBuilder::query(),
2319/// )
2320///     .build_state(&mut world)
2321///     .build_system(|param: DynSystemParam, query: Query<()>| {
2322///         let local: Local<usize> = param.downcast::<Local<usize>>().unwrap();
2323///         assert_eq!(*local, 10);
2324///     });
2325/// # world.run_system_once(system);
2326/// ```
2327pub struct DynSystemParam<'w, 's> {
2328    /// A `ParamState<T>` wrapping the state for the underlying system param.
2329    state: &'s mut dyn Any,
2330    world: UnsafeWorldCell<'w>,
2331    system_meta: SystemMeta,
2332    change_tick: Tick,
2333}
2334
2335impl<'w, 's> DynSystemParam<'w, 's> {
2336    /// # Safety
2337    /// - `state` must be a `ParamState<T>` for some inner `T: SystemParam`.
2338    /// - The passed [`UnsafeWorldCell`] must have access to any world data registered
2339    ///   in [`init_state`](SystemParam::init_state) for the inner system param.
2340    /// - `world` must be the same `World` that was used to initialize
2341    ///   [`state`](SystemParam::init_state) for the inner system param.
2342    unsafe fn new(
2343        state: &'s mut dyn Any,
2344        world: UnsafeWorldCell<'w>,
2345        system_meta: SystemMeta,
2346        change_tick: Tick,
2347    ) -> Self {
2348        Self {
2349            state,
2350            world,
2351            system_meta,
2352            change_tick,
2353        }
2354    }
2355
2356    /// Returns `true` if the inner system param is the same as `T`.
2357    pub fn is<T: SystemParam>(&self) -> bool
2358    // See downcast() function for an explanation of the where clause
2359    where
2360        T::Item<'static, 'static>: SystemParam<Item<'w, 's> = T> + 'static,
2361    {
2362        self.state.is::<ParamState<T::Item<'static, 'static>>>()
2363    }
2364
2365    /// Returns the inner system param if it is the correct type.
2366    /// This consumes the dyn param, so the returned param can have its original world and state lifetimes.
2367    pub fn downcast<T: SystemParam>(self) -> Option<T>
2368    // See downcast() function for an explanation of the where clause
2369    where
2370        T::Item<'static, 'static>: SystemParam<Item<'w, 's> = T> + 'static,
2371    {
2372        // SAFETY:
2373        // - `DynSystemParam::new()` ensures `state` is a `ParamState<T>`, that the world matches,
2374        //   and that it has access required by the inner system param.
2375        // - This consumes the `DynSystemParam`, so it is the only use of `world` with this access and it is available for `'w`.
2376        unsafe { downcast::<T>(self.state, &self.system_meta, self.world, self.change_tick) }
2377    }
2378
2379    /// Returns the inner system parameter if it is the correct type.
2380    /// This borrows the dyn param, so the returned param is only valid for the duration of that borrow.
2381    pub fn downcast_mut<'a, T: SystemParam>(&'a mut self) -> Option<T>
2382    // See downcast() function for an explanation of the where clause
2383    where
2384        T::Item<'static, 'static>: SystemParam<Item<'a, 'a> = T> + 'static,
2385    {
2386        // SAFETY:
2387        // - `DynSystemParam::new()` ensures `state` is a `ParamState<T>`, that the world matches,
2388        //   and that it has access required by the inner system param.
2389        // - This exclusively borrows the `DynSystemParam` for `'_`, so it is the only use of `world` with this access for `'_`.
2390        unsafe { downcast::<T>(self.state, &self.system_meta, self.world, self.change_tick) }
2391    }
2392
2393    /// Returns the inner system parameter if it is the correct type.
2394    /// This borrows the dyn param, so the returned param is only valid for the duration of that borrow,
2395    /// but since it only performs read access it can keep the original world lifetime.
2396    /// This can be useful with methods like [`Query::iter_inner()`] or [`Res::into_inner()`]
2397    /// to obtain references with the original world lifetime.
2398    pub fn downcast_mut_inner<'a, T: ReadOnlySystemParam>(&'a mut self) -> Option<T>
2399    // See downcast() function for an explanation of the where clause
2400    where
2401        T::Item<'static, 'static>: SystemParam<Item<'w, 'a> = T> + 'static,
2402    {
2403        // SAFETY:
2404        // - `DynSystemParam::new()` ensures `state` is a `ParamState<T>`, that the world matches,
2405        //   and that it has access required by the inner system param.
2406        // - The inner system param only performs read access, so it's safe to copy that access for the full `'w` lifetime.
2407        unsafe { downcast::<T>(self.state, &self.system_meta, self.world, self.change_tick) }
2408    }
2409}
2410
2411/// # Safety
2412/// - `state` must be a `ParamState<T>` for some inner `T: SystemParam`.
2413/// - The passed [`UnsafeWorldCell`] must have access to any world data registered
2414///   in [`init_state`](SystemParam::init_state) for the inner system param.
2415/// - `world` must be the same `World` that was used to initialize
2416///   [`state`](SystemParam::init_state) for the inner system param.
2417unsafe fn downcast<'w, 's, T: SystemParam>(
2418    state: &'s mut dyn Any,
2419    system_meta: &SystemMeta,
2420    world: UnsafeWorldCell<'w>,
2421    change_tick: Tick,
2422) -> Option<T>
2423// We need a 'static version of the SystemParam to use with `Any::downcast_mut()`,
2424// and we need a <'w, 's> version to actually return.
2425// The type parameter T must be the one we return in order to get type inference from the return value.
2426// So we use `T::Item<'static, 'static>` as the 'static version, and require that it be 'static.
2427// That means the return value will be T::Item<'static, 'static>::Item<'w, 's>,
2428// so we constrain that to be equal to T.
2429// Every actual `SystemParam` implementation has `T::Item == T` up to lifetimes,
2430// so they should all work with this constraint.
2431where
2432    T::Item<'static, 'static>: SystemParam<Item<'w, 's> = T> + 'static,
2433{
2434    state
2435        .downcast_mut::<ParamState<T::Item<'static, 'static>>>()
2436        .and_then(|state| {
2437            // SAFETY:
2438            // - The caller ensures the world has access for the underlying system param,
2439            //   and since the downcast succeeded, the underlying system param is T.
2440            // - The caller ensures the `world` matches.
2441            unsafe { T::Item::get_param(&mut state.0, system_meta, world, change_tick) }.ok()
2442        })
2443}
2444
2445/// The [`SystemParam::State`] for a [`DynSystemParam`].
2446pub struct DynSystemParamState(Box<dyn DynParamState>);
2447
2448impl DynSystemParamState {
2449    pub(crate) fn new<T: SystemParam + 'static>(state: T::State) -> Self {
2450        Self(Box::new(ParamState::<T>(state)))
2451    }
2452}
2453
2454/// Allows a [`SystemParam::State`] to be used as a trait object for implementing [`DynSystemParam`].
2455trait DynParamState: Sync + Send + Any {
2456    /// Applies any deferred mutations stored in this [`SystemParam`]'s state.
2457    /// This is used to apply [`Commands`] during [`ApplyDeferred`](crate::prelude::ApplyDeferred).
2458    ///
2459    /// [`Commands`]: crate::prelude::Commands
2460    fn apply(&mut self, system_meta: &SystemMeta, world: &mut World);
2461
2462    /// Queues any deferred mutations to be applied at the next [`ApplyDeferred`](crate::prelude::ApplyDeferred).
2463    fn queue(&mut self, system_meta: &SystemMeta, world: DeferredWorld);
2464
2465    /// Registers any [`World`] access used by this [`SystemParam`]
2466    fn init_access(
2467        &self,
2468        system_meta: &mut SystemMeta,
2469        component_access_set: &mut FilteredAccessSet,
2470        world: &mut World,
2471    );
2472
2473    /// Validates the inner parameter by calling [`SystemParam::get_param`] and discarding the value.
2474    ///
2475    /// # Safety
2476    /// Refer to [`SystemParam::get_param`].
2477    unsafe fn validate(
2478        &mut self,
2479        system_meta: &SystemMeta,
2480        world: UnsafeWorldCell,
2481        change_tick: Tick,
2482    ) -> Result<(), SystemParamValidationError>;
2483}
2484
2485/// A wrapper around a [`SystemParam::State`] that can be used as a trait object in a [`DynSystemParam`].
2486struct ParamState<T: SystemParam>(T::State);
2487
2488impl<T: SystemParam + 'static> DynParamState for ParamState<T> {
2489    fn apply(&mut self, system_meta: &SystemMeta, world: &mut World) {
2490        T::apply(&mut self.0, system_meta, world);
2491    }
2492
2493    fn queue(&mut self, system_meta: &SystemMeta, world: DeferredWorld) {
2494        T::queue(&mut self.0, system_meta, world);
2495    }
2496
2497    fn init_access(
2498        &self,
2499        system_meta: &mut SystemMeta,
2500        component_access_set: &mut FilteredAccessSet,
2501        world: &mut World,
2502    ) {
2503        T::init_access(&self.0, system_meta, component_access_set, world);
2504    }
2505
2506    unsafe fn validate(
2507        &mut self,
2508        system_meta: &SystemMeta,
2509        world: UnsafeWorldCell,
2510        change_tick: Tick,
2511    ) -> Result<(), SystemParamValidationError> {
2512        // SAFETY: Upheld by caller.
2513        unsafe { T::get_param(&mut self.0, system_meta, world, change_tick) }.map(drop)
2514    }
2515}
2516
2517// SAFETY: Delegates to the wrapped parameter, which ensures the safety requirements are met
2518unsafe impl SystemParam for DynSystemParam<'_, '_> {
2519    type State = DynSystemParamState;
2520
2521    type Item<'world, 'state> = DynSystemParam<'world, 'state>;
2522
2523    fn init_state(_world: &mut World) -> Self::State {
2524        DynSystemParamState::new::<()>(())
2525    }
2526
2527    fn init_access(
2528        state: &Self::State,
2529        system_meta: &mut SystemMeta,
2530        component_access_set: &mut FilteredAccessSet,
2531        world: &mut World,
2532    ) {
2533        state
2534            .0
2535            .init_access(system_meta, component_access_set, world);
2536    }
2537
2538    #[inline]
2539    unsafe fn get_param<'world, 'state>(
2540        state: &'state mut Self::State,
2541        system_meta: &SystemMeta,
2542        world: UnsafeWorldCell<'world>,
2543        change_tick: Tick,
2544    ) -> Result<Self::Item<'world, 'state>, SystemParamValidationError> {
2545        // Validate the inner parameter eagerly so that systems using DynSystemParam
2546        // are correctly skipped by the executor when the inner param is unavailable.
2547        // SAFETY: Upheld by caller.
2548        unsafe { state.0.validate(system_meta, world, change_tick) }?;
2549        // SAFETY:
2550        // - `state.0` is a boxed `ParamState<T>`.
2551        // - `init_access` calls `DynParamState::init_access`, which calls `init_access` on the inner parameter,
2552        //   so the caller ensures the world has the necessary access.
2553        // - The caller ensures that the provided world is the same and has the required access.
2554        Ok(unsafe {
2555            DynSystemParam::new(state.0.as_mut(), world, system_meta.clone(), change_tick)
2556        })
2557    }
2558
2559    fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World) {
2560        state.0.apply(system_meta, world);
2561    }
2562
2563    fn queue(state: &mut Self::State, system_meta: &SystemMeta, world: DeferredWorld) {
2564        state.0.queue(system_meta, world);
2565    }
2566}
2567
2568// SAFETY: Resource ComponentId access is applied to the access. If this FilteredResources
2569// conflicts with any prior access, a panic will occur.
2570unsafe impl SystemParam for FilteredResources<'_, '_> {
2571    type State = Access;
2572
2573    type Item<'world, 'state> = FilteredResources<'world, 'state>;
2574
2575    fn init_state(_world: &mut World) -> Self::State {
2576        Access::new()
2577    }
2578
2579    fn init_access(
2580        access: &Self::State,
2581        system_meta: &mut SystemMeta,
2582        component_access_set: &mut FilteredAccessSet,
2583        world: &mut World,
2584    ) {
2585        let combined_access = component_access_set.combined_access();
2586        let conflicts = combined_access.get_conflicts(access);
2587        if !conflicts.is_empty() {
2588            let accesses = conflicts.format_conflict_list(world.into());
2589            let system_name = &system_meta.name;
2590            panic!("error[B0002]: FilteredResources in system {system_name} accesses resources(s){accesses} in a way that conflicts with a previous system parameter. Consider removing the duplicate access. See: https://bevy.org/learn/errors/b0002");
2591        }
2592
2593        let mut filter = FilteredAccess::matches_everything();
2594        filter.access_mut().extend(access);
2595        filter.and_with(IS_RESOURCE);
2596        component_access_set.add(filter);
2597    }
2598
2599    unsafe fn get_param<'world, 'state>(
2600        state: &'state mut Self::State,
2601        system_meta: &SystemMeta,
2602        world: UnsafeWorldCell<'world>,
2603        change_tick: Tick,
2604    ) -> Result<Self::Item<'world, 'state>, SystemParamValidationError> {
2605        // SAFETY: The caller ensures that `world` has access to anything registered in `init_access`,
2606        // and we registered all resource access in `state``.
2607        Ok(unsafe { FilteredResources::new(world, state, system_meta.last_run, change_tick) })
2608    }
2609}
2610
2611// SAFETY: FilteredResources only reads resources.
2612unsafe impl ReadOnlySystemParam for FilteredResources<'_, '_> {}
2613
2614// SAFETY: Resource ComponentId access is applied to the access. If this FilteredResourcesMut
2615// conflicts with any prior access, a panic will occur.
2616unsafe impl SystemParam for FilteredResourcesMut<'_, '_> {
2617    type State = Access;
2618
2619    type Item<'world, 'state> = FilteredResourcesMut<'world, 'state>;
2620
2621    fn init_state(_world: &mut World) -> Self::State {
2622        Access::new()
2623    }
2624
2625    fn init_access(
2626        access: &Self::State,
2627        system_meta: &mut SystemMeta,
2628        component_access_set: &mut FilteredAccessSet,
2629        world: &mut World,
2630    ) {
2631        let combined_access = component_access_set.combined_access();
2632        let conflicts = combined_access.get_conflicts(access);
2633        if !conflicts.is_empty() {
2634            let accesses = conflicts.format_conflict_list(world.into());
2635            let system_name = &system_meta.name;
2636            panic!("error[B0002]: FilteredResourcesMut in system {system_name} accesses resources(s){accesses} in a way that conflicts with a previous system parameter. Consider removing the duplicate access. See: https://bevy.org/learn/errors/b0002");
2637        }
2638
2639        let mut filter = FilteredAccess::matches_everything();
2640        filter.access_mut().extend(access);
2641        filter.and_with(IS_RESOURCE);
2642        component_access_set.add(filter);
2643    }
2644
2645    unsafe fn get_param<'world, 'state>(
2646        state: &'state mut Self::State,
2647        system_meta: &SystemMeta,
2648        world: UnsafeWorldCell<'world>,
2649        change_tick: Tick,
2650    ) -> Result<Self::Item<'world, 'state>, SystemParamValidationError> {
2651        // SAFETY: The caller ensures that `world` has access to anything registered in `init_access`,
2652        // and we registered all resource access in `state``.
2653        Ok(unsafe { FilteredResourcesMut::new(world, state, system_meta.last_run, change_tick) })
2654    }
2655}
2656
2657/// An error that occurs when a system parameter is not valid,
2658/// used by system executors to determine what to do with a system.
2659///
2660/// Returned as an error from [`SystemParam::get_param`],
2661/// and handled using the unified error handling mechanisms defined in [`bevy_ecs::error`].
2662#[derive(Debug, PartialEq, Eq, Clone, Error)]
2663pub struct SystemParamValidationError {
2664    /// Whether the system should be skipped.
2665    ///
2666    /// If `false`, the error should be handled.
2667    /// By default, this will result in a panic. See [`error`](`crate::error`) for more information.
2668    ///
2669    /// This is the default behavior, and is suitable for system params that should *always* be valid,
2670    /// either because sensible fallback behavior exists (like [`Query`]) or because
2671    /// failures in validation should be considered a bug in the user's logic that must be immediately addressed (like [`Res`]).
2672    ///
2673    /// If `true`, the system should be skipped.
2674    /// This is set by wrapping the system param in [`If`],
2675    /// and indicates that the system is intended to only operate in certain application states.
2676    pub skipped: bool,
2677
2678    /// A message describing the validation error.
2679    pub message: Cow<'static, str>,
2680
2681    /// A string identifying the invalid parameter.
2682    /// This is usually the type name of the parameter.
2683    pub param: DebugName,
2684
2685    /// A string identifying the field within a parameter using `#[derive(SystemParam)]`.
2686    /// This will be an empty string for other parameters.
2687    ///
2688    /// This will be printed after `param` in the `Display` impl, and should include a `::` prefix if non-empty.
2689    pub field: Cow<'static, str>,
2690}
2691
2692impl SystemParamValidationError {
2693    /// Constructs a `SystemParamValidationError` that skips the system.
2694    /// The parameter name is initialized to the type name of `T`, so a `SystemParam` should usually pass `Self`.
2695    pub fn skipped<T>(message: impl Into<Cow<'static, str>>) -> Self {
2696        Self::new::<T>(true, message, Cow::Borrowed(""))
2697    }
2698
2699    /// Constructs a `SystemParamValidationError` for an invalid parameter that should be treated as an error.
2700    /// The parameter name is initialized to the type name of `T`, so a `SystemParam` should usually pass `Self`.
2701    pub fn invalid<T>(message: impl Into<Cow<'static, str>>) -> Self {
2702        Self::new::<T>(false, message, Cow::Borrowed(""))
2703    }
2704
2705    /// Constructs a `SystemParamValidationError` for an invalid parameter.
2706    /// The parameter name is initialized to the type name of `T`, so a `SystemParam` should usually pass `Self`.
2707    pub fn new<T>(
2708        skipped: bool,
2709        message: impl Into<Cow<'static, str>>,
2710        field: impl Into<Cow<'static, str>>,
2711    ) -> Self {
2712        Self {
2713            skipped,
2714            message: message.into(),
2715            param: DebugName::type_name::<T>(),
2716            field: field.into(),
2717        }
2718    }
2719
2720    pub(crate) const EMPTY: Self = Self {
2721        skipped: false,
2722        message: Cow::Borrowed(""),
2723        param: DebugName::borrowed(""),
2724        field: Cow::Borrowed(""),
2725    };
2726}
2727
2728impl Display for SystemParamValidationError {
2729    fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
2730        write!(
2731            fmt,
2732            "Parameter `{}{}` failed validation: {}",
2733            self.param.shortname(),
2734            self.field,
2735            self.message
2736        )?;
2737        if !self.skipped {
2738            write!(fmt, "\nIf this is an expected state, wrap the parameter in `Option<T>` and handle `None` when it happens, or wrap the parameter in `If<T>` to skip the system when it happens.")?;
2739        }
2740        Ok(())
2741    }
2742}
2743
2744#[cfg(test)]
2745mod tests {
2746    use super::*;
2747    use crate::query::Without;
2748    use crate::resource::IsResource;
2749    use crate::system::assert_is_system;
2750    use crate::world::EntityMut;
2751    use core::cell::RefCell;
2752
2753    #[test]
2754    #[should_panic]
2755    fn non_send_alias() {
2756        #[derive(Resource)]
2757        struct A(usize);
2758        fn my_system(mut res0: NonSendMut<A>, mut res1: NonSendMut<A>) {
2759            res0.0 += 1;
2760            res1.0 += 1;
2761        }
2762        let mut world = World::new();
2763        world.insert_non_send(A(42));
2764        let mut schedule = crate::schedule::Schedule::default();
2765        schedule.add_systems(my_system);
2766        schedule.run(&mut world);
2767    }
2768
2769    #[test]
2770    #[should_panic]
2771    fn non_send_and_entities() {
2772        #[derive(Resource)]
2773        struct A(usize);
2774        fn my_system(mut ns: NonSendMut<A>, _: Query<EntityMut>) {
2775            ns.0 += 1;
2776        }
2777        assert_is_system(my_system);
2778    }
2779
2780    #[test]
2781    #[should_panic]
2782    fn res_and_entities() {
2783        #[derive(Resource)]
2784        struct A(usize);
2785        fn my_system(mut res: ResMut<A>, _: Query<EntityMut>) {
2786            res.0 += 1;
2787        }
2788        assert_is_system(my_system);
2789    }
2790
2791    #[test]
2792    fn res_and_entities_filtered() {
2793        #[derive(Resource)]
2794        struct A(usize);
2795        fn res_system(mut res: ResMut<A>, _: Query<EntityMut, Without<IsResource>>) {
2796            res.0 += 1;
2797        }
2798        assert_is_system(res_system);
2799
2800        fn non_send_system(mut ns: NonSendMut<A>, _: Query<EntityMut, Without<A>>) {
2801            ns.0 += 1;
2802        }
2803
2804        assert_is_system(non_send_system);
2805    }
2806
2807    // Compile test for https://github.com/bevyengine/bevy/pull/2838.
2808    #[test]
2809    fn system_param_generic_bounds() {
2810        #[derive(SystemParam)]
2811        pub struct SpecialQuery<
2812            'w,
2813            's,
2814            D: QueryData + Send + Sync + 'static,
2815            F: QueryFilter + Send + Sync + 'static = (),
2816        > {
2817            _query: Query<'w, 's, D, F>,
2818        }
2819
2820        fn my_system(_: SpecialQuery<(), ()>) {}
2821        assert_is_system(my_system);
2822    }
2823
2824    // Compile tests for https://github.com/bevyengine/bevy/pull/6694.
2825    #[test]
2826    fn system_param_flexibility() {
2827        #[derive(SystemParam)]
2828        pub struct SpecialRes<'w, T: Resource> {
2829            _res: Res<'w, T>,
2830        }
2831
2832        #[derive(SystemParam)]
2833        pub struct SpecialLocal<'s, T: FromWorld + Send + 'static> {
2834            _local: Local<'s, T>,
2835        }
2836
2837        #[derive(Resource)]
2838        struct R;
2839
2840        fn my_system(_: SpecialRes<R>, _: SpecialLocal<u32>) {}
2841        assert_is_system(my_system);
2842    }
2843
2844    #[derive(Resource)]
2845    pub struct R<const I: usize>;
2846
2847    // Compile test for https://github.com/bevyengine/bevy/pull/7001.
2848    #[test]
2849    fn system_param_const_generics() {
2850        #[expect(
2851            dead_code,
2852            reason = "This struct is used to ensure that const generics are supported as a SystemParam; thus, the inner value never needs to be read."
2853        )]
2854        #[derive(SystemParam)]
2855        pub struct ConstGenericParam<'w, const I: usize>(Res<'w, R<I>>);
2856
2857        fn my_system(_: ConstGenericParam<0>, _: ConstGenericParam<1000>) {}
2858        assert_is_system(my_system);
2859    }
2860
2861    // Compile test for https://github.com/bevyengine/bevy/pull/6867.
2862    #[test]
2863    fn system_param_field_limit() {
2864        #[derive(SystemParam)]
2865        pub struct LongParam<'w> {
2866            // Each field should be a distinct type so there will
2867            // be an error if the derive messes up the field order.
2868            _r0: Res<'w, R<0>>,
2869            _r1: Res<'w, R<1>>,
2870            _r2: Res<'w, R<2>>,
2871            _r3: Res<'w, R<3>>,
2872            _r4: Res<'w, R<4>>,
2873            _r5: Res<'w, R<5>>,
2874            _r6: Res<'w, R<6>>,
2875            _r7: Res<'w, R<7>>,
2876            _r8: Res<'w, R<8>>,
2877            _r9: Res<'w, R<9>>,
2878            _r10: Res<'w, R<10>>,
2879            _r11: Res<'w, R<11>>,
2880            _r12: Res<'w, R<12>>,
2881            _r13: Res<'w, R<13>>,
2882            _r14: Res<'w, R<14>>,
2883            _r15: Res<'w, R<15>>,
2884            _r16: Res<'w, R<16>>,
2885        }
2886
2887        fn long_system(_: LongParam) {}
2888        assert_is_system(long_system);
2889    }
2890
2891    // Compile test for https://github.com/bevyengine/bevy/pull/6919.
2892    // Regression test for https://github.com/bevyengine/bevy/issues/7447.
2893    #[test]
2894    fn system_param_phantom_data() {
2895        #[derive(SystemParam)]
2896        struct PhantomParam<'w, T: Resource, Marker: 'static> {
2897            _foo: Res<'w, T>,
2898            marker: PhantomData<&'w Marker>,
2899        }
2900
2901        fn my_system(_: PhantomParam<R<0>, ()>) {}
2902        assert_is_system(my_system);
2903    }
2904
2905    // Compile tests for https://github.com/bevyengine/bevy/pull/6957.
2906    #[test]
2907    fn system_param_struct_variants() {
2908        #[derive(SystemParam)]
2909        pub struct UnitParam;
2910
2911        #[expect(
2912            dead_code,
2913            reason = "This struct is used to ensure that tuple structs are supported as a SystemParam; thus, the inner values never need to be read."
2914        )]
2915        #[derive(SystemParam)]
2916        pub struct TupleParam<'w, 's, R: Resource, L: FromWorld + Send + 'static>(
2917            Res<'w, R>,
2918            Local<'s, L>,
2919        );
2920
2921        fn my_system(_: UnitParam, _: TupleParam<R<0>, u32>) {}
2922        assert_is_system(my_system);
2923    }
2924
2925    // Regression test for https://github.com/bevyengine/bevy/issues/4200.
2926    #[test]
2927    fn system_param_private_fields() {
2928        #[derive(Resource)]
2929        struct PrivateResource;
2930
2931        #[expect(
2932            dead_code,
2933            reason = "This struct is used to ensure that SystemParam's derive can't leak private fields; thus, the inner values never need to be read."
2934        )]
2935        #[derive(SystemParam)]
2936        pub struct EncapsulatedParam<'w>(Res<'w, PrivateResource>);
2937
2938        fn my_system(_: EncapsulatedParam) {}
2939        assert_is_system(my_system);
2940    }
2941
2942    // Regression test for https://github.com/bevyengine/bevy/issues/7103.
2943    #[test]
2944    fn system_param_where_clause() {
2945        #[derive(SystemParam)]
2946        pub struct WhereParam<'w, 's, D>
2947        where
2948            D: 'static + QueryData,
2949        {
2950            _q: Query<'w, 's, D, ()>,
2951        }
2952
2953        fn my_system(_: WhereParam<()>) {}
2954        assert_is_system(my_system);
2955    }
2956
2957    // Regression test for https://github.com/bevyengine/bevy/issues/1727.
2958    #[test]
2959    fn system_param_name_collision() {
2960        #[derive(Resource)]
2961        pub struct FetchState;
2962
2963        #[derive(SystemParam)]
2964        pub struct Collide<'w> {
2965            _x: Res<'w, FetchState>,
2966        }
2967
2968        fn my_system(_: Collide) {}
2969        assert_is_system(my_system);
2970    }
2971
2972    // Regression test for https://github.com/bevyengine/bevy/issues/8192.
2973    #[test]
2974    fn system_param_invariant_lifetime() {
2975        #[derive(SystemParam)]
2976        pub struct InvariantParam<'w, 's> {
2977            _set: ParamSet<'w, 's, (Query<'w, 's, ()>,)>,
2978        }
2979
2980        fn my_system(_: InvariantParam) {}
2981        assert_is_system(my_system);
2982    }
2983
2984    // Compile test for https://github.com/bevyengine/bevy/pull/9589.
2985    #[test]
2986    fn non_sync_local() {
2987        fn non_sync_system(cell: Local<RefCell<u8>>) {
2988            assert_eq!(*cell.borrow(), 0);
2989        }
2990
2991        let mut world = World::new();
2992        let mut schedule = crate::schedule::Schedule::default();
2993        schedule.add_systems(non_sync_system);
2994        schedule.run(&mut world);
2995    }
2996
2997    // Regression test for https://github.com/bevyengine/bevy/issues/10207.
2998    #[test]
2999    fn param_set_non_send_first() {
3000        fn non_send_param_set(mut p: ParamSet<(NonSend<*mut u8>, ())>) {
3001            let _ = p.p0();
3002            p.p1();
3003        }
3004
3005        let mut world = World::new();
3006        world.insert_non_send(core::ptr::null_mut::<u8>());
3007        let mut schedule = crate::schedule::Schedule::default();
3008        schedule.add_systems((non_send_param_set, non_send_param_set, non_send_param_set));
3009        schedule.run(&mut world);
3010    }
3011
3012    // Regression test for https://github.com/bevyengine/bevy/issues/10207.
3013    #[test]
3014    fn param_set_non_send_second() {
3015        fn non_send_param_set(mut p: ParamSet<((), NonSendMut<*mut u8>)>) {
3016            p.p0();
3017            let _ = p.p1();
3018        }
3019
3020        let mut world = World::new();
3021        world.insert_non_send(core::ptr::null_mut::<u8>());
3022        let mut schedule = crate::schedule::Schedule::default();
3023        schedule.add_systems((non_send_param_set, non_send_param_set, non_send_param_set));
3024        schedule.run(&mut world);
3025    }
3026
3027    fn _dyn_system_param_type_inference(mut p: DynSystemParam) {
3028        // Make sure the downcast() methods are able to infer their type parameters from the use of the return type.
3029        // This is just a compilation test, so there is nothing to run.
3030        let _query: Query<()> = p.downcast_mut().unwrap();
3031        let _query: Query<()> = p.downcast_mut_inner().unwrap();
3032        let _query: Query<()> = p.downcast().unwrap();
3033    }
3034
3035    #[test]
3036    #[should_panic]
3037    fn missing_resource_error() {
3038        #[derive(Resource)]
3039        pub struct MissingResource;
3040
3041        let mut schedule = crate::schedule::Schedule::default();
3042        schedule.add_systems(res_system);
3043        let mut world = World::new();
3044        schedule.run(&mut world);
3045
3046        fn res_system(_: Res<MissingResource>) {}
3047    }
3048
3049    #[test]
3050    #[should_panic]
3051    fn missing_message_error() {
3052        use crate::prelude::{Message, MessageReader};
3053
3054        #[derive(Message)]
3055        pub struct MissingEvent;
3056
3057        let mut schedule = crate::schedule::Schedule::default();
3058        schedule.add_systems(message_system);
3059        let mut world = World::new();
3060        schedule.run(&mut world);
3061
3062        fn message_system(_: MessageReader<MissingEvent>) {}
3063    }
3064}