Thanks to visit codestin.com
Credit goes to docs.rs

bevy_ecs/system/
system_param.rs

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