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    #[track_caller]
1335    fn init_state(world: &mut World) -> Self::State {
1336        SyncCell::new(T::from_world(world))
1337    }
1338
1339    fn init_access(
1340        _state: &Self::State,
1341        system_meta: &mut SystemMeta,
1342        _component_access_set: &mut FilteredAccessSet,
1343        _world: &mut World,
1344    ) {
1345        system_meta.set_has_deferred();
1346    }
1347
1348    fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World) {
1349        state.get().apply(system_meta, world);
1350    }
1351
1352    fn queue(state: &mut Self::State, system_meta: &SystemMeta, world: DeferredWorld) {
1353        state.get().queue(system_meta, world);
1354    }
1355
1356    #[inline]
1357    unsafe fn get_param<'w, 's>(
1358        state: &'s mut Self::State,
1359        _system_meta: &SystemMeta,
1360        _world: UnsafeWorldCell<'w>,
1361        _change_tick: Tick,
1362    ) -> Self::Item<'w, 's> {
1363        Deferred(state.get())
1364    }
1365}
1366
1367/// A dummy type to tell the executor to run the system exclusively.
1368pub struct ExclusiveMarker(PhantomData<()>);
1369
1370// SAFETY: No world access.
1371unsafe impl SystemParam for ExclusiveMarker {
1372    type State = ();
1373    type Item<'w, 's> = Self;
1374
1375    #[inline]
1376    fn init_state(_world: &mut World) -> Self::State {}
1377
1378    fn init_access(
1379        _state: &Self::State,
1380        system_meta: &mut SystemMeta,
1381        _component_access_set: &mut FilteredAccessSet,
1382        _world: &mut World,
1383    ) {
1384        system_meta.set_exclusive();
1385    }
1386
1387    #[inline]
1388    unsafe fn get_param<'world, 'state>(
1389        _state: &'state mut Self::State,
1390        _system_meta: &SystemMeta,
1391        _world: UnsafeWorldCell<'world>,
1392        _change_tick: Tick,
1393    ) -> Self::Item<'world, 'state> {
1394        Self(PhantomData)
1395    }
1396}
1397
1398// SAFETY: Does not read any world state
1399unsafe impl ReadOnlySystemParam for ExclusiveMarker {}
1400
1401/// A dummy type that is [`!Send`](Send), to force systems to run on the main thread.
1402pub struct NonSendMarker(PhantomData<*mut ()>);
1403
1404// SAFETY: No world access.
1405unsafe impl SystemParam for NonSendMarker {
1406    type State = ();
1407    type Item<'w, 's> = Self;
1408
1409    #[inline]
1410    fn init_state(_world: &mut World) -> Self::State {}
1411
1412    fn init_access(
1413        _state: &Self::State,
1414        system_meta: &mut SystemMeta,
1415        _component_access_set: &mut FilteredAccessSet,
1416        _world: &mut World,
1417    ) {
1418        system_meta.set_non_send();
1419    }
1420
1421    #[inline]
1422    unsafe fn get_param<'world, 'state>(
1423        _state: &'state mut Self::State,
1424        _system_meta: &SystemMeta,
1425        _world: UnsafeWorldCell<'world>,
1426        _change_tick: Tick,
1427    ) -> Self::Item<'world, 'state> {
1428        Self(PhantomData)
1429    }
1430}
1431
1432// SAFETY: Does not read any world state
1433unsafe impl ReadOnlySystemParam for NonSendMarker {}
1434
1435// SAFETY: Only reads a single World non-send resource
1436unsafe impl<'w, T> ReadOnlySystemParam for NonSend<'w, T> {}
1437
1438// SAFETY: NonSendComponentId access is applied to SystemMeta. If this
1439// NonSend conflicts with any prior access, a panic will occur.
1440unsafe impl<'a, T: 'static> SystemParam for NonSend<'a, T> {
1441    type State = ComponentId;
1442    type Item<'w, 's> = NonSend<'w, T>;
1443
1444    fn init_state(world: &mut World) -> Self::State {
1445        world.components_registrator().register_non_send::<T>()
1446    }
1447
1448    fn init_access(
1449        &component_id: &Self::State,
1450        system_meta: &mut SystemMeta,
1451        component_access_set: &mut FilteredAccessSet,
1452        _world: &mut World,
1453    ) {
1454        system_meta.set_non_send();
1455
1456        let combined_access = component_access_set.combined_access();
1457        assert!(
1458            !combined_access.has_resource_write(component_id),
1459            "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",
1460            DebugName::type_name::<T>(),
1461            system_meta.name,
1462        );
1463        component_access_set.add_unfiltered_resource_read(component_id);
1464    }
1465
1466    #[inline]
1467    unsafe fn validate_param(
1468        &mut component_id: &mut Self::State,
1469        _system_meta: &SystemMeta,
1470        world: UnsafeWorldCell,
1471    ) -> Result<(), SystemParamValidationError> {
1472        // SAFETY: Read-only access to resource metadata.
1473        if unsafe { world.storages() }
1474            .non_send_resources
1475            .get(component_id)
1476            .is_some_and(ResourceData::is_present)
1477        {
1478            Ok(())
1479        } else {
1480            Err(SystemParamValidationError::invalid::<Self>(
1481                "Non-send resource does not exist",
1482            ))
1483        }
1484    }
1485
1486    #[inline]
1487    unsafe fn get_param<'w, 's>(
1488        &mut component_id: &'s mut Self::State,
1489        system_meta: &SystemMeta,
1490        world: UnsafeWorldCell<'w>,
1491        change_tick: Tick,
1492    ) -> Self::Item<'w, 's> {
1493        let (ptr, ticks) = world
1494            .get_non_send_with_ticks(component_id)
1495            .unwrap_or_else(|| {
1496                panic!(
1497                    "Non-send resource requested by {} does not exist: {}",
1498                    system_meta.name,
1499                    DebugName::type_name::<T>()
1500                );
1501            });
1502        NonSend {
1503            value: ptr.deref(),
1504            ticks: ComponentTicksRef::from_tick_cells(ticks, system_meta.last_run, change_tick),
1505        }
1506    }
1507}
1508
1509// SAFETY: NonSendMut ComponentId access is applied to SystemMeta. If this
1510// NonSendMut conflicts with any prior access, a panic will occur.
1511unsafe impl<'a, T: 'static> SystemParam for NonSendMut<'a, T> {
1512    type State = ComponentId;
1513    type Item<'w, 's> = NonSendMut<'w, T>;
1514
1515    fn init_state(world: &mut World) -> Self::State {
1516        world.components_registrator().register_non_send::<T>()
1517    }
1518
1519    fn init_access(
1520        &component_id: &Self::State,
1521        system_meta: &mut SystemMeta,
1522        component_access_set: &mut FilteredAccessSet,
1523        _world: &mut World,
1524    ) {
1525        system_meta.set_non_send();
1526
1527        let combined_access = component_access_set.combined_access();
1528        if combined_access.has_resource_write(component_id) {
1529            panic!(
1530                "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",
1531                DebugName::type_name::<T>(), system_meta.name);
1532        } else if combined_access.has_resource_read(component_id) {
1533            panic!(
1534                "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",
1535                DebugName::type_name::<T>(), system_meta.name);
1536        }
1537        component_access_set.add_unfiltered_resource_write(component_id);
1538    }
1539
1540    #[inline]
1541    unsafe fn validate_param(
1542        &mut component_id: &mut Self::State,
1543        _system_meta: &SystemMeta,
1544        world: UnsafeWorldCell,
1545    ) -> Result<(), SystemParamValidationError> {
1546        // SAFETY: Read-only access to resource metadata.
1547        if unsafe { world.storages() }
1548            .non_send_resources
1549            .get(component_id)
1550            .is_some_and(ResourceData::is_present)
1551        {
1552            Ok(())
1553        } else {
1554            Err(SystemParamValidationError::invalid::<Self>(
1555                "Non-send resource does not exist",
1556            ))
1557        }
1558    }
1559
1560    #[inline]
1561    unsafe fn get_param<'w, 's>(
1562        &mut component_id: &'s mut Self::State,
1563        system_meta: &SystemMeta,
1564        world: UnsafeWorldCell<'w>,
1565        change_tick: Tick,
1566    ) -> Self::Item<'w, 's> {
1567        let (ptr, ticks) = world
1568            .get_non_send_with_ticks(component_id)
1569            .unwrap_or_else(|| {
1570                panic!(
1571                    "Non-send resource requested by {} does not exist: {}",
1572                    system_meta.name,
1573                    DebugName::type_name::<T>()
1574                );
1575            });
1576        NonSendMut {
1577            value: ptr.assert_unique().deref_mut(),
1578            ticks: ComponentTicksMut::from_tick_cells(ticks, system_meta.last_run, change_tick),
1579        }
1580    }
1581}
1582
1583// SAFETY: Only reads World archetypes
1584unsafe impl<'a> ReadOnlySystemParam for &'a Archetypes {}
1585
1586// SAFETY: no component value access
1587unsafe impl<'a> SystemParam for &'a Archetypes {
1588    type State = ();
1589    type Item<'w, 's> = &'w Archetypes;
1590
1591    fn init_state(_world: &mut World) -> Self::State {}
1592
1593    fn init_access(
1594        _state: &Self::State,
1595        _system_meta: &mut SystemMeta,
1596        _component_access_set: &mut FilteredAccessSet,
1597        _world: &mut World,
1598    ) {
1599    }
1600
1601    #[inline]
1602    unsafe fn get_param<'w, 's>(
1603        _state: &'s mut Self::State,
1604        _system_meta: &SystemMeta,
1605        world: UnsafeWorldCell<'w>,
1606        _change_tick: Tick,
1607    ) -> Self::Item<'w, 's> {
1608        world.archetypes()
1609    }
1610}
1611
1612// SAFETY: Only reads World components
1613unsafe impl<'a> ReadOnlySystemParam for &'a Components {}
1614
1615// SAFETY: no component value access
1616unsafe impl<'a> SystemParam for &'a Components {
1617    type State = ();
1618    type Item<'w, 's> = &'w Components;
1619
1620    fn init_state(_world: &mut World) -> Self::State {}
1621
1622    fn init_access(
1623        _state: &Self::State,
1624        _system_meta: &mut SystemMeta,
1625        _component_access_set: &mut FilteredAccessSet,
1626        _world: &mut World,
1627    ) {
1628    }
1629
1630    #[inline]
1631    unsafe fn get_param<'w, 's>(
1632        _state: &'s mut Self::State,
1633        _system_meta: &SystemMeta,
1634        world: UnsafeWorldCell<'w>,
1635        _change_tick: Tick,
1636    ) -> Self::Item<'w, 's> {
1637        world.components()
1638    }
1639}
1640
1641// SAFETY: Only reads World entities
1642unsafe impl<'a> ReadOnlySystemParam for &'a Entities {}
1643
1644// SAFETY: no component value access
1645unsafe impl<'a> SystemParam for &'a Entities {
1646    type State = ();
1647    type Item<'w, 's> = &'w Entities;
1648
1649    fn init_state(_world: &mut World) -> Self::State {}
1650
1651    fn init_access(
1652        _state: &Self::State,
1653        _system_meta: &mut SystemMeta,
1654        _component_access_set: &mut FilteredAccessSet,
1655        _world: &mut World,
1656    ) {
1657    }
1658
1659    #[inline]
1660    unsafe fn get_param<'w, 's>(
1661        _state: &'s mut Self::State,
1662        _system_meta: &SystemMeta,
1663        world: UnsafeWorldCell<'w>,
1664        _change_tick: Tick,
1665    ) -> Self::Item<'w, 's> {
1666        world.entities()
1667    }
1668}
1669
1670// SAFETY: Only reads World entities
1671unsafe impl<'a> ReadOnlySystemParam for &'a EntityAllocator {}
1672
1673// SAFETY: no component value access
1674unsafe impl<'a> SystemParam for &'a EntityAllocator {
1675    type State = ();
1676    type Item<'w, 's> = &'w EntityAllocator;
1677
1678    fn init_state(_world: &mut World) -> Self::State {}
1679
1680    fn init_access(
1681        _state: &Self::State,
1682        _system_meta: &mut SystemMeta,
1683        _component_access_set: &mut FilteredAccessSet,
1684        _world: &mut World,
1685    ) {
1686    }
1687
1688    #[inline]
1689    unsafe fn get_param<'w, 's>(
1690        _state: &'s mut Self::State,
1691        _system_meta: &SystemMeta,
1692        world: UnsafeWorldCell<'w>,
1693        _change_tick: Tick,
1694    ) -> Self::Item<'w, 's> {
1695        world.entities_allocator()
1696    }
1697}
1698
1699// SAFETY: Only reads World bundles
1700unsafe impl<'a> ReadOnlySystemParam for &'a Bundles {}
1701
1702// SAFETY: no component value access
1703unsafe impl<'a> SystemParam for &'a Bundles {
1704    type State = ();
1705    type Item<'w, 's> = &'w Bundles;
1706
1707    fn init_state(_world: &mut World) -> Self::State {}
1708
1709    fn init_access(
1710        _state: &Self::State,
1711        _system_meta: &mut SystemMeta,
1712        _component_access_set: &mut FilteredAccessSet,
1713        _world: &mut World,
1714    ) {
1715    }
1716
1717    #[inline]
1718    unsafe fn get_param<'w, 's>(
1719        _state: &'s mut Self::State,
1720        _system_meta: &SystemMeta,
1721        world: UnsafeWorldCell<'w>,
1722        _change_tick: Tick,
1723    ) -> Self::Item<'w, 's> {
1724        world.bundles()
1725    }
1726}
1727
1728/// A [`SystemParam`] that reads the previous and current change ticks of the system.
1729///
1730/// A system's change ticks are updated each time it runs:
1731/// - `last_run` copies the previous value of `change_tick`
1732/// - `this_run` copies the current value of [`World::read_change_tick`]
1733///
1734/// Component change ticks that are more recent than `last_run` will be detected by the system.
1735/// Those can be read by calling [`last_changed`](crate::change_detection::DetectChanges::last_changed)
1736/// on a [`Mut<T>`](crate::change_detection::Mut) or [`ResMut<T>`](ResMut).
1737#[derive(Debug, Clone, Copy)]
1738pub struct SystemChangeTick {
1739    last_run: Tick,
1740    this_run: Tick,
1741}
1742
1743impl SystemChangeTick {
1744    /// Returns the current [`World`] change tick seen by the system.
1745    #[inline]
1746    pub fn this_run(&self) -> Tick {
1747        self.this_run
1748    }
1749
1750    /// Returns the [`World`] change tick seen by the system the previous time it ran.
1751    #[inline]
1752    pub fn last_run(&self) -> Tick {
1753        self.last_run
1754    }
1755}
1756
1757// SAFETY: Only reads internal system state
1758unsafe impl ReadOnlySystemParam for SystemChangeTick {}
1759
1760// SAFETY: `SystemChangeTick` doesn't require any world access
1761unsafe impl SystemParam for SystemChangeTick {
1762    type State = ();
1763    type Item<'w, 's> = SystemChangeTick;
1764
1765    fn init_state(_world: &mut World) -> Self::State {}
1766
1767    fn init_access(
1768        _state: &Self::State,
1769        _system_meta: &mut SystemMeta,
1770        _component_access_set: &mut FilteredAccessSet,
1771        _world: &mut World,
1772    ) {
1773    }
1774
1775    #[inline]
1776    unsafe fn get_param<'w, 's>(
1777        _state: &'s mut Self::State,
1778        system_meta: &SystemMeta,
1779        _world: UnsafeWorldCell<'w>,
1780        change_tick: Tick,
1781    ) -> Self::Item<'w, 's> {
1782        SystemChangeTick {
1783            last_run: system_meta.last_run,
1784            this_run: change_tick,
1785        }
1786    }
1787}
1788
1789// SAFETY: Delegates to `T`, which ensures the safety requirements are met
1790unsafe impl<T: SystemParam> SystemParam for Option<T> {
1791    type State = T::State;
1792
1793    type Item<'world, 'state> = Option<T::Item<'world, 'state>>;
1794
1795    fn init_state(world: &mut World) -> Self::State {
1796        T::init_state(world)
1797    }
1798
1799    fn init_access(
1800        state: &Self::State,
1801        system_meta: &mut SystemMeta,
1802        component_access_set: &mut FilteredAccessSet,
1803        world: &mut World,
1804    ) {
1805        T::init_access(state, system_meta, component_access_set, world);
1806    }
1807
1808    #[inline]
1809    unsafe fn get_param<'world, 'state>(
1810        state: &'state mut Self::State,
1811        system_meta: &SystemMeta,
1812        world: UnsafeWorldCell<'world>,
1813        change_tick: Tick,
1814    ) -> Self::Item<'world, 'state> {
1815        // SAFETY: Upheld by caller
1816        unsafe {
1817            T::validate_param(state, system_meta, world)
1818                .ok()
1819                .map(|()| T::get_param(state, system_meta, world, change_tick))
1820        }
1821    }
1822
1823    fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World) {
1824        T::apply(state, system_meta, world);
1825    }
1826
1827    fn queue(state: &mut Self::State, system_meta: &SystemMeta, world: DeferredWorld) {
1828        T::queue(state, system_meta, world);
1829    }
1830}
1831
1832// SAFETY: Delegates to `T`, which ensures the safety requirements are met
1833unsafe impl<T: ReadOnlySystemParam> ReadOnlySystemParam for Option<T> {}
1834
1835// SAFETY: Delegates to `T`, which ensures the safety requirements are met
1836unsafe impl<T: SystemParam> SystemParam for Result<T, SystemParamValidationError> {
1837    type State = T::State;
1838
1839    type Item<'world, 'state> = Result<T::Item<'world, 'state>, SystemParamValidationError>;
1840
1841    fn init_state(world: &mut World) -> Self::State {
1842        T::init_state(world)
1843    }
1844
1845    fn init_access(
1846        state: &Self::State,
1847        system_meta: &mut SystemMeta,
1848        component_access_set: &mut FilteredAccessSet,
1849        world: &mut World,
1850    ) {
1851        T::init_access(state, system_meta, component_access_set, world);
1852    }
1853
1854    #[inline]
1855    unsafe fn get_param<'world, 'state>(
1856        state: &'state mut Self::State,
1857        system_meta: &SystemMeta,
1858        world: UnsafeWorldCell<'world>,
1859        change_tick: Tick,
1860    ) -> Self::Item<'world, 'state> {
1861        // SAFETY: Upheld by caller
1862        unsafe {
1863            T::validate_param(state, system_meta, world)
1864                .map(|()| T::get_param(state, system_meta, world, change_tick))
1865        }
1866    }
1867
1868    fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World) {
1869        T::apply(state, system_meta, world);
1870    }
1871
1872    fn queue(state: &mut Self::State, system_meta: &SystemMeta, world: DeferredWorld) {
1873        T::queue(state, system_meta, world);
1874    }
1875}
1876
1877// SAFETY: Delegates to `T`, which ensures the safety requirements are met
1878unsafe impl<T: ReadOnlySystemParam> ReadOnlySystemParam for Result<T, SystemParamValidationError> {}
1879
1880/// A [`SystemParam`] that wraps another parameter and causes its system to skip instead of failing when the parameter is invalid.
1881///
1882/// # Example
1883///
1884/// ```
1885/// # use bevy_ecs::prelude::*;
1886/// # #[derive(Resource)]
1887/// # struct SomeResource;
1888/// // This system will fail if `SomeResource` is not present.
1889/// fn fails_on_missing_resource(res: Res<SomeResource>) {}
1890///
1891/// // This system will skip without error if `SomeResource` is not present.
1892/// fn skips_on_missing_resource(res: If<Res<SomeResource>>) {
1893///     // The inner parameter is available using `Deref`
1894///     let some_resource: &SomeResource = &res;
1895/// }
1896/// # bevy_ecs::system::assert_is_system(skips_on_missing_resource);
1897/// ```
1898#[derive(Debug)]
1899pub struct If<T>(pub T);
1900
1901impl<T> If<T> {
1902    /// Returns the inner `T`.
1903    ///
1904    /// The inner value is `pub`, so you can also obtain it by destructuring the parameter:
1905    ///
1906    /// ```
1907    /// # use bevy_ecs::prelude::*;
1908    /// # #[derive(Resource)]
1909    /// # struct SomeResource;
1910    /// fn skips_on_missing_resource(If(res): If<Res<SomeResource>>) {
1911    ///     let some_resource: Res<SomeResource> = res;
1912    /// }
1913    /// # bevy_ecs::system::assert_is_system(skips_on_missing_resource);
1914    /// ```
1915    pub fn into_inner(self) -> T {
1916        self.0
1917    }
1918}
1919
1920impl<T> Deref for If<T> {
1921    type Target = T;
1922    fn deref(&self) -> &Self::Target {
1923        &self.0
1924    }
1925}
1926
1927impl<T> DerefMut for If<T> {
1928    fn deref_mut(&mut self) -> &mut Self::Target {
1929        &mut self.0
1930    }
1931}
1932
1933// SAFETY: Delegates to `T`, which ensures the safety requirements are met
1934unsafe impl<T: SystemParam> SystemParam for If<T> {
1935    type State = T::State;
1936
1937    type Item<'world, 'state> = If<T::Item<'world, 'state>>;
1938
1939    fn init_state(world: &mut World) -> Self::State {
1940        T::init_state(world)
1941    }
1942
1943    fn init_access(
1944        state: &Self::State,
1945        system_meta: &mut SystemMeta,
1946        component_access_set: &mut FilteredAccessSet,
1947        world: &mut World,
1948    ) {
1949        T::init_access(state, system_meta, component_access_set, world);
1950    }
1951
1952    #[inline]
1953    unsafe fn validate_param(
1954        state: &mut Self::State,
1955        system_meta: &SystemMeta,
1956        world: UnsafeWorldCell,
1957    ) -> Result<(), SystemParamValidationError> {
1958        // SAFETY: Upheld by caller
1959        unsafe { T::validate_param(state, system_meta, world) }.map_err(|mut e| {
1960            e.skipped = true;
1961            e
1962        })
1963    }
1964
1965    #[inline]
1966    unsafe fn get_param<'world, 'state>(
1967        state: &'state mut Self::State,
1968        system_meta: &SystemMeta,
1969        world: UnsafeWorldCell<'world>,
1970        change_tick: Tick,
1971    ) -> Self::Item<'world, 'state> {
1972        // SAFETY: Upheld by caller.
1973        If(unsafe { T::get_param(state, system_meta, world, change_tick) })
1974    }
1975
1976    fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World) {
1977        T::apply(state, system_meta, world);
1978    }
1979
1980    fn queue(state: &mut Self::State, system_meta: &SystemMeta, world: DeferredWorld) {
1981        T::queue(state, system_meta, world);
1982    }
1983}
1984
1985// SAFETY: Delegates to `T`, which ensures the safety requirements are met
1986unsafe impl<T: ReadOnlySystemParam> ReadOnlySystemParam for If<T> {}
1987
1988// SAFETY: Registers access for each element of `state`.
1989// If any one conflicts, it will panic.
1990unsafe impl<T: SystemParam> SystemParam for Vec<T> {
1991    type State = Vec<T::State>;
1992
1993    type Item<'world, 'state> = Vec<T::Item<'world, 'state>>;
1994
1995    fn init_state(_world: &mut World) -> Self::State {
1996        Vec::new()
1997    }
1998
1999    fn init_access(
2000        state: &Self::State,
2001        system_meta: &mut SystemMeta,
2002        component_access_set: &mut FilteredAccessSet,
2003        world: &mut World,
2004    ) {
2005        for state in state {
2006            T::init_access(state, system_meta, component_access_set, world);
2007        }
2008    }
2009
2010    #[inline]
2011    unsafe fn validate_param(
2012        state: &mut Self::State,
2013        system_meta: &SystemMeta,
2014        world: UnsafeWorldCell,
2015    ) -> Result<(), SystemParamValidationError> {
2016        for state in state {
2017            // SAFETY: Upheld by caller
2018            unsafe { T::validate_param(state, system_meta, world)? };
2019        }
2020        Ok(())
2021    }
2022
2023    #[inline]
2024    unsafe fn get_param<'world, 'state>(
2025        state: &'state mut Self::State,
2026        system_meta: &SystemMeta,
2027        world: UnsafeWorldCell<'world>,
2028        change_tick: Tick,
2029    ) -> Self::Item<'world, 'state> {
2030        state
2031            .iter_mut()
2032            // SAFETY:
2033            // - 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.
2034            // - The caller ensures this was the world used to initialize our state, and we used that world to initialize parameter states
2035            .map(|state| unsafe { T::get_param(state, system_meta, world, change_tick) })
2036            .collect()
2037    }
2038
2039    fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World) {
2040        for state in state {
2041            T::apply(state, system_meta, world);
2042        }
2043    }
2044
2045    fn queue(state: &mut Self::State, system_meta: &SystemMeta, mut world: DeferredWorld) {
2046        for state in state {
2047            T::queue(state, system_meta, world.reborrow());
2048        }
2049    }
2050}
2051
2052// SAFETY: Registers access for each element of `state`.
2053// If any one conflicts with a previous parameter,
2054// the call passing a copy of the current access will panic.
2055unsafe impl<T: SystemParam> SystemParam for ParamSet<'_, '_, Vec<T>> {
2056    type State = Vec<T::State>;
2057
2058    type Item<'world, 'state> = ParamSet<'world, 'state, Vec<T>>;
2059
2060    fn init_state(_world: &mut World) -> Self::State {
2061        Vec::new()
2062    }
2063
2064    fn init_access(
2065        state: &Self::State,
2066        system_meta: &mut SystemMeta,
2067        component_access_set: &mut FilteredAccessSet,
2068        world: &mut World,
2069    ) {
2070        for state in state {
2071            // Call `init_access` on a clone of the original access set to check for conflicts
2072            let component_access_set_clone = &mut component_access_set.clone();
2073            T::init_access(state, system_meta, component_access_set_clone, world);
2074        }
2075        for state in state {
2076            // Pretend to add the param to the system alone to gather the new access,
2077            // then merge its access into the system.
2078            let mut access_set = FilteredAccessSet::new();
2079            T::init_access(state, system_meta, &mut access_set, world);
2080            component_access_set.extend(access_set);
2081        }
2082    }
2083
2084    #[inline]
2085    unsafe fn get_param<'world, 'state>(
2086        state: &'state mut Self::State,
2087        system_meta: &SystemMeta,
2088        world: UnsafeWorldCell<'world>,
2089        change_tick: Tick,
2090    ) -> Self::Item<'world, 'state> {
2091        ParamSet {
2092            param_states: state,
2093            system_meta: system_meta.clone(),
2094            world,
2095            change_tick,
2096        }
2097    }
2098
2099    fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World) {
2100        for state in state {
2101            T::apply(state, system_meta, world);
2102        }
2103    }
2104
2105    fn queue(state: &mut Self::State, system_meta: &SystemMeta, mut world: DeferredWorld) {
2106        for state in state {
2107            T::queue(state, system_meta, world.reborrow());
2108        }
2109    }
2110}
2111
2112impl<T: SystemParam> ParamSet<'_, '_, Vec<T>> {
2113    /// Accesses the parameter at the given index.
2114    /// No other parameters may be accessed while this one is active.
2115    pub fn get_mut(&mut self, index: usize) -> T::Item<'_, '_> {
2116        // SAFETY:
2117        // - We initialized the access for each parameter, so the caller ensures we have access to any world data needed by any param.
2118        //   We have mutable access to the ParamSet, so no other params in the set are active.
2119        // - 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
2120        unsafe {
2121            T::get_param(
2122                &mut self.param_states[index],
2123                &self.system_meta,
2124                self.world,
2125                self.change_tick,
2126            )
2127        }
2128    }
2129
2130    /// Calls a closure for each parameter in the set.
2131    pub fn for_each(&mut self, mut f: impl FnMut(T::Item<'_, '_>)) {
2132        self.param_states.iter_mut().for_each(|state| {
2133            f(
2134                // SAFETY:
2135                // - We initialized the access for each parameter, so the caller ensures we have access to any world data needed by any param.
2136                //   We have mutable access to the ParamSet, so no other params in the set are active.
2137                // - 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
2138                unsafe { T::get_param(state, &self.system_meta, self.world, self.change_tick) },
2139            );
2140        });
2141    }
2142}
2143
2144macro_rules! impl_system_param_tuple {
2145    ($(#[$meta:meta])* $($param: ident),*) => {
2146        $(#[$meta])*
2147        // SAFETY: tuple consists only of ReadOnlySystemParams
2148        unsafe impl<$($param: ReadOnlySystemParam),*> ReadOnlySystemParam for ($($param,)*) {}
2149
2150        #[expect(
2151            clippy::allow_attributes,
2152            reason = "This is in a macro, and as such, the below lints may not always apply."
2153        )]
2154        #[allow(
2155            non_snake_case,
2156            reason = "Certain variable names are provided by the caller, not by us."
2157        )]
2158        #[allow(
2159            unused_variables,
2160            reason = "Zero-length tuples won't use some of the parameters."
2161        )]
2162        #[allow(clippy::unused_unit, reason = "Zero length tuple is unit.")]
2163        $(#[$meta])*
2164        // SAFETY: implementers of each `SystemParam` in the tuple have validated their impls
2165        unsafe impl<$($param: SystemParam),*> SystemParam for ($($param,)*) {
2166            type State = ($($param::State,)*);
2167            type Item<'w, 's> = ($($param::Item::<'w, 's>,)*);
2168
2169            #[inline]
2170            #[track_caller]
2171            fn init_state(world: &mut World) -> Self::State {
2172                ($($param::init_state(world),)*)
2173            }
2174
2175            fn init_access(state: &Self::State, _system_meta: &mut SystemMeta, _component_access_set: &mut FilteredAccessSet, _world: &mut World) {
2176                let ($($param,)*) = state;
2177                $($param::init_access($param, _system_meta, _component_access_set, _world);)*
2178            }
2179
2180            #[inline]
2181            fn apply(($($param,)*): &mut Self::State, system_meta: &SystemMeta, world: &mut World) {
2182                $($param::apply($param, system_meta, world);)*
2183            }
2184
2185            #[inline]
2186            #[allow(
2187                unused_mut,
2188                reason = "The `world` parameter is unused for zero-length tuples; however, it must be mutable for other lengths of tuples."
2189            )]
2190            fn queue(($($param,)*): &mut Self::State, system_meta: &SystemMeta, mut world: DeferredWorld) {
2191                $($param::queue($param, system_meta, world.reborrow());)*
2192            }
2193
2194            #[inline]
2195            unsafe fn validate_param(
2196                state: &mut Self::State,
2197                system_meta: &SystemMeta,
2198                world: UnsafeWorldCell,
2199            ) -> Result<(), SystemParamValidationError> {
2200                let ($($param,)*) = state;
2201
2202                #[allow(
2203                    unused_unsafe,
2204                    reason = "Zero-length tuples won't have any params to validate."
2205                )]
2206                // SAFETY: Upheld by caller
2207                unsafe {
2208                    $(
2209                        $param::validate_param($param, system_meta, world)?;
2210                    )*
2211                }
2212                Ok(())
2213            }
2214
2215            #[inline]
2216            #[track_caller]
2217            unsafe fn get_param<'w, 's>(
2218                state: &'s mut Self::State,
2219                system_meta: &SystemMeta,
2220                world: UnsafeWorldCell<'w>,
2221                change_tick: Tick,
2222            ) -> Self::Item<'w, 's> {
2223                let ($($param,)*) = state;
2224
2225                #[allow(
2226                    unused_unsafe,
2227                    reason = "Zero-length tuples won't have any params to validate."
2228                )]
2229                // SAFETY: Upheld by caller
2230                unsafe {
2231                    #[allow(
2232                        clippy::unused_unit,
2233                        reason = "Zero-length tuples won't have any params to get."
2234                    )]
2235                    ($($param::get_param($param, system_meta, world, change_tick),)*)
2236                }
2237            }
2238        }
2239    };
2240}
2241
2242all_tuples!(
2243    #[doc(fake_variadic)]
2244    impl_system_param_tuple,
2245    0,
2246    16,
2247    P
2248);
2249
2250/// Contains type aliases for built-in [`SystemParam`]s with `'static` lifetimes.
2251/// This makes it more convenient to refer to these types in contexts where
2252/// explicit lifetime annotations are required.
2253///
2254/// Note that this is entirely safe and tracks lifetimes correctly.
2255/// This purely exists for convenience.
2256///
2257/// You can't instantiate a static `SystemParam`, you'll always end up with
2258/// `Res<'w, T>`, `ResMut<'w, T>` or `&'w T` bound to the lifetime of the provided
2259/// `&'w World`.
2260///
2261/// [`SystemParam`]: super::SystemParam
2262pub mod lifetimeless {
2263    /// A [`Query`](super::Query) with `'static` lifetimes.
2264    pub type SQuery<D, F = ()> = super::Query<'static, 'static, D, F>;
2265    /// A shorthand for writing `&'static T`.
2266    pub type Read<T> = &'static T;
2267    /// A shorthand for writing `&'static mut T`.
2268    pub type Write<T> = &'static mut T;
2269    /// A [`Res`](super::Res) with `'static` lifetimes.
2270    pub type SRes<T> = super::Res<'static, T>;
2271    /// A [`ResMut`](super::ResMut) with `'static` lifetimes.
2272    pub type SResMut<T> = super::ResMut<'static, T>;
2273    /// [`Commands`](crate::system::Commands) with `'static` lifetimes.
2274    pub type SCommands = crate::system::Commands<'static, 'static>;
2275}
2276
2277/// A helper for using system parameters in generic contexts
2278///
2279/// This type is a [`SystemParam`] adapter which always has
2280/// `Self::Item == Self` (ignoring lifetimes for brevity),
2281/// no matter the argument [`SystemParam`] (`P`) (other than
2282/// that `P` must be `'static`)
2283///
2284/// This makes it useful for having arbitrary [`SystemParam`] type arguments
2285/// to function systems, or for generic types using the [`derive@SystemParam`]
2286/// derive:
2287///
2288/// ```
2289/// # use bevy_ecs::prelude::*;
2290/// use bevy_ecs::system::{SystemParam, StaticSystemParam};
2291/// #[derive(SystemParam)]
2292/// struct GenericParam<'w,'s, T: SystemParam + 'static> {
2293///     field: StaticSystemParam<'w, 's, T>,
2294/// }
2295/// fn do_thing_generically<T: SystemParam + 'static>(t: StaticSystemParam<T>) {}
2296///
2297/// fn check_always_is_system<T: SystemParam + 'static>(){
2298///     bevy_ecs::system::assert_is_system(do_thing_generically::<T>);
2299/// }
2300/// ```
2301/// Note that in a real case you'd generally want
2302/// additional bounds on `P`, for your use of the parameter
2303/// to have a reason to be generic.
2304///
2305/// For example, using this would allow a type to be generic over
2306/// whether a resource is accessed mutably or not, with
2307/// impls being bounded on [`P: Deref<Target=MyType>`](Deref), and
2308/// [`P: DerefMut<Target=MyType>`](DerefMut) depending on whether the
2309/// method requires mutable access or not.
2310///
2311/// The method which doesn't use this type will not compile:
2312/// ```compile_fail
2313/// # use bevy_ecs::prelude::*;
2314/// # use bevy_ecs::system::{SystemParam, StaticSystemParam};
2315///
2316/// fn do_thing_generically<T: SystemParam + 'static>(t: T) {}
2317///
2318/// #[derive(SystemParam)]
2319/// struct GenericParam<'w, 's, T: SystemParam> {
2320///     field: T,
2321///     // Use the lifetimes in this type, or they will be unbound.
2322///     phantom: std::marker::PhantomData<&'w &'s ()>
2323/// }
2324/// # fn check_always_is_system<T: SystemParam + 'static>(){
2325/// #    bevy_ecs::system::assert_is_system(do_thing_generically::<T>);
2326/// # }
2327/// ```
2328pub struct StaticSystemParam<'w, 's, P: SystemParam>(SystemParamItem<'w, 's, P>);
2329
2330impl<'w, 's, P: SystemParam> Deref for StaticSystemParam<'w, 's, P> {
2331    type Target = SystemParamItem<'w, 's, P>;
2332
2333    fn deref(&self) -> &Self::Target {
2334        &self.0
2335    }
2336}
2337
2338impl<'w, 's, P: SystemParam> DerefMut for StaticSystemParam<'w, 's, P> {
2339    fn deref_mut(&mut self) -> &mut Self::Target {
2340        &mut self.0
2341    }
2342}
2343
2344impl<'w, 's, P: SystemParam> StaticSystemParam<'w, 's, P> {
2345    /// Get the value of the parameter
2346    pub fn into_inner(self) -> SystemParamItem<'w, 's, P> {
2347        self.0
2348    }
2349}
2350
2351// SAFETY: This doesn't add any more reads, and the delegated fetch confirms it
2352unsafe impl<'w, 's, P: ReadOnlySystemParam + 'static> ReadOnlySystemParam
2353    for StaticSystemParam<'w, 's, P>
2354{
2355}
2356
2357// SAFETY: all methods are just delegated to `P`'s `SystemParam` implementation
2358unsafe impl<P: SystemParam + 'static> SystemParam for StaticSystemParam<'_, '_, P> {
2359    type State = P::State;
2360    type Item<'world, 'state> = StaticSystemParam<'world, 'state, P>;
2361
2362    fn init_state(world: &mut World) -> Self::State {
2363        P::init_state(world)
2364    }
2365
2366    fn init_access(
2367        state: &Self::State,
2368        system_meta: &mut SystemMeta,
2369        component_access_set: &mut FilteredAccessSet,
2370        world: &mut World,
2371    ) {
2372        P::init_access(state, system_meta, component_access_set, world);
2373    }
2374
2375    fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World) {
2376        P::apply(state, system_meta, world);
2377    }
2378
2379    fn queue(state: &mut Self::State, system_meta: &SystemMeta, world: DeferredWorld) {
2380        P::queue(state, system_meta, world);
2381    }
2382
2383    #[inline]
2384    unsafe fn validate_param(
2385        state: &mut Self::State,
2386        system_meta: &SystemMeta,
2387        world: UnsafeWorldCell,
2388    ) -> Result<(), SystemParamValidationError> {
2389        // SAFETY: Upheld by caller
2390        unsafe { P::validate_param(state, system_meta, world) }
2391    }
2392
2393    #[inline]
2394    unsafe fn get_param<'world, 'state>(
2395        state: &'state mut Self::State,
2396        system_meta: &SystemMeta,
2397        world: UnsafeWorldCell<'world>,
2398        change_tick: Tick,
2399    ) -> Self::Item<'world, 'state> {
2400        // SAFETY: Defer to the safety of P::SystemParam
2401        StaticSystemParam(unsafe { P::get_param(state, system_meta, world, change_tick) })
2402    }
2403}
2404
2405// SAFETY: No world access.
2406unsafe impl<T: ?Sized> SystemParam for PhantomData<T> {
2407    type State = ();
2408    type Item<'world, 'state> = Self;
2409
2410    fn init_state(_world: &mut World) -> Self::State {}
2411
2412    fn init_access(
2413        _state: &Self::State,
2414        _system_meta: &mut SystemMeta,
2415        _component_access_set: &mut FilteredAccessSet,
2416        _world: &mut World,
2417    ) {
2418    }
2419
2420    #[inline]
2421    unsafe fn get_param<'world, 'state>(
2422        _state: &'state mut Self::State,
2423        _system_meta: &SystemMeta,
2424        _world: UnsafeWorldCell<'world>,
2425        _change_tick: Tick,
2426    ) -> Self::Item<'world, 'state> {
2427        PhantomData
2428    }
2429}
2430
2431// SAFETY: No world access.
2432unsafe impl<T: ?Sized> ReadOnlySystemParam for PhantomData<T> {}
2433
2434/// A [`SystemParam`] with a type that can be configured at runtime.
2435///
2436/// To be useful, this must be configured using a [`DynParamBuilder`](crate::system::DynParamBuilder) to build the system using a [`SystemParamBuilder`](crate::prelude::SystemParamBuilder).
2437///
2438/// # Examples
2439///
2440/// ```
2441/// # use bevy_ecs::{prelude::*, system::*};
2442/// #
2443/// # #[derive(Default, Resource)]
2444/// # struct A;
2445/// #
2446/// # #[derive(Default, Resource)]
2447/// # struct B;
2448/// #
2449/// # let mut world = World::new();
2450/// # world.init_resource::<A>();
2451/// # world.init_resource::<B>();
2452/// #
2453/// // If the inner parameter doesn't require any special building, use `ParamBuilder`.
2454/// // Either specify the type parameter on `DynParamBuilder::new()` ...
2455/// let system = (DynParamBuilder::new::<Res<A>>(ParamBuilder),)
2456///     .build_state(&mut world)
2457///     .build_system(expects_res_a);
2458/// # world.run_system_once(system);
2459///
2460/// // ... or use a factory method on `ParamBuilder` that returns a specific type.
2461/// let system = (DynParamBuilder::new(ParamBuilder::resource::<A>()),)
2462///     .build_state(&mut world)
2463///     .build_system(expects_res_a);
2464/// # world.run_system_once(system);
2465///
2466/// fn expects_res_a(mut param: DynSystemParam) {
2467///     // Use the `downcast` methods to retrieve the inner parameter.
2468///     // They will return `None` if the type does not match.
2469///     assert!(param.is::<Res<A>>());
2470///     assert!(!param.is::<Res<B>>());
2471///     assert!(param.downcast_mut::<Res<B>>().is_none());
2472///     let res = param.downcast_mut::<Res<A>>().unwrap();
2473///     // The type parameter can be left out if it can be determined from use.
2474///     let res: Res<A> = param.downcast().unwrap();
2475/// }
2476///
2477/// let system = (
2478///     // If the inner parameter also requires building,
2479///     // pass the appropriate `SystemParamBuilder`.
2480///     DynParamBuilder::new(LocalBuilder(10usize)),
2481///     // `DynSystemParam` is just an ordinary `SystemParam`,
2482///     // and can be combined with other parameters as usual!
2483///     ParamBuilder::query(),
2484/// )
2485///     .build_state(&mut world)
2486///     .build_system(|param: DynSystemParam, query: Query<()>| {
2487///         let local: Local<usize> = param.downcast::<Local<usize>>().unwrap();
2488///         assert_eq!(*local, 10);
2489///     });
2490/// # world.run_system_once(system);
2491/// ```
2492pub struct DynSystemParam<'w, 's> {
2493    /// A `ParamState<T>` wrapping the state for the underlying system param.
2494    state: &'s mut dyn Any,
2495    world: UnsafeWorldCell<'w>,
2496    system_meta: SystemMeta,
2497    change_tick: Tick,
2498}
2499
2500impl<'w, 's> DynSystemParam<'w, 's> {
2501    /// # Safety
2502    /// - `state` must be a `ParamState<T>` for some inner `T: SystemParam`.
2503    /// - The passed [`UnsafeWorldCell`] must have access to any world data registered
2504    ///   in [`init_state`](SystemParam::init_state) for the inner system param.
2505    /// - `world` must be the same `World` that was used to initialize
2506    ///   [`state`](SystemParam::init_state) for the inner system param.
2507    unsafe fn new(
2508        state: &'s mut dyn Any,
2509        world: UnsafeWorldCell<'w>,
2510        system_meta: SystemMeta,
2511        change_tick: Tick,
2512    ) -> Self {
2513        Self {
2514            state,
2515            world,
2516            system_meta,
2517            change_tick,
2518        }
2519    }
2520
2521    /// Returns `true` if the inner system param is the same as `T`.
2522    pub fn is<T: SystemParam>(&self) -> bool
2523    // See downcast() function for an explanation of the where clause
2524    where
2525        T::Item<'static, 'static>: SystemParam<Item<'w, 's> = T> + 'static,
2526    {
2527        self.state.is::<ParamState<T::Item<'static, 'static>>>()
2528    }
2529
2530    /// Returns the inner system param if it is the correct type.
2531    /// This consumes the dyn param, so the returned param can have its original world and state lifetimes.
2532    pub fn downcast<T: SystemParam>(self) -> Option<T>
2533    // See downcast() function for an explanation of the where clause
2534    where
2535        T::Item<'static, 'static>: SystemParam<Item<'w, 's> = T> + 'static,
2536    {
2537        // SAFETY:
2538        // - `DynSystemParam::new()` ensures `state` is a `ParamState<T>`, that the world matches,
2539        //   and that it has access required by the inner system param.
2540        // - This consumes the `DynSystemParam`, so it is the only use of `world` with this access and it is available for `'w`.
2541        unsafe { downcast::<T>(self.state, &self.system_meta, self.world, self.change_tick) }
2542    }
2543
2544    /// Returns the inner system parameter if it is the correct type.
2545    /// This borrows the dyn param, so the returned param is only valid for the duration of that borrow.
2546    pub fn downcast_mut<'a, T: SystemParam>(&'a mut self) -> Option<T>
2547    // See downcast() function for an explanation of the where clause
2548    where
2549        T::Item<'static, 'static>: SystemParam<Item<'a, 'a> = T> + 'static,
2550    {
2551        // SAFETY:
2552        // - `DynSystemParam::new()` ensures `state` is a `ParamState<T>`, that the world matches,
2553        //   and that it has access required by the inner system param.
2554        // - This exclusively borrows the `DynSystemParam` for `'_`, so it is the only use of `world` with this access for `'_`.
2555        unsafe { downcast::<T>(self.state, &self.system_meta, self.world, self.change_tick) }
2556    }
2557
2558    /// Returns the inner system parameter if it is the correct type.
2559    /// This borrows the dyn param, so the returned param is only valid for the duration of that borrow,
2560    /// but since it only performs read access it can keep the original world lifetime.
2561    /// This can be useful with methods like [`Query::iter_inner()`] or [`Res::into_inner()`]
2562    /// to obtain references with the original world lifetime.
2563    pub fn downcast_mut_inner<'a, T: ReadOnlySystemParam>(&'a mut self) -> Option<T>
2564    // See downcast() function for an explanation of the where clause
2565    where
2566        T::Item<'static, 'static>: SystemParam<Item<'w, 'a> = T> + 'static,
2567    {
2568        // SAFETY:
2569        // - `DynSystemParam::new()` ensures `state` is a `ParamState<T>`, that the world matches,
2570        //   and that it has access required by the inner system param.
2571        // - The inner system param only performs read access, so it's safe to copy that access for the full `'w` lifetime.
2572        unsafe { downcast::<T>(self.state, &self.system_meta, self.world, self.change_tick) }
2573    }
2574}
2575
2576/// # Safety
2577/// - `state` must be a `ParamState<T>` for some inner `T: SystemParam`.
2578/// - The passed [`UnsafeWorldCell`] must have access to any world data registered
2579///   in [`init_state`](SystemParam::init_state) for the inner system param.
2580/// - `world` must be the same `World` that was used to initialize
2581///   [`state`](SystemParam::init_state) for the inner system param.
2582unsafe fn downcast<'w, 's, T: SystemParam>(
2583    state: &'s mut dyn Any,
2584    system_meta: &SystemMeta,
2585    world: UnsafeWorldCell<'w>,
2586    change_tick: Tick,
2587) -> Option<T>
2588// We need a 'static version of the SystemParam to use with `Any::downcast_mut()`,
2589// and we need a <'w, 's> version to actually return.
2590// The type parameter T must be the one we return in order to get type inference from the return value.
2591// So we use `T::Item<'static, 'static>` as the 'static version, and require that it be 'static.
2592// That means the return value will be T::Item<'static, 'static>::Item<'w, 's>,
2593// so we constrain that to be equal to T.
2594// Every actual `SystemParam` implementation has `T::Item == T` up to lifetimes,
2595// so they should all work with this constraint.
2596where
2597    T::Item<'static, 'static>: SystemParam<Item<'w, 's> = T> + 'static,
2598{
2599    state
2600        .downcast_mut::<ParamState<T::Item<'static, 'static>>>()
2601        .map(|state| {
2602            // SAFETY:
2603            // - The caller ensures the world has access for the underlying system param,
2604            //   and since the downcast succeeded, the underlying system param is T.
2605            // - The caller ensures the `world` matches.
2606            unsafe { T::Item::get_param(&mut state.0, system_meta, world, change_tick) }
2607        })
2608}
2609
2610/// The [`SystemParam::State`] for a [`DynSystemParam`].
2611pub struct DynSystemParamState(Box<dyn DynParamState>);
2612
2613impl DynSystemParamState {
2614    pub(crate) fn new<T: SystemParam + 'static>(state: T::State) -> Self {
2615        Self(Box::new(ParamState::<T>(state)))
2616    }
2617}
2618
2619/// Allows a [`SystemParam::State`] to be used as a trait object for implementing [`DynSystemParam`].
2620trait DynParamState: Sync + Send + Any {
2621    /// Applies any deferred mutations stored in this [`SystemParam`]'s state.
2622    /// This is used to apply [`Commands`] during [`ApplyDeferred`](crate::prelude::ApplyDeferred).
2623    ///
2624    /// [`Commands`]: crate::prelude::Commands
2625    fn apply(&mut self, system_meta: &SystemMeta, world: &mut World);
2626
2627    /// Queues any deferred mutations to be applied at the next [`ApplyDeferred`](crate::prelude::ApplyDeferred).
2628    fn queue(&mut self, system_meta: &SystemMeta, world: DeferredWorld);
2629
2630    /// Registers any [`World`] access used by this [`SystemParam`]
2631    fn init_access(
2632        &self,
2633        system_meta: &mut SystemMeta,
2634        component_access_set: &mut FilteredAccessSet,
2635        world: &mut World,
2636    );
2637
2638    /// Refer to [`SystemParam::validate_param`].
2639    ///
2640    /// # Safety
2641    /// Refer to [`SystemParam::validate_param`].
2642    unsafe fn validate_param(
2643        &mut self,
2644        system_meta: &SystemMeta,
2645        world: UnsafeWorldCell,
2646    ) -> Result<(), SystemParamValidationError>;
2647}
2648
2649/// A wrapper around a [`SystemParam::State`] that can be used as a trait object in a [`DynSystemParam`].
2650struct ParamState<T: SystemParam>(T::State);
2651
2652impl<T: SystemParam + 'static> DynParamState for ParamState<T> {
2653    fn apply(&mut self, system_meta: &SystemMeta, world: &mut World) {
2654        T::apply(&mut self.0, system_meta, world);
2655    }
2656
2657    fn queue(&mut self, system_meta: &SystemMeta, world: DeferredWorld) {
2658        T::queue(&mut self.0, system_meta, world);
2659    }
2660
2661    fn init_access(
2662        &self,
2663        system_meta: &mut SystemMeta,
2664        component_access_set: &mut FilteredAccessSet,
2665        world: &mut World,
2666    ) {
2667        T::init_access(&self.0, system_meta, component_access_set, world);
2668    }
2669
2670    unsafe fn validate_param(
2671        &mut self,
2672        system_meta: &SystemMeta,
2673        world: UnsafeWorldCell,
2674    ) -> Result<(), SystemParamValidationError> {
2675        // SAFETY: Upheld by caller
2676        unsafe { T::validate_param(&mut self.0, system_meta, world) }
2677    }
2678}
2679
2680// SAFETY: Delegates to the wrapped parameter, which ensures the safety requirements are met
2681unsafe impl SystemParam for DynSystemParam<'_, '_> {
2682    type State = DynSystemParamState;
2683
2684    type Item<'world, 'state> = DynSystemParam<'world, 'state>;
2685
2686    fn init_state(_world: &mut World) -> Self::State {
2687        DynSystemParamState::new::<()>(())
2688    }
2689
2690    fn init_access(
2691        state: &Self::State,
2692        system_meta: &mut SystemMeta,
2693        component_access_set: &mut FilteredAccessSet,
2694        world: &mut World,
2695    ) {
2696        state
2697            .0
2698            .init_access(system_meta, component_access_set, world);
2699    }
2700
2701    #[inline]
2702    unsafe fn validate_param(
2703        state: &mut Self::State,
2704        system_meta: &SystemMeta,
2705        world: UnsafeWorldCell,
2706    ) -> Result<(), SystemParamValidationError> {
2707        // SAFETY: Upheld by caller.
2708        unsafe { state.0.validate_param(system_meta, world) }
2709    }
2710
2711    #[inline]
2712    unsafe fn get_param<'world, 'state>(
2713        state: &'state mut Self::State,
2714        system_meta: &SystemMeta,
2715        world: UnsafeWorldCell<'world>,
2716        change_tick: Tick,
2717    ) -> Self::Item<'world, 'state> {
2718        // SAFETY:
2719        // - `state.0` is a boxed `ParamState<T>`.
2720        // - `init_access` calls `DynParamState::init_access`, which calls `init_access` on the inner parameter,
2721        //   so the caller ensures the world has the necessary access.
2722        // - The caller ensures that the provided world is the same and has the required access.
2723        unsafe { DynSystemParam::new(state.0.as_mut(), world, system_meta.clone(), change_tick) }
2724    }
2725
2726    fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World) {
2727        state.0.apply(system_meta, world);
2728    }
2729
2730    fn queue(state: &mut Self::State, system_meta: &SystemMeta, world: DeferredWorld) {
2731        state.0.queue(system_meta, world);
2732    }
2733}
2734
2735// SAFETY: Resource ComponentId access is applied to the access. If this FilteredResources
2736// conflicts with any prior access, a panic will occur.
2737unsafe impl SystemParam for FilteredResources<'_, '_> {
2738    type State = Access;
2739
2740    type Item<'world, 'state> = FilteredResources<'world, 'state>;
2741
2742    fn init_state(_world: &mut World) -> Self::State {
2743        Access::new()
2744    }
2745
2746    fn init_access(
2747        access: &Self::State,
2748        system_meta: &mut SystemMeta,
2749        component_access_set: &mut FilteredAccessSet,
2750        world: &mut World,
2751    ) {
2752        let combined_access = component_access_set.combined_access();
2753        let conflicts = combined_access.get_conflicts(access);
2754        if !conflicts.is_empty() {
2755            let accesses = conflicts.format_conflict_list(world);
2756            let system_name = &system_meta.name;
2757            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");
2758        }
2759
2760        if access.has_read_all_resources() {
2761            component_access_set.add_unfiltered_read_all_resources();
2762        } else {
2763            for component_id in access.resource_reads_and_writes() {
2764                component_access_set.add_unfiltered_resource_read(component_id);
2765            }
2766        }
2767    }
2768
2769    unsafe fn get_param<'world, 'state>(
2770        state: &'state mut Self::State,
2771        system_meta: &SystemMeta,
2772        world: UnsafeWorldCell<'world>,
2773        change_tick: Tick,
2774    ) -> Self::Item<'world, 'state> {
2775        // SAFETY: The caller ensures that `world` has access to anything registered in `init_access`,
2776        // and we registered all resource access in `state``.
2777        unsafe { FilteredResources::new(world, state, system_meta.last_run, change_tick) }
2778    }
2779}
2780
2781// SAFETY: FilteredResources only reads resources.
2782unsafe impl ReadOnlySystemParam for FilteredResources<'_, '_> {}
2783
2784// SAFETY: Resource ComponentId access is applied to the access. If this FilteredResourcesMut
2785// conflicts with any prior access, a panic will occur.
2786unsafe impl SystemParam for FilteredResourcesMut<'_, '_> {
2787    type State = Access;
2788
2789    type Item<'world, 'state> = FilteredResourcesMut<'world, 'state>;
2790
2791    fn init_state(_world: &mut World) -> Self::State {
2792        Access::new()
2793    }
2794
2795    fn init_access(
2796        access: &Self::State,
2797        system_meta: &mut SystemMeta,
2798        component_access_set: &mut FilteredAccessSet,
2799        world: &mut World,
2800    ) {
2801        let combined_access = component_access_set.combined_access();
2802        let conflicts = combined_access.get_conflicts(access);
2803        if !conflicts.is_empty() {
2804            let accesses = conflicts.format_conflict_list(world);
2805            let system_name = &system_meta.name;
2806            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");
2807        }
2808
2809        if access.has_read_all_resources() {
2810            component_access_set.add_unfiltered_read_all_resources();
2811        } else {
2812            for component_id in access.resource_reads() {
2813                component_access_set.add_unfiltered_resource_read(component_id);
2814            }
2815        }
2816
2817        if access.has_write_all_resources() {
2818            component_access_set.add_unfiltered_write_all_resources();
2819        } else {
2820            for component_id in access.resource_writes() {
2821                component_access_set.add_unfiltered_resource_write(component_id);
2822            }
2823        }
2824    }
2825
2826    unsafe fn get_param<'world, 'state>(
2827        state: &'state mut Self::State,
2828        system_meta: &SystemMeta,
2829        world: UnsafeWorldCell<'world>,
2830        change_tick: Tick,
2831    ) -> Self::Item<'world, 'state> {
2832        // SAFETY: The caller ensures that `world` has access to anything registered in `init_access`,
2833        // and we registered all resource access in `state``.
2834        unsafe { FilteredResourcesMut::new(world, state, system_meta.last_run, change_tick) }
2835    }
2836}
2837
2838/// An error that occurs when a system parameter is not valid,
2839/// used by system executors to determine what to do with a system.
2840///
2841/// Returned as an error from [`SystemParam::validate_param`],
2842/// and handled using the unified error handling mechanisms defined in [`bevy_ecs::error`].
2843#[derive(Debug, PartialEq, Eq, Clone, Error)]
2844pub struct SystemParamValidationError {
2845    /// Whether the system should be skipped.
2846    ///
2847    /// If `false`, the error should be handled.
2848    /// By default, this will result in a panic. See [`error`](`crate::error`) for more information.
2849    ///
2850    /// This is the default behavior, and is suitable for system params that should *always* be valid,
2851    /// either because sensible fallback behavior exists (like [`Query`]) or because
2852    /// failures in validation should be considered a bug in the user's logic that must be immediately addressed (like [`Res`]).
2853    ///
2854    /// If `true`, the system should be skipped.
2855    /// This is set by wrapping the system param in [`If`],
2856    /// and indicates that the system is intended to only operate in certain application states.
2857    pub skipped: bool,
2858
2859    /// A message describing the validation error.
2860    pub message: Cow<'static, str>,
2861
2862    /// A string identifying the invalid parameter.
2863    /// This is usually the type name of the parameter.
2864    pub param: DebugName,
2865
2866    /// A string identifying the field within a parameter using `#[derive(SystemParam)]`.
2867    /// This will be an empty string for other parameters.
2868    ///
2869    /// This will be printed after `param` in the `Display` impl, and should include a `::` prefix if non-empty.
2870    pub field: Cow<'static, str>,
2871}
2872
2873impl SystemParamValidationError {
2874    /// Constructs a `SystemParamValidationError` that skips the system.
2875    /// The parameter name is initialized to the type name of `T`, so a `SystemParam` should usually pass `Self`.
2876    pub fn skipped<T>(message: impl Into<Cow<'static, str>>) -> Self {
2877        Self::new::<T>(true, message, Cow::Borrowed(""))
2878    }
2879
2880    /// Constructs a `SystemParamValidationError` for an invalid parameter that should be treated as an error.
2881    /// The parameter name is initialized to the type name of `T`, so a `SystemParam` should usually pass `Self`.
2882    pub fn invalid<T>(message: impl Into<Cow<'static, str>>) -> Self {
2883        Self::new::<T>(false, message, Cow::Borrowed(""))
2884    }
2885
2886    /// Constructs a `SystemParamValidationError` for an invalid parameter.
2887    /// The parameter name is initialized to the type name of `T`, so a `SystemParam` should usually pass `Self`.
2888    pub fn new<T>(
2889        skipped: bool,
2890        message: impl Into<Cow<'static, str>>,
2891        field: impl Into<Cow<'static, str>>,
2892    ) -> Self {
2893        Self {
2894            skipped,
2895            message: message.into(),
2896            param: DebugName::type_name::<T>(),
2897            field: field.into(),
2898        }
2899    }
2900
2901    pub(crate) const EMPTY: Self = Self {
2902        skipped: false,
2903        message: Cow::Borrowed(""),
2904        param: DebugName::borrowed(""),
2905        field: Cow::Borrowed(""),
2906    };
2907}
2908
2909impl Display for SystemParamValidationError {
2910    fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
2911        write!(
2912            fmt,
2913            "Parameter `{}{}` failed validation: {}",
2914            self.param.shortname(),
2915            self.field,
2916            self.message
2917        )?;
2918        if !self.skipped {
2919            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.")?;
2920        }
2921        Ok(())
2922    }
2923}
2924
2925#[cfg(test)]
2926mod tests {
2927    use super::*;
2928    use crate::system::assert_is_system;
2929    use core::cell::RefCell;
2930
2931    #[test]
2932    #[should_panic]
2933    fn non_send_alias() {
2934        #[derive(Resource)]
2935        struct A(usize);
2936        fn my_system(mut res0: NonSendMut<A>, mut res1: NonSendMut<A>) {
2937            res0.0 += 1;
2938            res1.0 += 1;
2939        }
2940        let mut world = World::new();
2941        world.insert_non_send_resource(A(42));
2942        let mut schedule = crate::schedule::Schedule::default();
2943        schedule.add_systems(my_system);
2944        schedule.run(&mut world);
2945    }
2946
2947    // Compile test for https://github.com/bevyengine/bevy/pull/2838.
2948    #[test]
2949    fn system_param_generic_bounds() {
2950        #[derive(SystemParam)]
2951        pub struct SpecialQuery<
2952            'w,
2953            's,
2954            D: QueryData + Send + Sync + 'static,
2955            F: QueryFilter + Send + Sync + 'static = (),
2956        > {
2957            _query: Query<'w, 's, D, F>,
2958        }
2959
2960        fn my_system(_: SpecialQuery<(), ()>) {}
2961        assert_is_system(my_system);
2962    }
2963
2964    // Compile tests for https://github.com/bevyengine/bevy/pull/6694.
2965    #[test]
2966    fn system_param_flexibility() {
2967        #[derive(SystemParam)]
2968        pub struct SpecialRes<'w, T: Resource> {
2969            _res: Res<'w, T>,
2970        }
2971
2972        #[derive(SystemParam)]
2973        pub struct SpecialLocal<'s, T: FromWorld + Send + 'static> {
2974            _local: Local<'s, T>,
2975        }
2976
2977        #[derive(Resource)]
2978        struct R;
2979
2980        fn my_system(_: SpecialRes<R>, _: SpecialLocal<u32>) {}
2981        assert_is_system(my_system);
2982    }
2983
2984    #[derive(Resource)]
2985    pub struct R<const I: usize>;
2986
2987    // Compile test for https://github.com/bevyengine/bevy/pull/7001.
2988    #[test]
2989    fn system_param_const_generics() {
2990        #[expect(
2991            dead_code,
2992            reason = "This struct is used to ensure that const generics are supported as a SystemParam; thus, the inner value never needs to be read."
2993        )]
2994        #[derive(SystemParam)]
2995        pub struct ConstGenericParam<'w, const I: usize>(Res<'w, R<I>>);
2996
2997        fn my_system(_: ConstGenericParam<0>, _: ConstGenericParam<1000>) {}
2998        assert_is_system(my_system);
2999    }
3000
3001    // Compile test for https://github.com/bevyengine/bevy/pull/6867.
3002    #[test]
3003    fn system_param_field_limit() {
3004        #[derive(SystemParam)]
3005        pub struct LongParam<'w> {
3006            // Each field should be a distinct type so there will
3007            // be an error if the derive messes up the field order.
3008            _r0: Res<'w, R<0>>,
3009            _r1: Res<'w, R<1>>,
3010            _r2: Res<'w, R<2>>,
3011            _r3: Res<'w, R<3>>,
3012            _r4: Res<'w, R<4>>,
3013            _r5: Res<'w, R<5>>,
3014            _r6: Res<'w, R<6>>,
3015            _r7: Res<'w, R<7>>,
3016            _r8: Res<'w, R<8>>,
3017            _r9: Res<'w, R<9>>,
3018            _r10: Res<'w, R<10>>,
3019            _r11: Res<'w, R<11>>,
3020            _r12: Res<'w, R<12>>,
3021            _r13: Res<'w, R<13>>,
3022            _r14: Res<'w, R<14>>,
3023            _r15: Res<'w, R<15>>,
3024            _r16: Res<'w, R<16>>,
3025        }
3026
3027        fn long_system(_: LongParam) {}
3028        assert_is_system(long_system);
3029    }
3030
3031    // Compile test for https://github.com/bevyengine/bevy/pull/6919.
3032    // Regression test for https://github.com/bevyengine/bevy/issues/7447.
3033    #[test]
3034    fn system_param_phantom_data() {
3035        #[derive(SystemParam)]
3036        struct PhantomParam<'w, T: Resource, Marker: 'static> {
3037            _foo: Res<'w, T>,
3038            marker: PhantomData<&'w Marker>,
3039        }
3040
3041        fn my_system(_: PhantomParam<R<0>, ()>) {}
3042        assert_is_system(my_system);
3043    }
3044
3045    // Compile tests for https://github.com/bevyengine/bevy/pull/6957.
3046    #[test]
3047    fn system_param_struct_variants() {
3048        #[derive(SystemParam)]
3049        pub struct UnitParam;
3050
3051        #[expect(
3052            dead_code,
3053            reason = "This struct is used to ensure that tuple structs are supported as a SystemParam; thus, the inner values never need to be read."
3054        )]
3055        #[derive(SystemParam)]
3056        pub struct TupleParam<'w, 's, R: Resource, L: FromWorld + Send + 'static>(
3057            Res<'w, R>,
3058            Local<'s, L>,
3059        );
3060
3061        fn my_system(_: UnitParam, _: TupleParam<R<0>, u32>) {}
3062        assert_is_system(my_system);
3063    }
3064
3065    // Regression test for https://github.com/bevyengine/bevy/issues/4200.
3066    #[test]
3067    fn system_param_private_fields() {
3068        #[derive(Resource)]
3069        struct PrivateResource;
3070
3071        #[expect(
3072            dead_code,
3073            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."
3074        )]
3075        #[derive(SystemParam)]
3076        pub struct EncapsulatedParam<'w>(Res<'w, PrivateResource>);
3077
3078        fn my_system(_: EncapsulatedParam) {}
3079        assert_is_system(my_system);
3080    }
3081
3082    // Regression test for https://github.com/bevyengine/bevy/issues/7103.
3083    #[test]
3084    fn system_param_where_clause() {
3085        #[derive(SystemParam)]
3086        pub struct WhereParam<'w, 's, D>
3087        where
3088            D: 'static + QueryData,
3089        {
3090            _q: Query<'w, 's, D, ()>,
3091        }
3092
3093        fn my_system(_: WhereParam<()>) {}
3094        assert_is_system(my_system);
3095    }
3096
3097    // Regression test for https://github.com/bevyengine/bevy/issues/1727.
3098    #[test]
3099    fn system_param_name_collision() {
3100        #[derive(Resource)]
3101        pub struct FetchState;
3102
3103        #[derive(SystemParam)]
3104        pub struct Collide<'w> {
3105            _x: Res<'w, FetchState>,
3106        }
3107
3108        fn my_system(_: Collide) {}
3109        assert_is_system(my_system);
3110    }
3111
3112    // Regression test for https://github.com/bevyengine/bevy/issues/8192.
3113    #[test]
3114    fn system_param_invariant_lifetime() {
3115        #[derive(SystemParam)]
3116        pub struct InvariantParam<'w, 's> {
3117            _set: ParamSet<'w, 's, (Query<'w, 's, ()>,)>,
3118        }
3119
3120        fn my_system(_: InvariantParam) {}
3121        assert_is_system(my_system);
3122    }
3123
3124    // Compile test for https://github.com/bevyengine/bevy/pull/9589.
3125    #[test]
3126    fn non_sync_local() {
3127        fn non_sync_system(cell: Local<RefCell<u8>>) {
3128            assert_eq!(*cell.borrow(), 0);
3129        }
3130
3131        let mut world = World::new();
3132        let mut schedule = crate::schedule::Schedule::default();
3133        schedule.add_systems(non_sync_system);
3134        schedule.run(&mut world);
3135    }
3136
3137    // Regression test for https://github.com/bevyengine/bevy/issues/10207.
3138    #[test]
3139    fn param_set_non_send_first() {
3140        fn non_send_param_set(mut p: ParamSet<(NonSend<*mut u8>, ())>) {
3141            let _ = p.p0();
3142            p.p1();
3143        }
3144
3145        let mut world = World::new();
3146        world.insert_non_send_resource(core::ptr::null_mut::<u8>());
3147        let mut schedule = crate::schedule::Schedule::default();
3148        schedule.add_systems((non_send_param_set, non_send_param_set, non_send_param_set));
3149        schedule.run(&mut world);
3150    }
3151
3152    // Regression test for https://github.com/bevyengine/bevy/issues/10207.
3153    #[test]
3154    fn param_set_non_send_second() {
3155        fn non_send_param_set(mut p: ParamSet<((), NonSendMut<*mut u8>)>) {
3156            p.p0();
3157            let _ = p.p1();
3158        }
3159
3160        let mut world = World::new();
3161        world.insert_non_send_resource(core::ptr::null_mut::<u8>());
3162        let mut schedule = crate::schedule::Schedule::default();
3163        schedule.add_systems((non_send_param_set, non_send_param_set, non_send_param_set));
3164        schedule.run(&mut world);
3165    }
3166
3167    fn _dyn_system_param_type_inference(mut p: DynSystemParam) {
3168        // Make sure the downcast() methods are able to infer their type parameters from the use of the return type.
3169        // This is just a compilation test, so there is nothing to run.
3170        let _query: Query<()> = p.downcast_mut().unwrap();
3171        let _query: Query<()> = p.downcast_mut_inner().unwrap();
3172        let _query: Query<()> = p.downcast().unwrap();
3173    }
3174
3175    #[test]
3176    #[should_panic]
3177    fn missing_resource_error() {
3178        #[derive(Resource)]
3179        pub struct MissingResource;
3180
3181        let mut schedule = crate::schedule::Schedule::default();
3182        schedule.add_systems(res_system);
3183        let mut world = World::new();
3184        schedule.run(&mut world);
3185
3186        fn res_system(_: Res<MissingResource>) {}
3187    }
3188
3189    #[test]
3190    #[should_panic]
3191    fn missing_message_error() {
3192        use crate::prelude::{Message, MessageReader};
3193
3194        #[derive(Message)]
3195        pub struct MissingEvent;
3196
3197        let mut schedule = crate::schedule::Schedule::default();
3198        schedule.add_systems(message_system);
3199        let mut world = World::new();
3200        schedule.run(&mut world);
3201
3202        fn message_system(_: MessageReader<MissingEvent>) {}
3203    }
3204}