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}