bevy_ecs/system/
system_param.rs

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