bevy_ecs/system/
system_param.rs

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