From 4fba03b529c30c32b5ac766e5f4b64cab8557760 Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Mon, 1 Jan 2024 16:02:21 +0000 Subject: [PATCH] impl ExclusiveSystemParam for PhantomData (#11153) # Objective Implement `ExclusiveSystemParam` for `PhantomData`. For the same reason `SystemParam` impl exists: to simplify writing generic code. https://github.com/bevyengine/bevy/blob/786abbf3f5e5be4b89c6b53d2d03162079f8e1f4/crates/bevy_ecs/src/system/system_param.rs#L1557 Also for consistency. ## Solution `impl ExclusiveSystemParam for PhantomData`. ## Changelog Added: PhantomData now implements ExclusiveSystemParam. --- .../src/system/exclusive_system_param.rs | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/crates/bevy_ecs/src/system/exclusive_system_param.rs b/crates/bevy_ecs/src/system/exclusive_system_param.rs index 2eb3c06941..3c356c9817 100644 --- a/crates/bevy_ecs/src/system/exclusive_system_param.rs +++ b/crates/bevy_ecs/src/system/exclusive_system_param.rs @@ -6,6 +6,7 @@ use crate::{ }; use bevy_utils::all_tuples; use bevy_utils::synccell::SyncCell; +use std::marker::PhantomData; /// A parameter that can be used in an exclusive system (a system with an `&mut World` parameter). /// Any parameters implementing this trait must come after the `&mut World` parameter. @@ -70,6 +71,17 @@ impl<'_s, T: FromWorld + Send + 'static> ExclusiveSystemParam for Local<'_s, T> } } +impl ExclusiveSystemParam for PhantomData { + type State = (); + type Item<'s> = PhantomData; + + fn init(_world: &mut World, _system_meta: &mut SystemMeta) -> Self::State {} + + fn get_param<'s>(_state: &'s mut Self::State, _system_meta: &SystemMeta) -> Self::Item<'s> { + PhantomData + } +} + macro_rules! impl_exclusive_system_param_tuple { ($($param: ident),*) => { #[allow(unused_variables)] @@ -98,3 +110,38 @@ macro_rules! impl_exclusive_system_param_tuple { } all_tuples!(impl_exclusive_system_param_tuple, 0, 16, P); + +#[cfg(test)] +mod tests { + use crate as bevy_ecs; + use crate::schedule::Schedule; + use crate::system::Local; + use crate::world::World; + use bevy_ecs_macros::Resource; + use std::marker::PhantomData; + + #[test] + fn test_exclusive_system_params() { + #[derive(Resource, Default)] + struct Res { + test_value: u32, + } + + fn my_system(world: &mut World, mut local: Local, _phantom: PhantomData>) { + assert_eq!(world.resource::().test_value, *local); + *local += 1; + world.resource_mut::().test_value += 1; + } + + let mut schedule = Schedule::default(); + schedule.add_systems(my_system); + + let mut world = World::default(); + world.init_resource::(); + + schedule.run(&mut world); + schedule.run(&mut world); + + assert_eq!(2, world.get_resource::().unwrap().test_value); + } +}