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    prelude::QueryBuilder,
9    query::{
10        Access, FilteredAccess, FilteredAccessSet, QueryData, QueryFilter, QueryState,
11        ReadOnlyQueryData,
12    },
13    system::{Query, SystemMeta},
14    world::{unsafe_world_cell::UnsafeWorldCell, DeferredWorld, FromWorld, World},
15};
16use bevy_ecs_macros::impl_param_set;
17pub use bevy_ecs_macros::Resource;
18pub use bevy_ecs_macros::SystemParam;
19use bevy_ptr::UnsafeCellDeref;
20use bevy_utils::{all_tuples, synccell::SyncCell};
21use std::{
22    fmt::Debug,
23    marker::PhantomData,
24    ops::{Deref, DerefMut},
25};
26
27/// A parameter that can be used in a [`System`](super::System).
28///
29/// # Derive
30///
31/// This trait can be derived with the [`derive@super::SystemParam`] macro.
32/// This macro only works if each field on the derived struct implements [`SystemParam`].
33/// Note: There are additional requirements on the field types.
34/// See the *Generic `SystemParam`s* section for details and workarounds of the probable
35/// cause if this derive causes an error to be emitted.
36///
37/// Derived `SystemParam` structs may have two lifetimes: `'w` for data stored in the [`World`],
38/// and `'s` for data stored in the parameter's state.
39///
40/// The following list shows the most common [`SystemParam`]s and which lifetime they require
41///
42/// ```
43/// # use bevy_ecs::prelude::*;
44/// # #[derive(Resource)]
45/// # struct SomeResource;
46/// # #[derive(Event)]
47/// # struct SomeEvent;
48/// # #[derive(Resource)]
49/// # struct SomeOtherResource;
50/// # use bevy_ecs::system::SystemParam;
51/// # #[derive(SystemParam)]
52/// # struct ParamsExample<'w, 's> {
53/// #    query:
54/// Query<'w, 's, Entity>,
55/// #    res:
56/// Res<'w, SomeResource>,
57/// #    res_mut:
58/// ResMut<'w, SomeOtherResource>,
59/// #    local:
60/// Local<'s, u8>,
61/// #    commands:
62/// Commands<'w, 's>,
63/// #    eventreader:
64/// EventReader<'w, 's, SomeEvent>,
65/// #    eventwriter:
66/// EventWriter<'w, SomeEvent>
67/// # }
68///```
69/// ## `PhantomData`
70///
71/// [`PhantomData`] is a special type of `SystemParam` that does nothing.
72/// This is useful for constraining generic types or lifetimes.
73///
74/// # Example
75///
76/// ```
77/// # use bevy_ecs::prelude::*;
78/// # #[derive(Resource)]
79/// # struct SomeResource;
80/// use std::marker::PhantomData;
81/// use bevy_ecs::system::SystemParam;
82///
83/// #[derive(SystemParam)]
84/// struct MyParam<'w, Marker: 'static> {
85///     foo: Res<'w, SomeResource>,
86///     marker: PhantomData<Marker>,
87/// }
88///
89/// fn my_system<T: 'static>(param: MyParam<T>) {
90///     // Access the resource through `param.foo`
91/// }
92///
93/// # bevy_ecs::system::assert_is_system(my_system::<()>);
94/// ```
95///
96/// # Generic `SystemParam`s
97///
98/// When using the derive macro, you may see an error in the form of:
99///
100/// ```text
101/// expected ... [ParamType]
102/// found associated type `<[ParamType] as SystemParam>::Item<'_, '_>`
103/// ```
104/// where `[ParamType]` is the type of one of your fields.
105/// To solve this error, you can wrap the field of type `[ParamType]` with [`StaticSystemParam`]
106/// (i.e. `StaticSystemParam<[ParamType]>`).
107///
108/// ## Details
109///
110/// The derive macro requires that the [`SystemParam`] implementation of
111/// each field `F`'s [`Item`](`SystemParam::Item`)'s is itself `F`
112/// (ignoring lifetimes for simplicity).
113/// This assumption is due to type inference reasons, so that the derived [`SystemParam`] can be
114/// used as an argument to a function system.
115/// If the compiler cannot validate this property for `[ParamType]`, it will error in the form shown above.
116///
117/// This will most commonly occur when working with `SystemParam`s generically, as the requirement
118/// has not been proven to the compiler.
119///
120/// # Safety
121///
122/// The implementor must ensure the following is true.
123/// - [`SystemParam::init_state`] correctly registers all [`World`] accesses used
124///   by [`SystemParam::get_param`] with the provided [`system_meta`](SystemMeta).
125/// - None of the world accesses may conflict with any prior accesses registered
126///   on `system_meta`.
127pub unsafe trait SystemParam: Sized {
128    /// Used to store data which persists across invocations of a system.
129    type State: Send + Sync + 'static;
130
131    /// The item type returned when constructing this system param.
132    /// The value of this associated type should be `Self`, instantiated with new lifetimes.
133    ///
134    /// You could think of `SystemParam::Item<'w, 's>` as being an *operation* that changes the lifetimes bound to `Self`.
135    type Item<'world, 'state>: SystemParam<State = Self::State>;
136
137    /// Registers any [`World`] access used by this [`SystemParam`]
138    /// and creates a new instance of this param's [`State`](Self::State).
139    fn init_state(world: &mut World, system_meta: &mut SystemMeta) -> Self::State;
140
141    /// For the specified [`Archetype`], registers the components accessed by this [`SystemParam`] (if applicable).a
142    ///
143    /// # Safety
144    /// `archetype` must be from the [`World`] used to initialize `state` in `init_state`.
145    #[inline]
146    #[allow(unused_variables)]
147    unsafe fn new_archetype(
148        state: &mut Self::State,
149        archetype: &Archetype,
150        system_meta: &mut SystemMeta,
151    ) {
152    }
153
154    /// Applies any deferred mutations stored in this [`SystemParam`]'s state.
155    /// This is used to apply [`Commands`] during [`apply_deferred`](crate::prelude::apply_deferred).
156    ///
157    /// [`Commands`]: crate::prelude::Commands
158    #[inline]
159    #[allow(unused_variables)]
160    fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World) {}
161
162    /// Queues any deferred mutations to be applied at the next [`apply_deferred`](crate::prelude::apply_deferred).
163    #[inline]
164    #[allow(unused_variables)]
165    fn queue(state: &mut Self::State, system_meta: &SystemMeta, world: DeferredWorld) {}
166
167    /// Creates a parameter to be passed into a [`SystemParamFunction`].
168    ///
169    /// [`SystemParamFunction`]: super::SystemParamFunction
170    ///
171    /// # Safety
172    ///
173    /// - The passed [`UnsafeWorldCell`] must have access to any world data
174    ///   registered in [`init_state`](SystemParam::init_state).
175    /// - `world` must be the same `World` that was used to initialize [`state`](SystemParam::init_state).
176    unsafe fn get_param<'world, 'state>(
177        state: &'state mut Self::State,
178        system_meta: &SystemMeta,
179        world: UnsafeWorldCell<'world>,
180        change_tick: Tick,
181    ) -> Self::Item<'world, 'state>;
182}
183
184/// A parameter that can be built with [`SystemBuilder`](crate::system::builder::SystemBuilder)
185pub trait BuildableSystemParam: SystemParam {
186    /// A mutable reference to this type will be passed to the builder function
187    type Builder<'b>;
188
189    /// Constructs [`SystemParam::State`] for `Self` using a given builder function
190    fn build(
191        world: &mut World,
192        meta: &mut SystemMeta,
193        func: impl FnOnce(&mut Self::Builder<'_>),
194    ) -> Self::State;
195}
196
197/// A [`SystemParam`] that only reads a given [`World`].
198///
199/// # Safety
200/// This must only be implemented for [`SystemParam`] impls that exclusively read the World passed in to [`SystemParam::get_param`]
201pub unsafe trait ReadOnlySystemParam: SystemParam {}
202
203/// Shorthand way of accessing the associated type [`SystemParam::Item`] for a given [`SystemParam`].
204pub type SystemParamItem<'w, 's, P> = <P as SystemParam>::Item<'w, 's>;
205
206// SAFETY: QueryState is constrained to read-only fetches, so it only reads World.
207unsafe impl<'w, 's, D: ReadOnlyQueryData + 'static, F: QueryFilter + 'static> ReadOnlySystemParam
208    for Query<'w, 's, D, F>
209{
210}
211
212// SAFETY: Relevant query ComponentId and ArchetypeComponentId access is applied to SystemMeta. If
213// this Query conflicts with any prior access, a panic will occur.
214unsafe impl<D: QueryData + 'static, F: QueryFilter + 'static> SystemParam for Query<'_, '_, D, F> {
215    type State = QueryState<D, F>;
216    type Item<'w, 's> = Query<'w, 's, D, F>;
217
218    fn init_state(world: &mut World, system_meta: &mut SystemMeta) -> Self::State {
219        let state = QueryState::new_with_access(world, &mut system_meta.archetype_component_access);
220        assert_component_access_compatibility(
221            &system_meta.name,
222            std::any::type_name::<D>(),
223            std::any::type_name::<F>(),
224            &system_meta.component_access_set,
225            &state.component_access,
226            world,
227        );
228        system_meta
229            .component_access_set
230            .add(state.component_access.clone());
231        state
232    }
233
234    unsafe fn new_archetype(
235        state: &mut Self::State,
236        archetype: &Archetype,
237        system_meta: &mut SystemMeta,
238    ) {
239        state.new_archetype(archetype, &mut system_meta.archetype_component_access);
240    }
241
242    #[inline]
243    unsafe fn get_param<'w, 's>(
244        state: &'s mut Self::State,
245        system_meta: &SystemMeta,
246        world: UnsafeWorldCell<'w>,
247        change_tick: Tick,
248    ) -> Self::Item<'w, 's> {
249        // SAFETY: We have registered all of the query's world accesses,
250        // so the caller ensures that `world` has permission to access any
251        // world data that the query needs.
252        unsafe { Query::new(world, state, system_meta.last_run, change_tick) }
253    }
254}
255
256impl<'w, 's, D: QueryData + 'static, F: QueryFilter + 'static> BuildableSystemParam
257    for Query<'w, 's, D, F>
258{
259    type Builder<'b> = QueryBuilder<'b, D, F>;
260
261    #[inline]
262    fn build(
263        world: &mut World,
264        system_meta: &mut SystemMeta,
265        build: impl FnOnce(&mut Self::Builder<'_>),
266    ) -> Self::State {
267        let mut builder = QueryBuilder::new(world);
268        build(&mut builder);
269        let state = builder.build();
270        assert_component_access_compatibility(
271            &system_meta.name,
272            std::any::type_name::<D>(),
273            std::any::type_name::<F>(),
274            &system_meta.component_access_set,
275            &state.component_access,
276            world,
277        );
278        system_meta
279            .component_access_set
280            .add(state.component_access.clone());
281        state
282    }
283}
284
285fn assert_component_access_compatibility(
286    system_name: &str,
287    query_type: &'static str,
288    filter_type: &'static str,
289    system_access: &FilteredAccessSet<ComponentId>,
290    current: &FilteredAccess<ComponentId>,
291    world: &World,
292) {
293    let conflicts = system_access.get_conflicts_single(current);
294    if conflicts.is_empty() {
295        return;
296    }
297    let conflicting_components = conflicts
298        .into_iter()
299        .map(|component_id| world.components.get_info(component_id).unwrap().name())
300        .collect::<Vec<&str>>();
301    let accesses = conflicting_components.join(", ");
302    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");
303}
304
305/// A collection of potentially conflicting [`SystemParam`]s allowed by disjoint access.
306///
307/// Allows systems to safely access and interact with up to 8 mutually exclusive [`SystemParam`]s, such as
308/// two queries that reference the same mutable data or an event reader and writer of the same type.
309///
310/// Each individual [`SystemParam`] can be accessed by using the functions `p0()`, `p1()`, ..., `p7()`,
311/// according to the order they are defined in the `ParamSet`. This ensures that there's either
312/// only one mutable reference to a parameter at a time or any number of immutable references.
313///
314/// # Examples
315///
316/// The following system mutably accesses the same component two times,
317/// which is not allowed due to rust's mutability rules.
318///
319/// ```should_panic
320/// # use bevy_ecs::prelude::*;
321/// #
322/// # #[derive(Component)]
323/// # struct Health;
324/// #
325/// # #[derive(Component)]
326/// # struct Enemy;
327/// #
328/// # #[derive(Component)]
329/// # struct Ally;
330/// #
331/// // This will panic at runtime when the system gets initialized.
332/// fn bad_system(
333///     mut enemies: Query<&mut Health, With<Enemy>>,
334///     mut allies: Query<&mut Health, With<Ally>>,
335/// ) {
336///     // ...
337/// }
338/// #
339/// # let mut bad_system_system = IntoSystem::into_system(bad_system);
340/// # let mut world = World::new();
341/// # bad_system_system.initialize(&mut world);
342/// # bad_system_system.run((), &mut world);
343/// ```
344///
345/// Conflicting `SystemParam`s like these can be placed in a `ParamSet`,
346/// which leverages the borrow checker to ensure that only one of the contained parameters are accessed at a given time.
347///
348/// ```
349/// # use bevy_ecs::prelude::*;
350/// #
351/// # #[derive(Component)]
352/// # struct Health;
353/// #
354/// # #[derive(Component)]
355/// # struct Enemy;
356/// #
357/// # #[derive(Component)]
358/// # struct Ally;
359/// #
360/// // Given the following system
361/// fn fancy_system(
362///     mut set: ParamSet<(
363///         Query<&mut Health, With<Enemy>>,
364///         Query<&mut Health, With<Ally>>,
365///     )>
366/// ) {
367///     // This will access the first `SystemParam`.
368///     for mut health in set.p0().iter_mut() {
369///         // Do your fancy stuff here...
370///     }
371///
372///     // The second `SystemParam`.
373///     // This would fail to compile if the previous parameter was still borrowed.
374///     for mut health in set.p1().iter_mut() {
375///         // Do even fancier stuff here...
376///     }
377/// }
378/// # bevy_ecs::system::assert_is_system(fancy_system);
379/// ```
380///
381/// Of course, `ParamSet`s can be used with any kind of `SystemParam`, not just [queries](Query).
382///
383/// ```
384/// # use bevy_ecs::prelude::*;
385/// #
386/// # #[derive(Event)]
387/// # struct MyEvent;
388/// # impl MyEvent {
389/// #   pub fn new() -> Self { Self }
390/// # }
391/// fn event_system(
392///     mut set: ParamSet<(
393///         // `EventReader`s and `EventWriter`s conflict with each other,
394///         // since they both access the event queue resource for `MyEvent`.
395///         EventReader<MyEvent>,
396///         EventWriter<MyEvent>,
397///         // `&World` reads the entire world, so a `ParamSet` is the only way
398///         // that it can be used in the same system as any mutable accesses.
399///         &World,
400///     )>,
401/// ) {
402///     for event in set.p0().read() {
403///         // ...
404///         # let _event = event;
405///     }
406///     set.p1().send(MyEvent::new());
407///     
408///     let entities = set.p2().entities();
409///     // ...
410///     # let _entities = entities;
411/// }
412/// # bevy_ecs::system::assert_is_system(event_system);
413/// ```
414pub struct ParamSet<'w, 's, T: SystemParam> {
415    param_states: &'s mut T::State,
416    world: UnsafeWorldCell<'w>,
417    system_meta: SystemMeta,
418    change_tick: Tick,
419}
420
421impl_param_set!();
422
423/// A type that can be inserted into a [`World`] as a singleton.
424///
425/// You can access resource data in systems using the [`Res`] and [`ResMut`] system parameters
426///
427/// Only one resource of each type can be stored in a [`World`] at any given time.
428///
429/// # Examples
430///
431/// ```
432/// # let mut world = World::default();
433/// # let mut schedule = Schedule::default();
434/// # use bevy_ecs::prelude::*;
435/// #[derive(Resource)]
436/// struct MyResource { value: u32 }
437///
438/// world.insert_resource(MyResource { value: 42 });
439///
440/// fn read_resource_system(resource: Res<MyResource>) {
441///     assert_eq!(resource.value, 42);
442/// }
443///
444/// fn write_resource_system(mut resource: ResMut<MyResource>) {
445///     assert_eq!(resource.value, 42);
446///     resource.value = 0;
447///     assert_eq!(resource.value, 0);
448/// }
449/// # schedule.add_systems((read_resource_system, write_resource_system).chain());
450/// # schedule.run(&mut world);
451/// ```
452///
453/// # `!Sync` Resources
454/// A `!Sync` type cannot implement `Resource`. However, it is possible to wrap a `Send` but not `Sync`
455/// type in [`SyncCell`] or the currently unstable [`Exclusive`] to make it `Sync`. This forces only
456/// having mutable access (`&mut T` only, never `&T`), but makes it safe to reference across multiple
457/// threads.
458///
459/// This will fail to compile since `RefCell` is `!Sync`.
460/// ```compile_fail
461/// # use std::cell::RefCell;
462/// # use bevy_ecs::system::Resource;
463///
464/// #[derive(Resource)]
465/// struct NotSync {
466///    counter: RefCell<usize>,
467/// }
468/// ```
469///
470/// This will compile since the `RefCell` is wrapped with `SyncCell`.
471/// ```
472/// # use std::cell::RefCell;
473/// # use bevy_ecs::system::Resource;
474/// use bevy_utils::synccell::SyncCell;
475///
476/// #[derive(Resource)]
477/// struct ActuallySync {
478///    counter: SyncCell<RefCell<usize>>,
479/// }
480/// ```
481///
482/// [`Exclusive`]: https://doc.rust-lang.org/nightly/std/sync/struct.Exclusive.html
483#[diagnostic::on_unimplemented(
484    message = "`{Self}` is not a `Resource`",
485    label = "invalid `Resource`",
486    note = "consider annotating `{Self}` with `#[derive(Resource)]`"
487)]
488pub trait Resource: Send + Sync + 'static {}
489
490// SAFETY: Res only reads a single World resource
491unsafe impl<'a, T: Resource> ReadOnlySystemParam for Res<'a, T> {}
492
493// SAFETY: Res ComponentId and ArchetypeComponentId access is applied to SystemMeta. If this Res
494// conflicts with any prior access, a panic will occur.
495unsafe impl<'a, T: Resource> SystemParam for Res<'a, T> {
496    type State = ComponentId;
497    type Item<'w, 's> = Res<'w, T>;
498
499    fn init_state(world: &mut World, system_meta: &mut SystemMeta) -> Self::State {
500        let component_id = world.components.init_resource::<T>();
501        world.initialize_resource_internal(component_id);
502
503        let combined_access = system_meta.component_access_set.combined_access();
504        assert!(
505            !combined_access.has_write(component_id),
506            "error[B0002]: Res<{}> in system {} conflicts with a previous ResMut<{0}> access. Consider removing the duplicate access. See: https://bevyengine.org/learn/errors/#b0002",
507            std::any::type_name::<T>(),
508            system_meta.name,
509        );
510        system_meta
511            .component_access_set
512            .add_unfiltered_read(component_id);
513
514        let archetype_component_id = world
515            .get_resource_archetype_component_id(component_id)
516            .unwrap();
517        system_meta
518            .archetype_component_access
519            .add_read(archetype_component_id);
520
521        component_id
522    }
523
524    #[inline]
525    unsafe fn get_param<'w, 's>(
526        &mut component_id: &'s mut Self::State,
527        system_meta: &SystemMeta,
528        world: UnsafeWorldCell<'w>,
529        change_tick: Tick,
530    ) -> Self::Item<'w, 's> {
531        let (ptr, ticks) = world
532            .get_resource_with_ticks(component_id)
533            .unwrap_or_else(|| {
534                panic!(
535                    "Resource requested by {} does not exist: {}",
536                    system_meta.name,
537                    std::any::type_name::<T>()
538                )
539            });
540        Res {
541            value: ptr.deref(),
542            ticks: Ticks {
543                added: ticks.added.deref(),
544                changed: ticks.changed.deref(),
545                last_run: system_meta.last_run,
546                this_run: change_tick,
547            },
548        }
549    }
550}
551
552// SAFETY: Only reads a single World resource
553unsafe impl<'a, T: Resource> ReadOnlySystemParam for Option<Res<'a, T>> {}
554
555// SAFETY: this impl defers to `Res`, which initializes and validates the correct world access.
556unsafe impl<'a, T: Resource> SystemParam for Option<Res<'a, T>> {
557    type State = ComponentId;
558    type Item<'w, 's> = Option<Res<'w, T>>;
559
560    fn init_state(world: &mut World, system_meta: &mut SystemMeta) -> Self::State {
561        Res::<T>::init_state(world, system_meta)
562    }
563
564    #[inline]
565    unsafe fn get_param<'w, 's>(
566        &mut component_id: &'s mut Self::State,
567        system_meta: &SystemMeta,
568        world: UnsafeWorldCell<'w>,
569        change_tick: Tick,
570    ) -> Self::Item<'w, 's> {
571        world
572            .get_resource_with_ticks(component_id)
573            .map(|(ptr, ticks)| Res {
574                value: ptr.deref(),
575                ticks: Ticks {
576                    added: ticks.added.deref(),
577                    changed: ticks.changed.deref(),
578                    last_run: system_meta.last_run,
579                    this_run: change_tick,
580                },
581            })
582    }
583}
584
585// SAFETY: Res ComponentId and ArchetypeComponentId access is applied to SystemMeta. If this Res
586// conflicts with any prior access, a panic will occur.
587unsafe impl<'a, T: Resource> SystemParam for ResMut<'a, T> {
588    type State = ComponentId;
589    type Item<'w, 's> = ResMut<'w, T>;
590
591    fn init_state(world: &mut World, system_meta: &mut SystemMeta) -> Self::State {
592        let component_id = world.components.init_resource::<T>();
593        world.initialize_resource_internal(component_id);
594
595        let combined_access = system_meta.component_access_set.combined_access();
596        if combined_access.has_write(component_id) {
597            panic!(
598                "error[B0002]: ResMut<{}> in system {} conflicts with a previous ResMut<{0}> access. Consider removing the duplicate access. See: https://bevyengine.org/learn/errors/#b0002",
599                std::any::type_name::<T>(), system_meta.name);
600        } else if combined_access.has_read(component_id) {
601            panic!(
602                "error[B0002]: ResMut<{}> in system {} conflicts with a previous Res<{0}> access. Consider removing the duplicate access. See: https://bevyengine.org/learn/errors/#b0002",
603                std::any::type_name::<T>(), system_meta.name);
604        }
605        system_meta
606            .component_access_set
607            .add_unfiltered_write(component_id);
608
609        let archetype_component_id = world
610            .get_resource_archetype_component_id(component_id)
611            .unwrap();
612        system_meta
613            .archetype_component_access
614            .add_write(archetype_component_id);
615
616        component_id
617    }
618
619    #[inline]
620    unsafe fn get_param<'w, 's>(
621        &mut component_id: &'s mut Self::State,
622        system_meta: &SystemMeta,
623        world: UnsafeWorldCell<'w>,
624        change_tick: Tick,
625    ) -> Self::Item<'w, 's> {
626        let value = world
627            .get_resource_mut_by_id(component_id)
628            .unwrap_or_else(|| {
629                panic!(
630                    "Resource requested by {} does not exist: {}",
631                    system_meta.name,
632                    std::any::type_name::<T>()
633                )
634            });
635        ResMut {
636            value: value.value.deref_mut::<T>(),
637            ticks: TicksMut {
638                added: value.ticks.added,
639                changed: value.ticks.changed,
640                last_run: system_meta.last_run,
641                this_run: change_tick,
642            },
643        }
644    }
645}
646
647// SAFETY: this impl defers to `ResMut`, which initializes and validates the correct world access.
648unsafe impl<'a, T: Resource> SystemParam for Option<ResMut<'a, T>> {
649    type State = ComponentId;
650    type Item<'w, 's> = Option<ResMut<'w, T>>;
651
652    fn init_state(world: &mut World, system_meta: &mut SystemMeta) -> Self::State {
653        ResMut::<T>::init_state(world, system_meta)
654    }
655
656    #[inline]
657    unsafe fn get_param<'w, 's>(
658        &mut component_id: &'s mut Self::State,
659        system_meta: &SystemMeta,
660        world: UnsafeWorldCell<'w>,
661        change_tick: Tick,
662    ) -> Self::Item<'w, 's> {
663        world
664            .get_resource_mut_by_id(component_id)
665            .map(|value| ResMut {
666                value: value.value.deref_mut::<T>(),
667                ticks: TicksMut {
668                    added: value.ticks.added,
669                    changed: value.ticks.changed,
670                    last_run: system_meta.last_run,
671                    this_run: change_tick,
672                },
673            })
674    }
675}
676
677/// SAFETY: only reads world
678unsafe impl<'w> ReadOnlySystemParam for &'w World {}
679
680// SAFETY: `read_all` access is set and conflicts result in a panic
681unsafe impl SystemParam for &'_ World {
682    type State = ();
683    type Item<'w, 's> = &'w World;
684
685    fn init_state(_world: &mut World, system_meta: &mut SystemMeta) -> Self::State {
686        let mut access = Access::default();
687        access.read_all();
688        if !system_meta
689            .archetype_component_access
690            .is_compatible(&access)
691        {
692            panic!("&World conflicts with a previous mutable system parameter. Allowing this would break Rust's mutability rules");
693        }
694        system_meta.archetype_component_access.extend(&access);
695
696        let mut filtered_access = FilteredAccess::default();
697
698        filtered_access.read_all();
699        if !system_meta
700            .component_access_set
701            .get_conflicts_single(&filtered_access)
702            .is_empty()
703        {
704            panic!("&World conflicts with a previous mutable system parameter. Allowing this would break Rust's mutability rules");
705        }
706        system_meta.component_access_set.add(filtered_access);
707    }
708
709    unsafe fn get_param<'w, 's>(
710        _state: &'s mut Self::State,
711        _system_meta: &SystemMeta,
712        world: UnsafeWorldCell<'w>,
713        _change_tick: Tick,
714    ) -> Self::Item<'w, 's> {
715        // SAFETY: Read-only access to the entire world was registered in `init_state`.
716        unsafe { world.world() }
717    }
718}
719
720/// SAFETY: `DeferredWorld` can read all components and resources but cannot be used to gain any other mutable references.
721unsafe impl<'w> SystemParam for DeferredWorld<'w> {
722    type State = ();
723    type Item<'world, 'state> = DeferredWorld<'world>;
724
725    fn init_state(_world: &mut World, system_meta: &mut SystemMeta) -> Self::State {
726        system_meta.component_access_set.read_all();
727        system_meta.component_access_set.write_all();
728        system_meta.set_has_deferred();
729    }
730
731    unsafe fn get_param<'world, 'state>(
732        _state: &'state mut Self::State,
733        _system_meta: &SystemMeta,
734        world: UnsafeWorldCell<'world>,
735        _change_tick: Tick,
736    ) -> Self::Item<'world, 'state> {
737        world.into_deferred()
738    }
739}
740
741/// A system local [`SystemParam`].
742///
743/// A local may only be accessed by the system itself and is therefore not visible to other systems.
744/// If two or more systems specify the same local type each will have their own unique local.
745/// If multiple [`SystemParam`]s within the same system each specify the same local type
746/// each will get their own distinct data storage.
747///
748/// The supplied lifetime parameter is the [`SystemParam`]s `'s` lifetime.
749///
750/// # Examples
751///
752/// ```
753/// # use bevy_ecs::prelude::*;
754/// # let world = &mut World::default();
755/// fn write_to_local(mut local: Local<usize>) {
756///     *local = 42;
757/// }
758/// fn read_from_local(local: Local<usize>) -> usize {
759///     *local
760/// }
761/// let mut write_system = IntoSystem::into_system(write_to_local);
762/// let mut read_system = IntoSystem::into_system(read_from_local);
763/// write_system.initialize(world);
764/// read_system.initialize(world);
765///
766/// assert_eq!(read_system.run((), world), 0);
767/// write_system.run((), world);
768/// // Note how the read local is still 0 due to the locals not being shared.
769/// assert_eq!(read_system.run((), world), 0);
770/// ```
771///
772/// N.B. A [`Local`]s value cannot be read or written to outside of the containing system.
773/// To add configuration to a system, convert a capturing closure into the system instead:
774///
775/// ```
776/// # use bevy_ecs::prelude::*;
777/// # use bevy_ecs::system::assert_is_system;
778/// struct Config(u32);
779/// #[derive(Resource)]
780/// struct MyU32Wrapper(u32);
781/// fn reset_to_system(value: Config) -> impl FnMut(ResMut<MyU32Wrapper>) {
782///     move |mut val| val.0 = value.0
783/// }
784///
785/// // .add_systems(reset_to_system(my_config))
786/// # assert_is_system(reset_to_system(Config(10)));
787/// ```
788#[derive(Debug)]
789pub struct Local<'s, T: FromWorld + Send + 'static>(pub(crate) &'s mut T);
790
791// SAFETY: Local only accesses internal state
792unsafe impl<'s, T: FromWorld + Send + 'static> ReadOnlySystemParam for Local<'s, T> {}
793
794impl<'s, T: FromWorld + Send + 'static> Deref for Local<'s, T> {
795    type Target = T;
796
797    #[inline]
798    fn deref(&self) -> &Self::Target {
799        self.0
800    }
801}
802
803impl<'s, T: FromWorld + Send + 'static> DerefMut for Local<'s, T> {
804    #[inline]
805    fn deref_mut(&mut self) -> &mut Self::Target {
806        self.0
807    }
808}
809
810impl<'s, 'a, T: FromWorld + Send + 'static> IntoIterator for &'a Local<'s, T>
811where
812    &'a T: IntoIterator,
813{
814    type Item = <&'a T as IntoIterator>::Item;
815    type IntoIter = <&'a T as IntoIterator>::IntoIter;
816
817    fn into_iter(self) -> Self::IntoIter {
818        self.0.into_iter()
819    }
820}
821
822impl<'s, 'a, T: FromWorld + Send + 'static> IntoIterator for &'a mut Local<'s, T>
823where
824    &'a mut T: IntoIterator,
825{
826    type Item = <&'a mut T as IntoIterator>::Item;
827    type IntoIter = <&'a mut T as IntoIterator>::IntoIter;
828
829    fn into_iter(self) -> Self::IntoIter {
830        self.0.into_iter()
831    }
832}
833
834// SAFETY: only local state is accessed
835unsafe impl<'a, T: FromWorld + Send + 'static> SystemParam for Local<'a, T> {
836    type State = SyncCell<T>;
837    type Item<'w, 's> = Local<'s, T>;
838
839    fn init_state(world: &mut World, _system_meta: &mut SystemMeta) -> Self::State {
840        SyncCell::new(T::from_world(world))
841    }
842
843    #[inline]
844    unsafe fn get_param<'w, 's>(
845        state: &'s mut Self::State,
846        _system_meta: &SystemMeta,
847        _world: UnsafeWorldCell<'w>,
848        _change_tick: Tick,
849    ) -> Self::Item<'w, 's> {
850        Local(state.get())
851    }
852}
853
854impl<'w, T: FromWorld + Send + 'static> BuildableSystemParam for Local<'w, T> {
855    type Builder<'b> = T;
856
857    fn build(
858        world: &mut World,
859        _meta: &mut SystemMeta,
860        func: impl FnOnce(&mut Self::Builder<'_>),
861    ) -> Self::State {
862        let mut value = T::from_world(world);
863        func(&mut value);
864        SyncCell::new(value)
865    }
866}
867
868/// Types that can be used with [`Deferred<T>`] in systems.
869/// This allows storing system-local data which is used to defer [`World`] mutations.
870///
871/// Types that implement `SystemBuffer` should take care to perform as many
872/// computations up-front as possible. Buffers cannot be applied in parallel,
873/// so you should try to minimize the time spent in [`SystemBuffer::apply`].
874pub trait SystemBuffer: FromWorld + Send + 'static {
875    /// Applies any deferred mutations to the [`World`].
876    fn apply(&mut self, system_meta: &SystemMeta, world: &mut World);
877    /// Queues any deferred mutations to be applied at the next [`apply_deferred`](crate::prelude::apply_deferred).
878    fn queue(&mut self, _system_meta: &SystemMeta, _world: DeferredWorld) {}
879}
880
881/// A [`SystemParam`] that stores a buffer which gets applied to the [`World`] during
882/// [`apply_deferred`](crate::schedule::apply_deferred).
883/// This is used internally by [`Commands`] to defer `World` mutations.
884///
885/// [`Commands`]: crate::system::Commands
886///
887/// # Examples
888///
889/// By using this type to defer mutations, you can avoid mutable `World` access within
890/// a system, which allows it to run in parallel with more systems.
891///
892/// Note that deferring mutations is *not* free, and should only be used if
893/// the gains in parallelization outweigh the time it takes to apply deferred mutations.
894/// In general, [`Deferred`] should only be used for mutations that are infrequent,
895/// or which otherwise take up a small portion of a system's run-time.
896///
897/// ```
898/// # use bevy_ecs::prelude::*;
899/// // Tracks whether or not there is a threat the player should be aware of.
900/// #[derive(Resource, Default)]
901/// pub struct Alarm(bool);
902///
903/// #[derive(Component)]
904/// pub struct Settlement {
905///     // ...
906/// }
907///
908/// // A threat from inside the settlement.
909/// #[derive(Component)]
910/// pub struct Criminal;
911///
912/// // A threat from outside the settlement.
913/// #[derive(Component)]
914/// pub struct Monster;
915///
916/// # impl Criminal { pub fn is_threat(&self, _: &Settlement) -> bool { true } }
917///
918/// use bevy_ecs::system::{Deferred, SystemBuffer, SystemMeta};
919///
920/// // Uses deferred mutations to allow signalling the alarm from multiple systems in parallel.
921/// #[derive(Resource, Default)]
922/// struct AlarmFlag(bool);
923///
924/// impl AlarmFlag {
925///     /// Sounds the alarm the next time buffers are applied via apply_deferred.
926///     pub fn flag(&mut self) {
927///         self.0 = true;
928///     }
929/// }
930///
931/// impl SystemBuffer for AlarmFlag {
932///     // When `AlarmFlag` is used in a system, this function will get
933///     // called the next time buffers are applied via apply_deferred.
934///     fn apply(&mut self, system_meta: &SystemMeta, world: &mut World) {
935///         if self.0 {
936///             world.resource_mut::<Alarm>().0 = true;
937///             self.0 = false;
938///         }
939///     }
940/// }
941///
942/// // Sound the alarm if there are any criminals who pose a threat.
943/// fn alert_criminal(
944///     settlements: Query<&Settlement>,
945///     criminals: Query<&Criminal>,
946///     mut alarm: Deferred<AlarmFlag>
947/// ) {
948///     let settlement = settlements.single();
949///     for criminal in &criminals {
950///         // Only sound the alarm if the criminal is a threat.
951///         // For this example, assume that this check is expensive to run.
952///         // Since the majority of this system's run-time is dominated
953///         // by calling `is_threat()`, we defer sounding the alarm to
954///         // allow this system to run in parallel with other alarm systems.
955///         if criminal.is_threat(settlement) {
956///             alarm.flag();
957///         }
958///     }
959/// }
960///
961/// // Sound the alarm if there is a monster.
962/// fn alert_monster(
963///     monsters: Query<&Monster>,
964///     mut alarm: ResMut<Alarm>
965/// ) {
966///     if monsters.iter().next().is_some() {
967///         // Since this system does nothing except for sounding the alarm,
968///         // it would be pointless to defer it, so we sound the alarm directly.
969///         alarm.0 = true;
970///     }
971/// }
972///
973/// let mut world = World::new();
974/// world.init_resource::<Alarm>();
975/// world.spawn(Settlement {
976///     // ...
977/// });
978///
979/// let mut schedule = Schedule::default();
980/// // These two systems have no conflicts and will run in parallel.
981/// schedule.add_systems((alert_criminal, alert_monster));
982///
983/// // There are no criminals or monsters, so the alarm is not sounded.
984/// schedule.run(&mut world);
985/// assert_eq!(world.resource::<Alarm>().0, false);
986///
987/// // Spawn a monster, which will cause the alarm to be sounded.
988/// let m_id = world.spawn(Monster).id();
989/// schedule.run(&mut world);
990/// assert_eq!(world.resource::<Alarm>().0, true);
991///
992/// // Remove the monster and reset the alarm.
993/// world.entity_mut(m_id).despawn();
994/// world.resource_mut::<Alarm>().0 = false;
995///
996/// // Spawn a criminal, which will cause the alarm to be sounded.
997/// world.spawn(Criminal);
998/// schedule.run(&mut world);
999/// assert_eq!(world.resource::<Alarm>().0, true);
1000/// ```
1001pub struct Deferred<'a, T: SystemBuffer>(pub(crate) &'a mut T);
1002
1003impl<'a, T: SystemBuffer> Deref for Deferred<'a, T> {
1004    type Target = T;
1005    #[inline]
1006    fn deref(&self) -> &Self::Target {
1007        self.0
1008    }
1009}
1010
1011impl<'a, T: SystemBuffer> DerefMut for Deferred<'a, T> {
1012    #[inline]
1013    fn deref_mut(&mut self) -> &mut Self::Target {
1014        self.0
1015    }
1016}
1017
1018impl<T: SystemBuffer> Deferred<'_, T> {
1019    /// Returns a [`Deferred<T>`] with a smaller lifetime.
1020    /// This is useful if you have `&mut Deferred<T>` but need `Deferred<T>`.
1021    pub fn reborrow(&mut self) -> Deferred<T> {
1022        Deferred(self.0)
1023    }
1024}
1025
1026// SAFETY: Only local state is accessed.
1027unsafe impl<T: SystemBuffer> ReadOnlySystemParam for Deferred<'_, T> {}
1028
1029// SAFETY: Only local state is accessed.
1030unsafe impl<T: SystemBuffer> SystemParam for Deferred<'_, T> {
1031    type State = SyncCell<T>;
1032    type Item<'w, 's> = Deferred<'s, T>;
1033
1034    fn init_state(world: &mut World, system_meta: &mut SystemMeta) -> Self::State {
1035        system_meta.set_has_deferred();
1036        SyncCell::new(T::from_world(world))
1037    }
1038
1039    fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World) {
1040        state.get().apply(system_meta, world);
1041    }
1042
1043    fn queue(state: &mut Self::State, system_meta: &SystemMeta, world: DeferredWorld) {
1044        state.get().queue(system_meta, world);
1045    }
1046
1047    unsafe fn get_param<'w, 's>(
1048        state: &'s mut Self::State,
1049        _system_meta: &SystemMeta,
1050        _world: UnsafeWorldCell<'w>,
1051        _change_tick: Tick,
1052    ) -> Self::Item<'w, 's> {
1053        Deferred(state.get())
1054    }
1055}
1056
1057/// Shared borrow of a non-[`Send`] resource.
1058///
1059/// Only `Send` resources may be accessed with the [`Res`] [`SystemParam`]. In case that the
1060/// resource does not implement `Send`, this `SystemParam` wrapper can be used. This will instruct
1061/// the scheduler to instead run the system on the main thread so that it doesn't send the resource
1062/// over to another thread.
1063///
1064/// # Panics
1065///
1066/// Panics when used as a `SystemParameter` if the resource does not exist.
1067///
1068/// Use `Option<NonSend<T>>` instead if the resource might not always exist.
1069pub struct NonSend<'w, T: 'static> {
1070    pub(crate) value: &'w T,
1071    ticks: ComponentTicks,
1072    last_run: Tick,
1073    this_run: Tick,
1074}
1075
1076// SAFETY: Only reads a single World non-send resource
1077unsafe impl<'w, T> ReadOnlySystemParam for NonSend<'w, T> {}
1078
1079impl<'w, T> Debug for NonSend<'w, T>
1080where
1081    T: Debug,
1082{
1083    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1084        f.debug_tuple("NonSend").field(&self.value).finish()
1085    }
1086}
1087
1088impl<'w, T: 'static> NonSend<'w, T> {
1089    /// Returns `true` if the resource was added after the system last ran.
1090    pub fn is_added(&self) -> bool {
1091        self.ticks.is_added(self.last_run, self.this_run)
1092    }
1093
1094    /// Returns `true` if the resource was added or mutably dereferenced after the system last ran.
1095    pub fn is_changed(&self) -> bool {
1096        self.ticks.is_changed(self.last_run, self.this_run)
1097    }
1098}
1099
1100impl<'w, T> Deref for NonSend<'w, T> {
1101    type Target = T;
1102
1103    fn deref(&self) -> &Self::Target {
1104        self.value
1105    }
1106}
1107impl<'a, T> From<NonSendMut<'a, T>> for NonSend<'a, T> {
1108    fn from(nsm: NonSendMut<'a, T>) -> Self {
1109        Self {
1110            value: nsm.value,
1111            ticks: ComponentTicks {
1112                added: nsm.ticks.added.to_owned(),
1113                changed: nsm.ticks.changed.to_owned(),
1114            },
1115            this_run: nsm.ticks.this_run,
1116            last_run: nsm.ticks.last_run,
1117        }
1118    }
1119}
1120
1121// SAFETY: NonSendComponentId and ArchetypeComponentId access is applied to SystemMeta. If this
1122// NonSend conflicts with any prior access, a panic will occur.
1123unsafe impl<'a, T: 'static> SystemParam for NonSend<'a, T> {
1124    type State = ComponentId;
1125    type Item<'w, 's> = NonSend<'w, T>;
1126
1127    fn init_state(world: &mut World, system_meta: &mut SystemMeta) -> Self::State {
1128        system_meta.set_non_send();
1129
1130        let component_id = world.components.init_non_send::<T>();
1131        world.initialize_non_send_internal(component_id);
1132
1133        let combined_access = system_meta.component_access_set.combined_access();
1134        assert!(
1135            !combined_access.has_write(component_id),
1136            "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",
1137            std::any::type_name::<T>(),
1138            system_meta.name,
1139        );
1140        system_meta
1141            .component_access_set
1142            .add_unfiltered_read(component_id);
1143
1144        let archetype_component_id = world
1145            .get_non_send_archetype_component_id(component_id)
1146            .unwrap();
1147        system_meta
1148            .archetype_component_access
1149            .add_read(archetype_component_id);
1150
1151        component_id
1152    }
1153
1154    #[inline]
1155    unsafe fn get_param<'w, 's>(
1156        &mut component_id: &'s mut Self::State,
1157        system_meta: &SystemMeta,
1158        world: UnsafeWorldCell<'w>,
1159        change_tick: Tick,
1160    ) -> Self::Item<'w, 's> {
1161        let (ptr, ticks) = world
1162            .get_non_send_with_ticks(component_id)
1163            .unwrap_or_else(|| {
1164                panic!(
1165                    "Non-send resource requested by {} does not exist: {}",
1166                    system_meta.name,
1167                    std::any::type_name::<T>()
1168                )
1169            });
1170
1171        NonSend {
1172            value: ptr.deref(),
1173            ticks: ticks.read(),
1174            last_run: system_meta.last_run,
1175            this_run: change_tick,
1176        }
1177    }
1178}
1179
1180// SAFETY: Only reads a single World non-send resource
1181unsafe impl<T: 'static> ReadOnlySystemParam for Option<NonSend<'_, T>> {}
1182
1183// SAFETY: this impl defers to `NonSend`, which initializes and validates the correct world access.
1184unsafe impl<T: 'static> SystemParam for Option<NonSend<'_, T>> {
1185    type State = ComponentId;
1186    type Item<'w, 's> = Option<NonSend<'w, T>>;
1187
1188    fn init_state(world: &mut World, system_meta: &mut SystemMeta) -> Self::State {
1189        NonSend::<T>::init_state(world, system_meta)
1190    }
1191
1192    #[inline]
1193    unsafe fn get_param<'w, 's>(
1194        &mut component_id: &'s mut Self::State,
1195        system_meta: &SystemMeta,
1196        world: UnsafeWorldCell<'w>,
1197        change_tick: Tick,
1198    ) -> Self::Item<'w, 's> {
1199        world
1200            .get_non_send_with_ticks(component_id)
1201            .map(|(ptr, ticks)| NonSend {
1202                value: ptr.deref(),
1203                ticks: ticks.read(),
1204                last_run: system_meta.last_run,
1205                this_run: change_tick,
1206            })
1207    }
1208}
1209
1210// SAFETY: NonSendMut ComponentId and ArchetypeComponentId access is applied to SystemMeta. If this
1211// NonSendMut conflicts with any prior access, a panic will occur.
1212unsafe impl<'a, T: 'static> SystemParam for NonSendMut<'a, T> {
1213    type State = ComponentId;
1214    type Item<'w, 's> = NonSendMut<'w, T>;
1215
1216    fn init_state(world: &mut World, system_meta: &mut SystemMeta) -> Self::State {
1217        system_meta.set_non_send();
1218
1219        let component_id = world.components.init_non_send::<T>();
1220        world.initialize_non_send_internal(component_id);
1221
1222        let combined_access = system_meta.component_access_set.combined_access();
1223        if combined_access.has_write(component_id) {
1224            panic!(
1225                "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",
1226                std::any::type_name::<T>(), system_meta.name);
1227        } else if combined_access.has_read(component_id) {
1228            panic!(
1229                "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",
1230                std::any::type_name::<T>(), system_meta.name);
1231        }
1232        system_meta
1233            .component_access_set
1234            .add_unfiltered_write(component_id);
1235
1236        let archetype_component_id = world
1237            .get_non_send_archetype_component_id(component_id)
1238            .unwrap();
1239        system_meta
1240            .archetype_component_access
1241            .add_write(archetype_component_id);
1242
1243        component_id
1244    }
1245
1246    #[inline]
1247    unsafe fn get_param<'w, 's>(
1248        &mut component_id: &'s mut Self::State,
1249        system_meta: &SystemMeta,
1250        world: UnsafeWorldCell<'w>,
1251        change_tick: Tick,
1252    ) -> Self::Item<'w, 's> {
1253        let (ptr, ticks) = world
1254            .get_non_send_with_ticks(component_id)
1255            .unwrap_or_else(|| {
1256                panic!(
1257                    "Non-send resource requested by {} does not exist: {}",
1258                    system_meta.name,
1259                    std::any::type_name::<T>()
1260                )
1261            });
1262        NonSendMut {
1263            value: ptr.assert_unique().deref_mut(),
1264            ticks: TicksMut::from_tick_cells(ticks, system_meta.last_run, change_tick),
1265        }
1266    }
1267}
1268
1269// SAFETY: this impl defers to `NonSendMut`, which initializes and validates the correct world access.
1270unsafe impl<'a, T: 'static> SystemParam for Option<NonSendMut<'a, T>> {
1271    type State = ComponentId;
1272    type Item<'w, 's> = Option<NonSendMut<'w, T>>;
1273
1274    fn init_state(world: &mut World, system_meta: &mut SystemMeta) -> Self::State {
1275        NonSendMut::<T>::init_state(world, system_meta)
1276    }
1277
1278    #[inline]
1279    unsafe fn get_param<'w, 's>(
1280        &mut component_id: &'s mut Self::State,
1281        system_meta: &SystemMeta,
1282        world: UnsafeWorldCell<'w>,
1283        change_tick: Tick,
1284    ) -> Self::Item<'w, 's> {
1285        world
1286            .get_non_send_with_ticks(component_id)
1287            .map(|(ptr, ticks)| NonSendMut {
1288                value: ptr.assert_unique().deref_mut(),
1289                ticks: TicksMut::from_tick_cells(ticks, system_meta.last_run, change_tick),
1290            })
1291    }
1292}
1293
1294// SAFETY: Only reads World archetypes
1295unsafe impl<'a> ReadOnlySystemParam for &'a Archetypes {}
1296
1297// SAFETY: no component value access
1298unsafe impl<'a> SystemParam for &'a Archetypes {
1299    type State = ();
1300    type Item<'w, 's> = &'w Archetypes;
1301
1302    fn init_state(_world: &mut World, _system_meta: &mut SystemMeta) -> Self::State {}
1303
1304    #[inline]
1305    unsafe fn get_param<'w, 's>(
1306        _state: &'s mut Self::State,
1307        _system_meta: &SystemMeta,
1308        world: UnsafeWorldCell<'w>,
1309        _change_tick: Tick,
1310    ) -> Self::Item<'w, 's> {
1311        world.archetypes()
1312    }
1313}
1314
1315// SAFETY: Only reads World components
1316unsafe impl<'a> ReadOnlySystemParam for &'a Components {}
1317
1318// SAFETY: no component value access
1319unsafe impl<'a> SystemParam for &'a Components {
1320    type State = ();
1321    type Item<'w, 's> = &'w Components;
1322
1323    fn init_state(_world: &mut World, _system_meta: &mut SystemMeta) -> Self::State {}
1324
1325    #[inline]
1326    unsafe fn get_param<'w, 's>(
1327        _state: &'s mut Self::State,
1328        _system_meta: &SystemMeta,
1329        world: UnsafeWorldCell<'w>,
1330        _change_tick: Tick,
1331    ) -> Self::Item<'w, 's> {
1332        world.components()
1333    }
1334}
1335
1336// SAFETY: Only reads World entities
1337unsafe impl<'a> ReadOnlySystemParam for &'a Entities {}
1338
1339// SAFETY: no component value access
1340unsafe impl<'a> SystemParam for &'a Entities {
1341    type State = ();
1342    type Item<'w, 's> = &'w Entities;
1343
1344    fn init_state(_world: &mut World, _system_meta: &mut SystemMeta) -> Self::State {}
1345
1346    #[inline]
1347    unsafe fn get_param<'w, 's>(
1348        _state: &'s mut Self::State,
1349        _system_meta: &SystemMeta,
1350        world: UnsafeWorldCell<'w>,
1351        _change_tick: Tick,
1352    ) -> Self::Item<'w, 's> {
1353        world.entities()
1354    }
1355}
1356
1357// SAFETY: Only reads World bundles
1358unsafe impl<'a> ReadOnlySystemParam for &'a Bundles {}
1359
1360// SAFETY: no component value access
1361unsafe impl<'a> SystemParam for &'a Bundles {
1362    type State = ();
1363    type Item<'w, 's> = &'w Bundles;
1364
1365    fn init_state(_world: &mut World, _system_meta: &mut SystemMeta) -> Self::State {}
1366
1367    #[inline]
1368    unsafe fn get_param<'w, 's>(
1369        _state: &'s mut Self::State,
1370        _system_meta: &SystemMeta,
1371        world: UnsafeWorldCell<'w>,
1372        _change_tick: Tick,
1373    ) -> Self::Item<'w, 's> {
1374        world.bundles()
1375    }
1376}
1377
1378/// A [`SystemParam`] that reads the previous and current change ticks of the system.
1379///
1380/// A system's change ticks are updated each time it runs:
1381/// - `last_run` copies the previous value of `change_tick`
1382/// - `this_run` copies the current value of [`World::read_change_tick`]
1383///
1384/// Component change ticks that are more recent than `last_run` will be detected by the system.
1385/// Those can be read by calling [`last_changed`](crate::change_detection::DetectChanges::last_changed)
1386/// on a [`Mut<T>`](crate::change_detection::Mut) or [`ResMut<T>`](ResMut).
1387#[derive(Debug)]
1388pub struct SystemChangeTick {
1389    last_run: Tick,
1390    this_run: Tick,
1391}
1392
1393impl SystemChangeTick {
1394    /// Returns the current [`World`] change tick seen by the system.
1395    #[inline]
1396    pub fn this_run(&self) -> Tick {
1397        self.this_run
1398    }
1399
1400    /// Returns the [`World`] change tick seen by the system the previous time it ran.
1401    #[inline]
1402    pub fn last_run(&self) -> Tick {
1403        self.last_run
1404    }
1405}
1406
1407// SAFETY: Only reads internal system state
1408unsafe impl ReadOnlySystemParam for SystemChangeTick {}
1409
1410// SAFETY: `SystemChangeTick` doesn't require any world access
1411unsafe impl SystemParam for SystemChangeTick {
1412    type State = ();
1413    type Item<'w, 's> = SystemChangeTick;
1414
1415    fn init_state(_world: &mut World, _system_meta: &mut SystemMeta) -> Self::State {}
1416
1417    unsafe fn get_param<'w, 's>(
1418        _state: &'s mut Self::State,
1419        system_meta: &SystemMeta,
1420        _world: UnsafeWorldCell<'w>,
1421        change_tick: Tick,
1422    ) -> Self::Item<'w, 's> {
1423        SystemChangeTick {
1424            last_run: system_meta.last_run,
1425            this_run: change_tick,
1426        }
1427    }
1428}
1429
1430macro_rules! impl_system_param_tuple {
1431    ($($param: ident),*) => {
1432        // SAFETY: tuple consists only of ReadOnlySystemParams
1433        unsafe impl<$($param: ReadOnlySystemParam),*> ReadOnlySystemParam for ($($param,)*) {}
1434
1435        // SAFETY: implementors of each `SystemParam` in the tuple have validated their impls
1436        #[allow(clippy::undocumented_unsafe_blocks)] // false positive by clippy
1437        #[allow(non_snake_case)]
1438        unsafe impl<$($param: SystemParam),*> SystemParam for ($($param,)*) {
1439            type State = ($($param::State,)*);
1440            type Item<'w, 's> = ($($param::Item::<'w, 's>,)*);
1441
1442            #[inline]
1443            fn init_state(_world: &mut World, _system_meta: &mut SystemMeta) -> Self::State {
1444                (($($param::init_state(_world, _system_meta),)*))
1445            }
1446
1447            #[inline]
1448            #[allow(unused_unsafe)]
1449            unsafe fn new_archetype(($($param,)*): &mut Self::State, _archetype: &Archetype, _system_meta: &mut SystemMeta) {
1450                // SAFETY: The caller ensures that `archetype` is from the World the state was initialized from in `init_state`.
1451                unsafe { $($param::new_archetype($param, _archetype, _system_meta);)* }
1452            }
1453
1454            #[inline]
1455            fn apply(($($param,)*): &mut Self::State, _system_meta: &SystemMeta, _world: &mut World) {
1456                $($param::apply($param, _system_meta, _world);)*
1457            }
1458
1459            #[inline]
1460            fn queue(($($param,)*): &mut Self::State, _system_meta: &SystemMeta, mut _world: DeferredWorld) {
1461                $($param::queue($param, _system_meta, _world.reborrow());)*
1462            }
1463
1464            #[inline]
1465            #[allow(clippy::unused_unit)]
1466            unsafe fn get_param<'w, 's>(
1467                state: &'s mut Self::State,
1468                _system_meta: &SystemMeta,
1469                _world: UnsafeWorldCell<'w>,
1470                _change_tick: Tick,
1471            ) -> Self::Item<'w, 's> {
1472
1473                let ($($param,)*) = state;
1474                ($($param::get_param($param, _system_meta, _world, _change_tick),)*)
1475            }
1476        }
1477    };
1478}
1479
1480all_tuples!(impl_system_param_tuple, 0, 16, P);
1481
1482/// Contains type aliases for built-in [`SystemParam`]s with `'static` lifetimes.
1483/// This makes it more convenient to refer to these types in contexts where
1484/// explicit lifetime annotations are required.
1485///
1486/// Note that this is entirely safe and tracks lifetimes correctly.
1487/// This purely exists for convenience.
1488///
1489/// You can't instantiate a static `SystemParam`, you'll always end up with
1490/// `Res<'w, T>`, `ResMut<'w, T>` or `&'w T` bound to the lifetime of the provided
1491/// `&'w World`.
1492///
1493/// [`SystemParam`]: super::SystemParam
1494pub mod lifetimeless {
1495    /// A [`Query`](super::Query) with `'static` lifetimes.
1496    pub type SQuery<D, F = ()> = super::Query<'static, 'static, D, F>;
1497    /// A shorthand for writing `&'static T`.
1498    pub type Read<T> = &'static T;
1499    /// A shorthand for writing `&'static mut T`.
1500    pub type Write<T> = &'static mut T;
1501    /// A [`Res`](super::Res) with `'static` lifetimes.
1502    pub type SRes<T> = super::Res<'static, T>;
1503    /// A [`ResMut`](super::ResMut) with `'static` lifetimes.
1504    pub type SResMut<T> = super::ResMut<'static, T>;
1505    /// [`Commands`](crate::system::Commands) with `'static` lifetimes.
1506    pub type SCommands = crate::system::Commands<'static, 'static>;
1507}
1508
1509/// A helper for using system parameters in generic contexts
1510///
1511/// This type is a [`SystemParam`] adapter which always has
1512/// `Self::State::Item == Self` (ignoring lifetimes for brevity),
1513/// no matter the argument [`SystemParam`] (`P`) (other than
1514/// that `P` must be `'static`)
1515///
1516/// This makes it useful for having arbitrary [`SystemParam`] type arguments
1517/// to function systems, or for generic types using the [`derive@SystemParam`]
1518/// derive:
1519///
1520/// ```
1521/// # use bevy_ecs::prelude::*;
1522/// use bevy_ecs::system::{SystemParam, StaticSystemParam};
1523/// #[derive(SystemParam)]
1524/// struct GenericParam<'w,'s, T: SystemParam + 'static> {
1525///     field: StaticSystemParam<'w, 's, T>,
1526/// }
1527/// fn do_thing_generically<T: SystemParam + 'static>(t: StaticSystemParam<T>) {}
1528///
1529/// fn check_always_is_system<T: SystemParam + 'static>(){
1530///     bevy_ecs::system::assert_is_system(do_thing_generically::<T>);
1531/// }
1532/// ```
1533/// Note that in a real case you'd generally want
1534/// additional bounds on `P`, for your use of the parameter
1535/// to have a reason to be generic.
1536///
1537/// For example, using this would allow a type to be generic over
1538/// whether a resource is accessed mutably or not, with
1539/// impls being bounded on [`P: Deref<Target=MyType>`](Deref), and
1540/// [`P: DerefMut<Target=MyType>`](DerefMut) depending on whether the
1541/// method requires mutable access or not.
1542///
1543/// The method which doesn't use this type will not compile:
1544/// ```compile_fail
1545/// # use bevy_ecs::prelude::*;
1546/// # use bevy_ecs::system::{SystemParam, StaticSystemParam};
1547///
1548/// fn do_thing_generically<T: SystemParam + 'static>(t: T) {}
1549///
1550/// #[derive(SystemParam)]
1551/// struct GenericParam<'w, 's, T: SystemParam> {
1552///     field: T,
1553///     // Use the lifetimes in this type, or they will be unbound.
1554///     phantom: core::marker::PhantomData<&'w &'s ()>
1555/// }
1556/// # fn check_always_is_system<T: SystemParam + 'static>(){
1557/// #    bevy_ecs::system::assert_is_system(do_thing_generically::<T>);
1558/// # }
1559/// ```
1560///
1561pub struct StaticSystemParam<'w, 's, P: SystemParam>(SystemParamItem<'w, 's, P>);
1562
1563impl<'w, 's, P: SystemParam> Deref for StaticSystemParam<'w, 's, P> {
1564    type Target = SystemParamItem<'w, 's, P>;
1565
1566    fn deref(&self) -> &Self::Target {
1567        &self.0
1568    }
1569}
1570
1571impl<'w, 's, P: SystemParam> DerefMut for StaticSystemParam<'w, 's, P> {
1572    fn deref_mut(&mut self) -> &mut Self::Target {
1573        &mut self.0
1574    }
1575}
1576
1577impl<'w, 's, P: SystemParam> StaticSystemParam<'w, 's, P> {
1578    /// Get the value of the parameter
1579    pub fn into_inner(self) -> SystemParamItem<'w, 's, P> {
1580        self.0
1581    }
1582}
1583
1584// SAFETY: This doesn't add any more reads, and the delegated fetch confirms it
1585unsafe impl<'w, 's, P: ReadOnlySystemParam + 'static> ReadOnlySystemParam
1586    for StaticSystemParam<'w, 's, P>
1587{
1588}
1589
1590// SAFETY: all methods are just delegated to `P`'s `SystemParam` implementation
1591unsafe impl<P: SystemParam + 'static> SystemParam for StaticSystemParam<'_, '_, P> {
1592    type State = P::State;
1593    type Item<'world, 'state> = StaticSystemParam<'world, 'state, P>;
1594
1595    fn init_state(world: &mut World, system_meta: &mut SystemMeta) -> Self::State {
1596        P::init_state(world, system_meta)
1597    }
1598
1599    unsafe fn new_archetype(
1600        state: &mut Self::State,
1601        archetype: &Archetype,
1602        system_meta: &mut SystemMeta,
1603    ) {
1604        // SAFETY: The caller guarantees that the provided `archetype` matches the World used to initialize `state`.
1605        unsafe { P::new_archetype(state, archetype, system_meta) };
1606    }
1607
1608    fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World) {
1609        P::apply(state, system_meta, world);
1610    }
1611
1612    fn queue(state: &mut Self::State, system_meta: &SystemMeta, world: DeferredWorld) {
1613        P::queue(state, system_meta, world);
1614    }
1615
1616    unsafe fn get_param<'world, 'state>(
1617        state: &'state mut Self::State,
1618        system_meta: &SystemMeta,
1619        world: UnsafeWorldCell<'world>,
1620        change_tick: Tick,
1621    ) -> Self::Item<'world, 'state> {
1622        // SAFETY: Defer to the safety of P::SystemParam
1623        StaticSystemParam(unsafe { P::get_param(state, system_meta, world, change_tick) })
1624    }
1625}
1626
1627// SAFETY: No world access.
1628unsafe impl<T: ?Sized> SystemParam for PhantomData<T> {
1629    type State = ();
1630    type Item<'world, 'state> = Self;
1631
1632    fn init_state(_world: &mut World, _system_meta: &mut SystemMeta) -> Self::State {}
1633
1634    unsafe fn get_param<'world, 'state>(
1635        _state: &'state mut Self::State,
1636        _system_meta: &SystemMeta,
1637        _world: UnsafeWorldCell<'world>,
1638        _change_tick: Tick,
1639    ) -> Self::Item<'world, 'state> {
1640        PhantomData
1641    }
1642}
1643
1644// SAFETY: No world access.
1645unsafe impl<T: ?Sized> ReadOnlySystemParam for PhantomData<T> {}
1646
1647#[cfg(test)]
1648mod tests {
1649    use super::*;
1650    use crate::{
1651        self as bevy_ecs, // Necessary for the `SystemParam` Derive when used inside `bevy_ecs`.
1652        system::assert_is_system,
1653    };
1654    use std::cell::RefCell;
1655
1656    // Compile test for https://github.com/bevyengine/bevy/pull/2838.
1657    #[test]
1658    fn system_param_generic_bounds() {
1659        #[derive(SystemParam)]
1660        pub struct SpecialQuery<
1661            'w,
1662            's,
1663            D: QueryData + Send + Sync + 'static,
1664            F: QueryFilter + Send + Sync + 'static = (),
1665        > {
1666            _query: Query<'w, 's, D, F>,
1667        }
1668
1669        fn my_system(_: SpecialQuery<(), ()>) {}
1670        assert_is_system(my_system);
1671    }
1672
1673    // Compile tests for https://github.com/bevyengine/bevy/pull/6694.
1674    #[test]
1675    fn system_param_flexibility() {
1676        #[derive(SystemParam)]
1677        pub struct SpecialRes<'w, T: Resource> {
1678            _res: Res<'w, T>,
1679        }
1680
1681        #[derive(SystemParam)]
1682        pub struct SpecialLocal<'s, T: FromWorld + Send + 'static> {
1683            _local: Local<'s, T>,
1684        }
1685
1686        #[derive(Resource)]
1687        struct R;
1688
1689        fn my_system(_: SpecialRes<R>, _: SpecialLocal<u32>) {}
1690        assert_is_system(my_system);
1691    }
1692
1693    #[derive(Resource)]
1694    pub struct R<const I: usize>;
1695
1696    // Compile test for https://github.com/bevyengine/bevy/pull/7001.
1697    #[test]
1698    fn system_param_const_generics() {
1699        #[allow(dead_code)]
1700        #[derive(SystemParam)]
1701        pub struct ConstGenericParam<'w, const I: usize>(Res<'w, R<I>>);
1702
1703        fn my_system(_: ConstGenericParam<0>, _: ConstGenericParam<1000>) {}
1704        assert_is_system(my_system);
1705    }
1706
1707    // Compile test for https://github.com/bevyengine/bevy/pull/6867.
1708    #[test]
1709    fn system_param_field_limit() {
1710        #[derive(SystemParam)]
1711        pub struct LongParam<'w> {
1712            // Each field should be a distinct type so there will
1713            // be an error if the derive messes up the field order.
1714            _r0: Res<'w, R<0>>,
1715            _r1: Res<'w, R<1>>,
1716            _r2: Res<'w, R<2>>,
1717            _r3: Res<'w, R<3>>,
1718            _r4: Res<'w, R<4>>,
1719            _r5: Res<'w, R<5>>,
1720            _r6: Res<'w, R<6>>,
1721            _r7: Res<'w, R<7>>,
1722            _r8: Res<'w, R<8>>,
1723            _r9: Res<'w, R<9>>,
1724            _r10: Res<'w, R<10>>,
1725            _r11: Res<'w, R<11>>,
1726            _r12: Res<'w, R<12>>,
1727            _r13: Res<'w, R<13>>,
1728            _r14: Res<'w, R<14>>,
1729            _r15: Res<'w, R<15>>,
1730            _r16: Res<'w, R<16>>,
1731        }
1732
1733        fn long_system(_: LongParam) {}
1734        assert_is_system(long_system);
1735    }
1736
1737    // Compile test for https://github.com/bevyengine/bevy/pull/6919.
1738    // Regression test for https://github.com/bevyengine/bevy/issues/7447.
1739    #[test]
1740    fn system_param_phantom_data() {
1741        #[derive(SystemParam)]
1742        struct PhantomParam<'w, T: Resource, Marker: 'static> {
1743            _foo: Res<'w, T>,
1744            marker: PhantomData<&'w Marker>,
1745        }
1746
1747        fn my_system(_: PhantomParam<R<0>, ()>) {}
1748        assert_is_system(my_system);
1749    }
1750
1751    // Compile tests for https://github.com/bevyengine/bevy/pull/6957.
1752    #[test]
1753    fn system_param_struct_variants() {
1754        #[derive(SystemParam)]
1755        pub struct UnitParam;
1756
1757        #[allow(dead_code)]
1758        #[derive(SystemParam)]
1759        pub struct TupleParam<'w, 's, R: Resource, L: FromWorld + Send + 'static>(
1760            Res<'w, R>,
1761            Local<'s, L>,
1762        );
1763
1764        fn my_system(_: UnitParam, _: TupleParam<R<0>, u32>) {}
1765        assert_is_system(my_system);
1766    }
1767
1768    // Regression test for https://github.com/bevyengine/bevy/issues/4200.
1769    #[test]
1770    fn system_param_private_fields() {
1771        #[derive(Resource)]
1772        struct PrivateResource;
1773
1774        #[allow(dead_code)]
1775        #[derive(SystemParam)]
1776        pub struct EncapsulatedParam<'w>(Res<'w, PrivateResource>);
1777
1778        fn my_system(_: EncapsulatedParam) {}
1779        assert_is_system(my_system);
1780    }
1781
1782    // Regression test for https://github.com/bevyengine/bevy/issues/7103.
1783    #[test]
1784    fn system_param_where_clause() {
1785        #[derive(SystemParam)]
1786        pub struct WhereParam<'w, 's, D>
1787        where
1788            D: 'static + QueryData,
1789        {
1790            _q: Query<'w, 's, D, ()>,
1791        }
1792
1793        fn my_system(_: WhereParam<()>) {}
1794        assert_is_system(my_system);
1795    }
1796
1797    // Regression test for https://github.com/bevyengine/bevy/issues/1727.
1798    #[test]
1799    fn system_param_name_collision() {
1800        #[derive(Resource)]
1801        pub struct FetchState;
1802
1803        #[derive(SystemParam)]
1804        pub struct Collide<'w> {
1805            _x: Res<'w, FetchState>,
1806        }
1807
1808        fn my_system(_: Collide) {}
1809        assert_is_system(my_system);
1810    }
1811
1812    // Regression test for https://github.com/bevyengine/bevy/issues/8192.
1813    #[test]
1814    fn system_param_invariant_lifetime() {
1815        #[derive(SystemParam)]
1816        pub struct InvariantParam<'w, 's> {
1817            _set: ParamSet<'w, 's, (Query<'w, 's, ()>,)>,
1818        }
1819
1820        fn my_system(_: InvariantParam) {}
1821        assert_is_system(my_system);
1822    }
1823
1824    // Compile test for https://github.com/bevyengine/bevy/pull/9589.
1825    #[test]
1826    fn non_sync_local() {
1827        fn non_sync_system(cell: Local<RefCell<u8>>) {
1828            assert_eq!(*cell.borrow(), 0);
1829        }
1830
1831        let mut world = World::new();
1832        let mut schedule = crate::schedule::Schedule::default();
1833        schedule.add_systems(non_sync_system);
1834        schedule.run(&mut world);
1835    }
1836
1837    // Regression test for https://github.com/bevyengine/bevy/issues/10207.
1838    #[test]
1839    fn param_set_non_send_first() {
1840        fn non_send_param_set(mut p: ParamSet<(NonSend<*mut u8>, ())>) {
1841            let _ = p.p0();
1842            p.p1();
1843        }
1844
1845        let mut world = World::new();
1846        world.insert_non_send_resource(std::ptr::null_mut::<u8>());
1847        let mut schedule = crate::schedule::Schedule::default();
1848        schedule.add_systems((non_send_param_set, non_send_param_set, non_send_param_set));
1849        schedule.run(&mut world);
1850    }
1851
1852    // Regression test for https://github.com/bevyengine/bevy/issues/10207.
1853    #[test]
1854    fn param_set_non_send_second() {
1855        fn non_send_param_set(mut p: ParamSet<((), NonSendMut<*mut u8>)>) {
1856            p.p0();
1857            let _ = p.p1();
1858        }
1859
1860        let mut world = World::new();
1861        world.insert_non_send_resource(std::ptr::null_mut::<u8>());
1862        let mut schedule = crate::schedule::Schedule::default();
1863        schedule.add_systems((non_send_param_set, non_send_param_set, non_send_param_set));
1864        schedule.run(&mut world);
1865    }
1866}