From d38a4db3d0c7157f1d9428fcfd1a9a1983dc865b Mon Sep 17 00:00:00 2001
From: JoJoJet <21144246+JoJoJet@users.noreply.github.com>
Date: Wed, 7 Dec 2022 08:12:05 -0500
Subject: [PATCH 01/49] simplify `Extract` bounds
---
crates/bevy_render/src/extract_param.rs | 10 ++--------
1 file changed, 2 insertions(+), 8 deletions(-)
diff --git a/crates/bevy_render/src/extract_param.rs b/crates/bevy_render/src/extract_param.rs
index b3d4ba665a55a..f854938d8e3a6 100644
--- a/crates/bevy_render/src/extract_param.rs
+++ b/crates/bevy_render/src/extract_param.rs
@@ -49,10 +49,7 @@ where
item: SystemParamItem<'w, 's, P>,
}
-impl<'w, 's, P> SystemParam for Extract<'w, 's, P>
-where
- P: ReadOnlySystemParam,
-{
+impl<'w, 's, P: ReadOnlySystemParam> SystemParam for Extract<'w, 's, P> {
type State = ExtractState
;
}
@@ -64,10 +61,7 @@ pub struct ExtractState {
// SAFETY: only accesses MainWorld resource with read only system params using ResState,
// which is initialized in init()
-unsafe impl SystemParamState for ExtractState
-where
- P: ReadOnlySystemParam + 'static,
-{
+unsafe impl SystemParamState for ExtractState {
type Item<'w, 's> = Extract<'w, 's, P>;
fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self {
From 5913ea0f14d5c23ac8089182868c83bd13c03914 Mon Sep 17 00:00:00 2001
From: JoJoJet <21144246+JoJoJet@users.noreply.github.com>
Date: Tue, 6 Dec 2022 19:01:52 -0500
Subject: [PATCH 02/49] flatten `SystemParam`
---
crates/bevy_ecs/macros/src/lib.rs | 112 +++--
.../src/system/commands/parallel_scope.rs | 23 +-
crates/bevy_ecs/src/system/function_system.rs | 27 +-
crates/bevy_ecs/src/system/system_param.rs | 411 ++++++++----------
crates/bevy_render/src/extract_param.rs | 43 +-
5 files changed, 271 insertions(+), 345 deletions(-)
diff --git a/crates/bevy_ecs/macros/src/lib.rs b/crates/bevy_ecs/macros/src/lib.rs
index 010a0e33108de..cc8533ff647a4 100644
--- a/crates/bevy_ecs/macros/src/lib.rs
+++ b/crates/bevy_ecs/macros/src/lib.rs
@@ -216,7 +216,6 @@ pub fn impl_param_set(_input: TokenStream) -> TokenStream {
let mut tokens = TokenStream::new();
let max_params = 8;
let params = get_idents(|i| format!("P{i}"), max_params);
- let params_state = get_idents(|i| format!("PF{i}"), max_params);
let metas = get_idents(|i| format!("m{i}"), max_params);
let mut param_fn_muts = Vec::new();
for (i, param) in params.iter().enumerate() {
@@ -228,7 +227,7 @@ pub fn impl_param_set(_input: TokenStream) -> TokenStream {
// Conflicting params in ParamSet are not accessible at the same time
// ParamSets are guaranteed to not conflict with other SystemParams
unsafe {
- <#param::State as SystemParamState>::get_param(&mut self.param_states.#index, &self.system_meta, self.world, self.change_tick)
+ <#param as SystemParam>::get_param(&mut self.param_states.#index, &self.system_meta, self.world, self.change_tick)
}
}
});
@@ -236,36 +235,25 @@ pub fn impl_param_set(_input: TokenStream) -> TokenStream {
for param_count in 1..=max_params {
let param = ¶ms[0..param_count];
- let param_state = ¶ms_state[0..param_count];
let meta = &metas[0..param_count];
let param_fn_mut = ¶m_fn_muts[0..param_count];
tokens.extend(TokenStream::from(quote! {
- impl<'w, 's, #(#param: SystemParam,)*> SystemParam for ParamSet<'w, 's, (#(#param,)*)>
+ unsafe impl<'_w, '_s, #(#param: SystemParam,)*> SystemParam for ParamSet<'_w, '_s, (#(#param,)*)>
+ where #(
+ for<'w, 's> #param::Item::<'w, 's>: SystemParam,
+ )*
{
type State = ParamSetState<(#(#param::State,)*)>;
- }
-
- // SAFETY: All parameters are constrained to ReadOnlyState, so World is only read
-
- unsafe impl<'w, 's, #(#param,)*> ReadOnlySystemParam for ParamSet<'w, 's, (#(#param,)*)>
- where #(#param: ReadOnlySystemParam,)*
- { }
-
- // SAFETY: Relevant parameter ComponentId and ArchetypeComponentId access is applied to SystemMeta. If any ParamState conflicts
- // with any prior access, a panic will occur.
-
- unsafe impl<#(#param_state: SystemParamState,)*> SystemParamState for ParamSetState<(#(#param_state,)*)>
- {
- type Item<'w, 's> = ParamSet<'w, 's, (#(<#param_state as SystemParamState>::Item::<'w, 's>,)*)>;
+ type Item<'w, 's> = ParamSet<'w, 's, (#(#param::Item<'w, 's>,)*)>;
- fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self {
+ fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self::State {
#(
// Pretend to add each param to the system alone, see if it conflicts
let mut #meta = system_meta.clone();
#meta.component_access_set.clear();
#meta.archetype_component_access.clear();
- #param_state::init(world, &mut #meta);
- let #param = #param_state::init(world, &mut system_meta.clone());
+ #param::init(world, &mut #meta);
+ let #param = #param::init(world, &mut system_meta.clone());
)*
#(
system_meta
@@ -278,20 +266,20 @@ pub fn impl_param_set(_input: TokenStream) -> TokenStream {
ParamSetState((#(#param,)*))
}
- fn new_archetype(&mut self, archetype: &Archetype, system_meta: &mut SystemMeta) {
- let (#(#param,)*) = &mut self.0;
+ fn new_archetype(state: &mut Self::State, archetype: &Archetype, system_meta: &mut SystemMeta) {
+ let (#(#param,)*) = &mut state.0;
#(
- #param.new_archetype(archetype, system_meta);
+ <#param as SystemParam>::new_archetype(#param, archetype, system_meta);
)*
}
- fn apply(&mut self, world: &mut World) {
- self.0.apply(world)
+ fn apply(state: &mut Self::State, world: &mut World) {
+ <(#(#param,)*)>::apply(&mut state.0, world);
}
#[inline]
unsafe fn get_param<'w, 's>(
- state: &'s mut Self,
+ state: &'s mut Self::State,
system_meta: &SystemMeta,
world: &'w World,
change_tick: u32,
@@ -305,9 +293,13 @@ pub fn impl_param_set(_input: TokenStream) -> TokenStream {
}
}
+ // SAFETY: All parameters are constrained to ReadOnlyState, so World is only read
+ unsafe impl<'w, 's, #(#param,)*> ReadOnlySystemParam for ParamSet<'w, 's, (#(#param,)*)>
+ where #(#param: ReadOnlySystemParam,)*
+ { }
+
impl<'w, 's, #(#param: SystemParam,)*> ParamSet<'w, 's, (#(#param,)*)>
{
-
#(#param_fn_mut)*
}
}));
@@ -401,6 +393,12 @@ pub fn derive_system_param(input: TokenStream) -> TokenStream {
.filter(|g| matches!(g, GenericParam::Type(_)))
.collect();
+ let mut shadowed_lifetimes: Vec<_> = generics.lifetimes().map(|x| x.lifetime.clone()).collect();
+ for lifetime in &mut shadowed_lifetimes {
+ let shadowed_ident = format_ident!("_{}", lifetime.ident);
+ lifetime.ident = shadowed_ident;
+ }
+
let mut punctuated_generics = Punctuated::<_, Token![,]>::new();
punctuated_generics.extend(lifetimeless_generics.iter().map(|g| match g {
GenericParam::Type(g) => GenericParam::Type(TypeParam {
@@ -434,56 +432,56 @@ pub fn derive_system_param(input: TokenStream) -> TokenStream {
// The struct can still be accessed via SystemParam::State, e.g. EventReaderState can be accessed via
// as SystemParam>::State
const _: () = {
- impl<'w, 's, #punctuated_generics> #path::system::SystemParam for #struct_name #ty_generics #where_clause {
- type State = State<'w, 's, #punctuated_generic_idents>;
- }
-
- #[doc(hidden)]
- type State<'w, 's, #punctuated_generic_idents> = FetchState<
- (#(<#field_types as #path::system::SystemParam>::State,)*),
- #punctuated_generic_idents
- >;
-
- #[doc(hidden)]
- #state_struct_visibility struct FetchState {
- state: TSystemParamState,
- marker: std::marker::PhantomData(#punctuated_generic_idents)>
- }
-
- unsafe impl<'__w, '__s, #punctuated_generics> #path::system::SystemParamState for
- State<'__w, '__s, #punctuated_generic_idents>
- #where_clause {
+ unsafe impl<'_w, '_s, #punctuated_generics> #path::system::SystemParam for #struct_name <#(#shadowed_lifetimes,)* #punctuated_generic_idents> #where_clause {
+ type State = State<'_w, '_s, #punctuated_generic_idents>;
type Item<'w, 's> = #struct_name #ty_generics;
- fn init(world: &mut #path::world::World, system_meta: &mut #path::system::SystemMeta) -> Self {
- Self {
- state: #path::system::SystemParamState::init(world, system_meta),
+ fn init(world: &mut #path::world::World, system_meta: &mut #path::system::SystemMeta) -> Self::State {
+ FetchState {
+ state: >::init(world, system_meta),
marker: std::marker::PhantomData,
}
}
- fn new_archetype(&mut self, archetype: path::archetype::Archetype, system_meta: &mut #path::system::SystemMeta) {
- self.state.new_archetype(archetype, system_meta)
+ fn new_archetype(state: &mut Self::State, archetype: path::archetype::Archetype, system_meta: &mut #path::system::SystemMeta) {
+ >::new_archetype(&mut state.state, archetype, system_meta)
}
- fn apply(&mut self, world: &mut #path::world::World) {
- self.state.apply(world)
+ fn apply(state: &mut Self::State, world: &mut #path::world::World) {
+ >::apply(&mut state.state, world);
}
unsafe fn get_param<'w, 's>(
- state: &'s mut Self,
+ state: &'s mut Self::State,
system_meta: path::system::SystemMeta,
world: &'w #path::world::World,
change_tick: u32,
) -> Self::Item<'w, 's> {
#struct_name {
- #(#fields: <<#field_types as #path::system::SystemParam>::State as #path::system::SystemParamState>::get_param(&mut state.state.#field_indices, system_meta, world, change_tick),)*
+ #(#fields: <#field_types as #path::system::SystemParam>::get_param(&mut state.state.#field_indices, system_meta, world, change_tick),)*
#(#ignored_fields: <#ignored_field_types>::default(),)*
}
}
}
- // Safety: Each field is `ReadOnlySystemParam`, so this can only read from the `World`
+ #[doc(hidden)]
+ type State<'w, 's, #punctuated_generic_idents> = FetchState<
+ (#(<#field_types as #path::system::SystemParam>::State,)*),
+ #punctuated_generic_idents
+ >;
+
+ #[doc(hidden)]
+ type FieldsTuple<'w, 's, #punctuated_generic_idents> = (
+ #(#field_types,)*
+ );
+
+ #[doc(hidden)]
+ #state_struct_visibility struct FetchState {
+ state: TSystemParamState,
+ marker: std::marker::PhantomData(#punctuated_generic_idents)>
+ }
+
+ // Safety: The `ParamState` is `ReadOnlySystemParam`, so this can only read from the `World`
unsafe impl<'w, 's, #punctuated_generics> #path::system::ReadOnlySystemParam for #struct_name #ty_generics #read_only_where_clause {}
};
})
diff --git a/crates/bevy_ecs/src/system/commands/parallel_scope.rs b/crates/bevy_ecs/src/system/commands/parallel_scope.rs
index 5fccd74228061..c980b81546d39 100644
--- a/crates/bevy_ecs/src/system/commands/parallel_scope.rs
+++ b/crates/bevy_ecs/src/system/commands/parallel_scope.rs
@@ -2,11 +2,7 @@ use std::cell::Cell;
use thread_local::ThreadLocal;
-use crate::{
- entity::Entities,
- prelude::World,
- system::{SystemParam, SystemParamState},
-};
+use crate::{entity::Entities, prelude::World, system::SystemParam};
use super::{CommandQueue, Commands};
@@ -48,26 +44,23 @@ pub struct ParallelCommands<'w, 's> {
entities: &'w Entities,
}
-impl SystemParam for ParallelCommands<'_, '_> {
- type State = ParallelCommandsState;
-}
-
// SAFETY: no component or resource access to report
-unsafe impl SystemParamState for ParallelCommandsState {
+unsafe impl SystemParam for ParallelCommands<'_, '_> {
+ type State = ParallelCommandsState;
type Item<'w, 's> = ParallelCommands<'w, 's>;
- fn init(_: &mut World, _: &mut crate::system::SystemMeta) -> Self {
- Self::default()
+ fn init(_: &mut World, _: &mut crate::system::SystemMeta) -> Self::State {
+ ParallelCommandsState::default()
}
- fn apply(&mut self, world: &mut World) {
- for cq in &mut self.thread_local_storage {
+ fn apply(state: &mut Self::State, world: &mut World) {
+ for cq in &mut state.thread_local_storage {
cq.get_mut().apply(world);
}
}
unsafe fn get_param<'w, 's>(
- state: &'s mut Self,
+ state: &'s mut Self::State,
_: &crate::system::SystemMeta,
world: &'w World,
_: u32,
diff --git a/crates/bevy_ecs/src/system/function_system.rs b/crates/bevy_ecs/src/system/function_system.rs
index 3a4c9006ae6d6..b5ae963bb23ac 100644
--- a/crates/bevy_ecs/src/system/function_system.rs
+++ b/crates/bevy_ecs/src/system/function_system.rs
@@ -5,10 +5,7 @@ use crate::{
prelude::FromWorld,
query::{Access, FilteredAccessSet},
schedule::{SystemLabel, SystemLabelId},
- system::{
- check_system_change_tick, ReadOnlySystemParam, System, SystemParam, SystemParamItem,
- SystemParamState,
- },
+ system::{check_system_change_tick, ReadOnlySystemParam, System, SystemParam, SystemParamItem},
world::{World, WorldId},
};
use bevy_ecs_macros::all_tuples;
@@ -144,7 +141,7 @@ impl SystemState {
pub fn new(world: &mut World) -> Self {
let mut meta = SystemMeta::new::();
meta.last_change_tick = world.change_tick().wrapping_sub(MAX_CHANGE_AGE);
- let param_state = ::init(world, &mut meta);
+ let param_state = ::init(world, &mut meta);
Self {
meta,
param_state,
@@ -182,7 +179,7 @@ impl SystemState {
/// This function should be called manually after the values returned by [`SystemState::get`] and [`SystemState::get_mut`]
/// are finished being used.
pub fn apply(&mut self, world: &mut World) {
- self.param_state.apply(world);
+ Param::apply(&mut self.param_state, world);
}
#[inline]
@@ -198,7 +195,8 @@ impl SystemState {
let archetype_index_range = old_generation.value()..new_generation.value();
for archetype_index in archetype_index_range {
- self.param_state.new_archetype(
+ Param::new_archetype(
+ &mut self.param_state,
&archetypes[ArchetypeId::new(archetype_index)],
&mut self.meta,
);
@@ -217,7 +215,7 @@ impl SystemState {
world: &'w World,
) -> SystemParamItem<'w, 's, Param> {
let change_tick = world.increment_change_tick();
- let param = ::get_param(
+ let param = ::get_param(
&mut self.param_state,
&self.meta,
world,
@@ -394,7 +392,7 @@ where
// We update the archetype component access correctly based on `Param`'s requirements
// in `update_archetype_component_access`.
// Our caller upholds the requirements.
- let params = ::State::get_param(
+ let params = ::get_param(
self.param_state.as_mut().expect(Self::PARAM_MESSAGE),
&self.system_meta,
world,
@@ -416,17 +414,14 @@ where
#[inline]
fn apply_buffers(&mut self, world: &mut World) {
let param_state = self.param_state.as_mut().expect(Self::PARAM_MESSAGE);
- param_state.apply(world);
+ Param::apply(param_state, world);
}
#[inline]
fn initialize(&mut self, world: &mut World) {
self.world_id = Some(world.id());
self.system_meta.last_change_tick = world.change_tick().wrapping_sub(MAX_CHANGE_AGE);
- self.param_state = Some(::init(
- world,
- &mut self.system_meta,
- ));
+ self.param_state = Some(::init(world, &mut self.system_meta));
}
fn update_archetype_component_access(&mut self, world: &World) {
@@ -437,7 +432,9 @@ where
let archetype_index_range = old_generation.value()..new_generation.value();
for archetype_index in archetype_index_range {
- self.param_state.as_mut().unwrap().new_archetype(
+ let param_state = self.param_state.as_mut().unwrap();
+ Param::new_archetype(
+ param_state,
&archetypes[ArchetypeId::new(archetype_index)],
&mut self.system_meta,
);
diff --git a/crates/bevy_ecs/src/system/system_param.rs b/crates/bevy_ecs/src/system/system_param.rs
index c9ef8ab840eb3..2537462bf3dfc 100644
--- a/crates/bevy_ecs/src/system/system_param.rs
+++ b/crates/bevy_ecs/src/system/system_param.rs
@@ -121,13 +121,6 @@ use std::{
///
/// [`SyncCell`]: bevy_utils::synccell::SyncCell
/// [`Exclusive`]: https://doc.rust-lang.org/nightly/std/sync/struct.Exclusive.html
-pub trait SystemParam: Sized {
- type State: SystemParamState;
-}
-
-pub type SystemParamItem<'w, 's, P> = <::State as SystemParamState>::Item<'w, 's>;
-
-/// The state of a [`SystemParam`].
///
/// # Safety
///
@@ -135,20 +128,29 @@ pub type SystemParamItem<'w, 's, P> = <
::State as SystemParamS
/// [`World`] access used by the [`SystemParamState`].
/// Additionally, it is the implementor's responsibility to ensure there is no
/// conflicting access across all [`SystemParam`]'s.
-pub unsafe trait SystemParamState: Send + Sync + 'static {
- fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self;
+pub unsafe trait SystemParam: Sized {
+ type State: Send + Sync + 'static;
+ type Item<'world, 'state>;
+
+ fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self::State;
+
#[inline]
- fn new_archetype(&mut self, _archetype: &Archetype, _system_meta: &mut SystemMeta) {}
+ fn new_archetype(
+ _state: &mut Self::State,
+ _archetype: &Archetype,
+ _system_meta: &mut SystemMeta,
+ ) {
+ }
+
#[inline]
- fn apply(&mut self, _world: &mut World) {}
+ fn apply(_state: &mut Self::State, _world: &mut World) {}
- type Item<'world, 'state>: SystemParam;
/// # Safety
///
/// This call might access any of the input parameters in an unsafe way. Make sure the data
/// access is safe in the context of the system scheduler.
unsafe fn get_param<'world, 'state>(
- state: &'state mut Self,
+ state: &'state mut Self::State,
system_meta: &SystemMeta,
world: &'world World,
change_tick: u32,
@@ -161,11 +163,7 @@ pub unsafe trait SystemParamState: Send + Sync + 'static {
/// This must only be implemented for [`SystemParam`] impls that exclusively read the World passed in to [`SystemParamState::get_param`]
pub unsafe trait ReadOnlySystemParam: SystemParam {}
-impl<'w, 's, Q: WorldQuery + 'static, F: ReadOnlyWorldQuery + 'static> SystemParam
- for Query<'w, 's, Q, F>
-{
- type State = QueryState;
-}
+pub type SystemParamItem<'w, 's, P> = ::Item<'w, 's>;
// SAFETY: QueryState is constrained to read-only fetches, so it only reads World.
unsafe impl<'w, 's, Q: ReadOnlyWorldQuery + 'static, F: ReadOnlyWorldQuery + 'static>
@@ -173,14 +171,14 @@ unsafe impl<'w, 's, Q: ReadOnlyWorldQuery + 'static, F: ReadOnlyWorldQuery + 'st
{
}
-// SAFETY: Relevant query ComponentId and ArchetypeComponentId access is applied to SystemMeta. If
-// this QueryState conflicts with any prior access, a panic will occur.
-unsafe impl SystemParamState
- for QueryState
+// SAFETY: QueryState is constrained to read-only fetches, so it only reads World.
+unsafe impl<'_w, '_s, Q: WorldQuery + 'static, F: ReadOnlyWorldQuery + 'static> SystemParam
+ for Query<'_w, '_s, Q, F>
{
+ type State = QueryState;
type Item<'w, 's> = Query<'w, 's, Q, F>;
- fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self {
+ fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self::State {
let state = QueryState::new(world);
assert_component_access_compatibility(
&system_meta.name,
@@ -199,16 +197,16 @@ unsafe impl SystemPara
state
}
- fn new_archetype(&mut self, archetype: &Archetype, system_meta: &mut SystemMeta) {
- self.new_archetype(archetype);
+ fn new_archetype(state: &mut Self::State, archetype: &Archetype, system_meta: &mut SystemMeta) {
+ state.new_archetype(archetype);
system_meta
.archetype_component_access
- .extend(&self.archetype_component_access);
+ .extend(&state.archetype_component_access);
}
#[inline]
unsafe fn get_param<'w, 's>(
- state: &'s mut Self,
+ state: &'s mut Self::State,
system_meta: &SystemMeta,
world: &'w World,
change_tick: u32,
@@ -245,7 +243,7 @@ pub struct ParamSet<'w, 's, T: SystemParam> {
change_tick: u32,
}
/// The [`SystemParamState`] of [`ParamSet`].
-pub struct ParamSetState(T);
+pub struct ParamSetState(T);
impl_param_set!();
@@ -301,9 +299,6 @@ pub struct Res<'w, T: Resource> {
change_tick: u32,
}
-// SAFETY: Res only reads a single World resource
-unsafe impl<'w, T: Resource> ReadOnlySystemParam for Res<'w, T> {}
-
impl<'w, T: Resource> Debug for Res<'w, T>
where
T: Debug,
@@ -389,16 +384,16 @@ pub struct ResState {
marker: PhantomData,
}
-impl<'a, T: Resource> SystemParam for Res<'a, T> {
- type State = ResState;
-}
+// SAFETY: Res only reads a single World resource
+unsafe impl<'a, T: Resource> ReadOnlySystemParam for Res<'a, T> {}
// SAFETY: Res ComponentId and ArchetypeComponentId access is applied to SystemMeta. If this Res
// conflicts with any prior access, a panic will occur.
-unsafe impl SystemParamState for ResState {
+unsafe impl<'a, T: Resource> SystemParam for Res<'a, T> {
+ type State = ResState;
type Item<'w, 's> = Res<'w, T>;
- fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self {
+ fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self::State {
let component_id = world.initialize_resource::();
let combined_access = system_meta.component_access_set.combined_access();
assert!(
@@ -417,7 +412,7 @@ unsafe impl SystemParamState for ResState {
system_meta
.archetype_component_access
.add_read(archetype_component_id);
- Self {
+ ResState {
component_id,
marker: PhantomData,
}
@@ -425,7 +420,7 @@ unsafe impl SystemParamState for ResState {
#[inline]
unsafe fn get_param<'w, 's>(
- state: &'s mut Self,
+ state: &'s mut Self::State,
system_meta: &SystemMeta,
world: &'w World,
change_tick: u32,
@@ -454,25 +449,22 @@ unsafe impl SystemParamState for ResState {
#[doc(hidden)]
pub struct OptionResState(ResState);
-impl<'a, T: Resource> SystemParam for Option> {
- type State = OptionResState;
-}
-
// SAFETY: Only reads a single World resource
unsafe impl<'a, T: Resource> ReadOnlySystemParam for Option> {}
// SAFETY: this impl defers to `ResState`, which initializes
// and validates the correct world access
-unsafe impl SystemParamState for OptionResState {
+unsafe impl<'a, T: Resource> SystemParam for Option> {
+ type State = OptionResState;
type Item<'w, 's> = Option>;
- fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self {
- Self(ResState::init(world, system_meta))
+ fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self::State {
+ OptionResState(Res::init(world, system_meta))
}
#[inline]
unsafe fn get_param<'w, 's>(
- state: &'s mut Self,
+ state: &'s mut Self::State,
system_meta: &SystemMeta,
world: &'w World,
change_tick: u32,
@@ -496,16 +488,13 @@ pub struct ResMutState {
marker: PhantomData,
}
-impl<'a, T: Resource> SystemParam for ResMut<'a, T> {
- type State = ResMutState;
-}
-
// SAFETY: Res ComponentId and ArchetypeComponentId access is applied to SystemMeta. If this Res
// conflicts with any prior access, a panic will occur.
-unsafe impl SystemParamState for ResMutState {
+unsafe impl<'a, T: Resource> SystemParam for ResMut<'a, T> {
+ type State = ResMutState;
type Item<'w, 's> = ResMut<'w, T>;
- fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self {
+ fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self::State {
let component_id = world.initialize_resource::();
let combined_access = system_meta.component_access_set.combined_access();
if combined_access.has_write(component_id) {
@@ -527,7 +516,7 @@ unsafe impl SystemParamState for ResMutState {
system_meta
.archetype_component_access
.add_write(archetype_component_id);
- Self {
+ ResMutState {
component_id,
marker: PhantomData,
}
@@ -535,7 +524,7 @@ unsafe impl SystemParamState for ResMutState {
#[inline]
unsafe fn get_param<'w, 's>(
- state: &'s mut Self,
+ state: &'s mut Self::State,
system_meta: &SystemMeta,
world: &'w World,
change_tick: u32,
@@ -566,22 +555,19 @@ unsafe impl SystemParamState for ResMutState {
#[doc(hidden)]
pub struct OptionResMutState(ResMutState);
-impl<'a, T: Resource> SystemParam for Option> {
- type State = OptionResMutState;
-}
-
// SAFETY: this impl defers to `ResMutState`, which initializes
// and validates the correct world access
-unsafe impl SystemParamState for OptionResMutState {
+unsafe impl<'a, T: Resource> SystemParam for Option> {
+ type State = OptionResMutState;
type Item<'w, 's> = Option>;
- fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self {
- Self(ResMutState::init(world, system_meta))
+ fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self::State {
+ OptionResMutState(ResMut::init(world, system_meta))
}
#[inline]
unsafe fn get_param<'w, 's>(
- state: &'s mut Self,
+ state: &'s mut Self::State,
system_meta: &SystemMeta,
world: &'w World,
change_tick: u32,
@@ -600,28 +586,25 @@ unsafe impl SystemParamState for OptionResMutState {
}
}
-impl<'w, 's> SystemParam for Commands<'w, 's> {
- type State = CommandQueue;
-}
-
// SAFETY: Commands only accesses internal state
unsafe impl<'w, 's> ReadOnlySystemParam for Commands<'w, 's> {}
// SAFETY: only local state is accessed
-unsafe impl SystemParamState for CommandQueue {
+unsafe impl<'_w, '_s> SystemParam for Commands<'_w, '_s> {
+ type State = CommandQueue;
type Item<'w, 's> = Commands<'w, 's>;
- fn init(_world: &mut World, _system_meta: &mut SystemMeta) -> Self {
+ fn init(_world: &mut World, _system_meta: &mut SystemMeta) -> Self::State {
Default::default()
}
- fn apply(&mut self, world: &mut World) {
- self.apply(world);
+ fn apply(state: &mut Self::State, world: &mut World) {
+ state.apply(world);
}
#[inline]
unsafe fn get_param<'w, 's>(
- state: &'s mut Self,
+ state: &'s mut Self::State,
_system_meta: &SystemMeta,
world: &'w World,
_change_tick: u32,
@@ -637,15 +620,12 @@ unsafe impl<'w> ReadOnlySystemParam for &'w World {}
#[doc(hidden)]
pub struct WorldState;
-impl<'w> SystemParam for &'w World {
- type State = WorldState;
-}
-
// SAFETY: `read_all` access is set and conflicts result in a panic
-unsafe impl SystemParamState for WorldState {
+unsafe impl<'_w> SystemParam for &'_w World {
+ type State = WorldState;
type Item<'w, 's> = &'w World;
- fn init(_world: &mut World, system_meta: &mut SystemMeta) -> Self {
+ fn init(_world: &mut World, system_meta: &mut SystemMeta) -> Self::State {
let mut access = Access::default();
access.read_all();
if !system_meta
@@ -672,7 +652,7 @@ unsafe impl SystemParamState for WorldState {
}
unsafe fn get_param<'w, 's>(
- _state: &'s mut Self,
+ _state: &'s mut Self::State,
_system_meta: &SystemMeta,
world: &'w World,
_change_tick: u32,
@@ -782,21 +762,18 @@ where
#[doc(hidden)]
pub struct LocalState(pub(crate) SyncCell);
-impl<'a, T: FromWorld + Send + 'static> SystemParam for Local<'a, T> {
- type State = LocalState;
-}
-
// SAFETY: only local state is accessed
-unsafe impl SystemParamState for LocalState {
+unsafe impl<'a, T: FromWorld + Send + 'static> SystemParam for Local<'a, T> {
+ type State = LocalState;
type Item<'w, 's> = Local<'s, T>;
- fn init(world: &mut World, _system_meta: &mut SystemMeta) -> Self {
- Self(SyncCell::new(T::from_world(world)))
+ fn init(world: &mut World, _system_meta: &mut SystemMeta) -> Self::State {
+ LocalState(SyncCell::new(T::from_world(world)))
}
#[inline]
unsafe fn get_param<'w, 's>(
- state: &'s mut Self,
+ state: &'s mut Self::State,
_system_meta: &SystemMeta,
_world: &'w World,
_change_tick: u32,
@@ -870,17 +847,14 @@ pub struct RemovedComponentsState {
marker: PhantomData,
}
-impl<'a, T: Component> SystemParam for RemovedComponents<'a, T> {
- type State = RemovedComponentsState;
-}
-
// SAFETY: no component access. removed component entity collections can be read in parallel and are
// never mutably borrowed during system execution
-unsafe impl SystemParamState for RemovedComponentsState {
+unsafe impl<'a, T: Component> SystemParam for RemovedComponents<'a, T> {
+ type State = RemovedComponentsState;
type Item<'w, 's> = RemovedComponents<'w, T>;
- fn init(world: &mut World, _system_meta: &mut SystemMeta) -> Self {
- Self {
+ fn init(world: &mut World, _system_meta: &mut SystemMeta) -> Self::State {
+ RemovedComponentsState {
component_id: world.init_component::(),
marker: PhantomData,
}
@@ -888,7 +862,7 @@ unsafe impl SystemParamState for RemovedComponentsState {
#[inline]
unsafe fn get_param<'w, 's>(
- state: &'s mut Self,
+ state: &'s mut Self::State,
_system_meta: &SystemMeta,
world: &'w World,
_change_tick: u32,
@@ -973,16 +947,13 @@ pub struct NonSendState {
marker: PhantomData T>,
}
-impl<'a, T: 'static> SystemParam for NonSend<'a, T> {
- type State = NonSendState;
-}
-
// SAFETY: NonSendComponentId and ArchetypeComponentId access is applied to SystemMeta. If this
// NonSend conflicts with any prior access, a panic will occur.
-unsafe impl SystemParamState for NonSendState {
+unsafe impl<'a, T: 'static> SystemParam for NonSend<'a, T> {
+ type State = NonSendState;
type Item<'w, 's> = NonSend<'w, T>;
- fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self {
+ fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self::State {
system_meta.set_non_send();
let component_id = world.initialize_non_send_resource::();
@@ -1003,7 +974,7 @@ unsafe impl SystemParamState for NonSendState {
system_meta
.archetype_component_access
.add_read(archetype_component_id);
- Self {
+ NonSendState {
component_id,
marker: PhantomData,
}
@@ -1011,7 +982,7 @@ unsafe impl SystemParamState for NonSendState {
#[inline]
unsafe fn get_param<'w, 's>(
- state: &'s mut Self,
+ state: &'s mut Self::State,
system_meta: &SystemMeta,
world: &'w World,
change_tick: u32,
@@ -1041,25 +1012,22 @@ unsafe impl SystemParamState for NonSendState {
#[doc(hidden)]
pub struct OptionNonSendState(NonSendState);
-impl<'w, T: 'static> SystemParam for Option> {
- type State = OptionNonSendState;
-}
-
// SAFETY: Only reads a single non-send resource
unsafe impl<'w, T: 'static> ReadOnlySystemParam for Option> {}
// SAFETY: this impl defers to `NonSendState`, which initializes
// and validates the correct world access
-unsafe impl SystemParamState for OptionNonSendState {
+unsafe impl<'_w, T: 'static> SystemParam for Option> {
+ type State = OptionNonSendState;
type Item<'w, 's> = Option>;
- fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self {
- Self(NonSendState::init(world, system_meta))
+ fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self::State {
+ OptionNonSendState(NonSend::init(world, system_meta))
}
#[inline]
unsafe fn get_param<'w, 's>(
- state: &'s mut Self,
+ state: &'s mut Self::State,
system_meta: &SystemMeta,
world: &'w World,
change_tick: u32,
@@ -1076,6 +1044,9 @@ unsafe impl SystemParamState for OptionNonSendState {
}
}
+// SAFETY: Only reads a single non-send resource
+unsafe impl<'a, T: 'static> ReadOnlySystemParam for NonSendMut<'a, T> {}
+
/// The [`SystemParamState`] of [`NonSendMut`].
#[doc(hidden)]
pub struct NonSendMutState {
@@ -1083,16 +1054,13 @@ pub struct NonSendMutState {
marker: PhantomData T>,
}
-impl<'a, T: 'static> SystemParam for NonSendMut<'a, T> {
- type State = NonSendMutState;
-}
-
// SAFETY: NonSendMut ComponentId and ArchetypeComponentId access is applied to SystemMeta. If this
// NonSendMut conflicts with any prior access, a panic will occur.
-unsafe impl SystemParamState for NonSendMutState {
+unsafe impl<'a, T: 'static> SystemParam for NonSendMut<'a, T> {
+ type State = NonSendMutState;
type Item<'w, 's> = NonSendMut<'w, T>;
- fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self {
+ fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self::State {
system_meta.set_non_send();
let component_id = world.initialize_non_send_resource::();
@@ -1116,7 +1084,7 @@ unsafe impl SystemParamState for NonSendMutState {
system_meta
.archetype_component_access
.add_write(archetype_component_id);
- Self {
+ NonSendMutState {
component_id,
marker: PhantomData,
}
@@ -1124,7 +1092,7 @@ unsafe impl SystemParamState for NonSendMutState {
#[inline]
unsafe fn get_param<'w, 's>(
- state: &'s mut Self,
+ state: &'s mut Self::State,
system_meta: &SystemMeta,
world: &'w World,
change_tick: u32,
@@ -1151,22 +1119,19 @@ unsafe impl SystemParamState for NonSendMutState {
#[doc(hidden)]
pub struct OptionNonSendMutState(NonSendMutState);
-impl<'a, T: 'static> SystemParam for Option> {
- type State = OptionNonSendMutState;
-}
-
// SAFETY: this impl defers to `NonSendMutState`, which initializes
// and validates the correct world access
-unsafe impl SystemParamState for OptionNonSendMutState {
+unsafe impl<'a, T: 'static> SystemParam for Option> {
+ type State = OptionNonSendMutState;
type Item<'w, 's> = Option>;
- fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self {
- Self(NonSendMutState::init(world, system_meta))
+ fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self::State {
+ OptionNonSendMutState(NonSendMut::init(world, system_meta))
}
#[inline]
unsafe fn get_param<'w, 's>(
- state: &'s mut Self,
+ state: &'s mut Self::State,
system_meta: &SystemMeta,
world: &'w World,
change_tick: u32,
@@ -1181,8 +1146,24 @@ unsafe impl SystemParamState for OptionNonSendMutState {
}
}
-impl<'a> SystemParam for &'a Archetypes {
+// SAFETY: no component value access
+unsafe impl<'a> SystemParam for &'a Archetypes {
type State = ArchetypesState;
+ type Item<'w, 's> = &'w Archetypes;
+
+ fn init(_world: &mut World, _system_meta: &mut SystemMeta) -> Self::State {
+ ArchetypesState
+ }
+
+ #[inline]
+ unsafe fn get_param<'w, 's>(
+ _state: &'s mut Self::State,
+ _system_meta: &SystemMeta,
+ world: &'w World,
+ _change_tick: u32,
+ ) -> Self::Item<'w, 's> {
+ world.archetypes()
+ }
}
// SAFETY: Only reads World archetypes
@@ -1193,28 +1174,25 @@ unsafe impl<'a> ReadOnlySystemParam for &'a Archetypes {}
pub struct ArchetypesState;
// SAFETY: no component value access
-unsafe impl SystemParamState for ArchetypesState {
- type Item<'w, 's> = &'w Archetypes;
+unsafe impl<'a> SystemParam for &'a Components {
+ type State = ComponentsState;
+ type Item<'w, 's> = &'w Components;
- fn init(_world: &mut World, _system_meta: &mut SystemMeta) -> Self {
- Self
+ fn init(_world: &mut World, _system_meta: &mut SystemMeta) -> Self::State {
+ ComponentsState
}
#[inline]
unsafe fn get_param<'w, 's>(
- _state: &'s mut Self,
+ _state: &'s mut Self::State,
_system_meta: &SystemMeta,
world: &'w World,
_change_tick: u32,
) -> Self::Item<'w, 's> {
- world.archetypes()
+ world.components()
}
}
-impl<'a> SystemParam for &'a Components {
- type State = ComponentsState;
-}
-
// SAFETY: Only reads World components
unsafe impl<'a> ReadOnlySystemParam for &'a Components {}
@@ -1223,28 +1201,25 @@ unsafe impl<'a> ReadOnlySystemParam for &'a Components {}
pub struct ComponentsState;
// SAFETY: no component value access
-unsafe impl SystemParamState for ComponentsState {
- type Item<'w, 's> = &'w Components;
+unsafe impl<'a> SystemParam for &'a Entities {
+ type State = EntitiesState;
+ type Item<'w, 's> = &'w Entities;
- fn init(_world: &mut World, _system_meta: &mut SystemMeta) -> Self {
- Self
+ fn init(_world: &mut World, _system_meta: &mut SystemMeta) -> Self::State {
+ EntitiesState
}
#[inline]
unsafe fn get_param<'w, 's>(
- _state: &'s mut Self,
+ _state: &'s mut Self::State,
_system_meta: &SystemMeta,
world: &'w World,
_change_tick: u32,
) -> Self::Item<'w, 's> {
- world.components()
+ world.entities()
}
}
-impl<'a> SystemParam for &'a Entities {
- type State = EntitiesState;
-}
-
// SAFETY: Only reads World entities
unsafe impl<'a> ReadOnlySystemParam for &'a Entities {}
@@ -1253,28 +1228,25 @@ unsafe impl<'a> ReadOnlySystemParam for &'a Entities {}
pub struct EntitiesState;
// SAFETY: no component value access
-unsafe impl SystemParamState for EntitiesState {
- type Item<'w, 's> = &'w Entities;
+unsafe impl<'a> SystemParam for &'a Bundles {
+ type State = BundlesState;
+ type Item<'w, 's> = &'w Bundles;
- fn init(_world: &mut World, _system_meta: &mut SystemMeta) -> Self {
- Self
+ fn init(_world: &mut World, _system_meta: &mut SystemMeta) -> Self::State {
+ BundlesState
}
#[inline]
unsafe fn get_param<'w, 's>(
- _state: &'s mut Self,
+ _state: &'s mut Self::State,
_system_meta: &SystemMeta,
world: &'w World,
_change_tick: u32,
) -> Self::Item<'w, 's> {
- world.entities()
+ world.bundles()
}
}
-impl<'a> SystemParam for &'a Bundles {
- type State = BundlesState;
-}
-
// SAFETY: Only reads World bundles
unsafe impl<'a> ReadOnlySystemParam for &'a Bundles {}
@@ -1282,25 +1254,6 @@ unsafe impl<'a> ReadOnlySystemParam for &'a Bundles {}
#[doc(hidden)]
pub struct BundlesState;
-// SAFETY: no component value access
-unsafe impl SystemParamState for BundlesState {
- type Item<'w, 's> = &'w Bundles;
-
- fn init(_world: &mut World, _system_meta: &mut SystemMeta) -> Self {
- Self
- }
-
- #[inline]
- unsafe fn get_param<'w, 's>(
- _state: &'s mut Self,
- _system_meta: &SystemMeta,
- world: &'w World,
- _change_tick: u32,
- ) -> Self::Item<'w, 's> {
- world.bundles()
- }
-}
-
/// A [`SystemParam`] that reads the previous and current change ticks of the system.
///
/// A system's change ticks are updated each time it runs:
@@ -1333,24 +1286,17 @@ impl SystemChangeTick {
// SAFETY: Only reads internal system state
unsafe impl ReadOnlySystemParam for SystemChangeTick {}
-impl SystemParam for SystemChangeTick {
- type State = SystemChangeTickState;
-}
-
-/// The [`SystemParamState`] of [`SystemChangeTick`].
-#[doc(hidden)]
-pub struct SystemChangeTickState {}
-
// SAFETY: `SystemParamTickState` doesn't require any world access
-unsafe impl SystemParamState for SystemChangeTickState {
+unsafe impl SystemParam for SystemChangeTick {
+ type State = SystemChangeTickState;
type Item<'w, 's> = SystemChangeTick;
- fn init(_world: &mut World, _system_meta: &mut SystemMeta) -> Self {
- Self {}
+ fn init(_world: &mut World, _system_meta: &mut SystemMeta) -> Self::State {
+ SystemChangeTickState {}
}
unsafe fn get_param<'w, 's>(
- _state: &'s mut Self,
+ _state: &'s mut Self::State,
system_meta: &SystemMeta,
_world: &'w World,
change_tick: u32,
@@ -1362,6 +1308,10 @@ unsafe impl SystemParamState for SystemChangeTickState {
}
}
+/// The [`SystemParamState`] of [`SystemChangeTick`].
+#[doc(hidden)]
+pub struct SystemChangeTickState {}
+
/// Name of the system that corresponds to this [`crate::system::SystemState`].
///
/// This is not a reliable identifier, it is more so useful for debugging
@@ -1409,32 +1359,20 @@ impl<'s> std::fmt::Display for SystemName<'s> {
}
}
-impl<'s> SystemParam for SystemName<'s> {
- type State = SystemNameState;
-}
-
-// SAFETY: Only reads internal system state
-unsafe impl<'s> ReadOnlySystemParam for SystemName<'s> {}
-
-/// The [`SystemParamState`] of [`SystemName`].
-#[doc(hidden)]
-pub struct SystemNameState {
- name: Cow<'static, str>,
-}
-
// SAFETY: no component value access
-unsafe impl SystemParamState for SystemNameState {
+unsafe impl<'_s> SystemParam for SystemName<'_s> {
+ type State = SystemNameState;
type Item<'w, 's> = SystemName<'s>;
- fn init(_world: &mut World, system_meta: &mut SystemMeta) -> Self {
- Self {
+ fn init(_world: &mut World, system_meta: &mut SystemMeta) -> Self::State {
+ SystemNameState {
name: system_meta.name.clone(),
}
}
#[inline]
unsafe fn get_param<'w, 's>(
- state: &'s mut Self,
+ state: &'s mut Self::State,
_system_meta: &SystemMeta,
_world: &'w World,
_change_tick: u32,
@@ -1445,43 +1383,51 @@ unsafe impl SystemParamState for SystemNameState {
}
}
+// SAFETY: Only reads internal system state
+unsafe impl<'s> ReadOnlySystemParam for SystemName<'s> {}
+
+/// The [`SystemParamState`] of [`SystemName`].
+#[doc(hidden)]
+pub struct SystemNameState {
+ name: Cow<'static, str>,
+}
+
macro_rules! impl_system_param_tuple {
($($param: ident),*) => {
- impl<$($param: SystemParam),*> SystemParam for ($($param,)*) {
- type State = ($($param::State,)*);
- }
// SAFETY: tuple consists only of ReadOnlySystemParams
unsafe impl<$($param: ReadOnlySystemParam),*> ReadOnlySystemParam for ($($param,)*) {}
-
// SAFETY: implementors of each `SystemParamState` in the tuple have validated their impls
#[allow(clippy::undocumented_unsafe_blocks)] // false positive by clippy
#[allow(non_snake_case)]
- unsafe impl<$($param: SystemParamState),*> SystemParamState for ($($param,)*) {
+ unsafe impl<$($param: SystemParam),*> SystemParam for ($($param,)*) {
+ type State = ($($param::State,)*);
type Item<'w, 's> = ($($param::Item::<'w, 's>,)*);
#[inline]
- fn init(_world: &mut World, _system_meta: &mut SystemMeta) -> Self {
+ fn init(_world: &mut World, _system_meta: &mut SystemMeta) -> Self::State {
(($($param::init(_world, _system_meta),)*))
}
#[inline]
- fn new_archetype(&mut self, _archetype: &Archetype, _system_meta: &mut SystemMeta) {
- let ($($param,)*) = self;
- $($param.new_archetype(_archetype, _system_meta);)*
+ fn new_archetype(($($param,)*): &mut Self::State, _archetype: &Archetype, _system_meta: &mut SystemMeta) {
+ $(
+ <$param as SystemParam>::new_archetype($param, _archetype, _system_meta);
+ )*
}
#[inline]
- fn apply(&mut self, _world: &mut World) {
- let ($($param,)*) = self;
- $($param.apply(_world);)*
+ fn apply(($($param,)*): &mut Self::State, _world: &mut World) {
+ $(
+ <$param as SystemParam>::apply($param, _world);
+ )*
}
#[inline]
#[allow(clippy::unused_unit)]
unsafe fn get_param<'w, 's>(
- state: &'s mut Self,
+ state: &'s mut Self::State,
_system_meta: &SystemMeta,
_world: &'w World,
_change_tick: u32,
@@ -1558,7 +1504,7 @@ pub mod lifetimeless {
/// # }
/// ```
///
-pub struct StaticSystemParam<'w, 's, P: SystemParam>(SystemParamItem<'w, 's, P>);
+pub struct StaticSystemParam<'w, 's, P: SystemParam + 's>(SystemParamItem<'w, 's, P>);
impl<'w, 's, P: SystemParam> Deref for StaticSystemParam<'w, 's, P> {
type Target = SystemParamItem<'w, 's, P>;
@@ -1591,38 +1537,31 @@ unsafe impl<'w, 's, P: ReadOnlySystemParam + 'static> ReadOnlySystemParam
{
}
-impl<'world, 'state, P: SystemParam + 'static> SystemParam
- for StaticSystemParam<'world, 'state, P>
-{
- type State = StaticSystemParamState;
-}
-
// SAFETY: all methods are just delegated to `S`'s `SystemParamState` implementation
-unsafe impl + 'static> SystemParamState
- for StaticSystemParamState
-{
+unsafe impl<'_w, '_s, P: SystemParam + 'static> SystemParam for StaticSystemParam<'_w, '_s, P> {
+ type State = StaticSystemParamState;
type Item<'world, 'state> = StaticSystemParam<'world, 'state, P>;
- fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self {
- Self(S::init(world, system_meta), PhantomData)
+ fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self::State {
+ StaticSystemParamState(P::init(world, system_meta), PhantomData)
}
- fn new_archetype(&mut self, archetype: &Archetype, system_meta: &mut SystemMeta) {
- self.0.new_archetype(archetype, system_meta);
+ fn new_archetype(state: &mut Self::State, archetype: &Archetype, system_meta: &mut SystemMeta) {
+ P::new_archetype(&mut state.0, archetype, system_meta);
}
- fn apply(&mut self, world: &mut World) {
- self.0.apply(world);
+ fn apply(state: &mut Self::State, world: &mut World) {
+ P::apply(&mut state.0, world);
}
unsafe fn get_param<'world, 'state>(
- state: &'state mut Self,
+ state: &'state mut Self::State,
system_meta: &SystemMeta,
world: &'world World,
change_tick: u32,
) -> Self::Item<'world, 'state> {
// SAFETY: We properly delegate SystemParamState
- StaticSystemParam(S::get_param(&mut state.0, system_meta, world, change_tick))
+ StaticSystemParam(P::get_param(&mut state.0, system_meta, world, change_tick))
}
}
diff --git a/crates/bevy_render/src/extract_param.rs b/crates/bevy_render/src/extract_param.rs
index f854938d8e3a6..ec71736747550 100644
--- a/crates/bevy_render/src/extract_param.rs
+++ b/crates/bevy_render/src/extract_param.rs
@@ -2,8 +2,7 @@ use crate::MainWorld;
use bevy_ecs::{
prelude::*,
system::{
- ReadOnlySystemParam, ResState, SystemMeta, SystemParam, SystemParamItem, SystemParamState,
- SystemState,
+ ReadOnlySystemParam, ResState, SystemMeta, SystemParam, SystemParamItem, SystemState,
},
};
use std::ops::{Deref, DerefMut};
@@ -49,36 +48,30 @@ where
item: SystemParamItem<'w, 's, P>,
}
-impl<'w, 's, P: ReadOnlySystemParam> SystemParam for Extract<'w, 's, P> {
- type State = ExtractState;
-}
-
-#[doc(hidden)]
-pub struct ExtractState {
- state: SystemState,
- main_world_state: ResState,
-}
-
-// SAFETY: only accesses MainWorld resource with read only system params using ResState,
+// SAFETY: only accesses MainWorld resource with read only system params using Res,
// which is initialized in init()
-unsafe impl SystemParamState for ExtractState {
+unsafe impl<'_w, '_s, P> SystemParam for Extract<'_w, '_s, P>
+where
+ P: ReadOnlySystemParam,
+{
+ type State = ExtractState
;
type Item<'w, 's> = Extract<'w, 's, P>;
- fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self {
+ fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self::State {
let mut main_world = world.resource_mut::();
- Self {
+ ExtractState {
state: SystemState::new(&mut main_world),
- main_world_state: ResState::init(world, system_meta),
+ main_world_state: Res::init(world, system_meta),
}
}
unsafe fn get_param<'w, 's>(
- state: &'s mut Self,
+ state: &'s mut Self::State,
system_meta: &SystemMeta,
world: &'w World,
change_tick: u32,
) -> Self::Item<'w, 's> {
- let main_world = ResState::::get_param(
+ let main_world = Res::::get_param(
&mut state.main_world_state,
system_meta,
world,
@@ -89,7 +82,13 @@ unsafe impl SystemParamState for ExtractState<
}
}
-impl<'w, 's, P: SystemParam> Deref for Extract<'w, 's, P>
+#[doc(hidden)]
+pub struct ExtractState {
+ state: SystemState,
+ main_world_state: ResState,
+}
+
+impl<'w, 's, P> Deref for Extract<'w, 's, P>
where
P: ReadOnlySystemParam,
{
@@ -101,7 +100,7 @@ where
}
}
-impl<'w, 's, P: SystemParam> DerefMut for Extract<'w, 's, P>
+impl<'w, 's, P> DerefMut for Extract<'w, 's, P>
where
P: ReadOnlySystemParam,
{
@@ -111,7 +110,7 @@ where
}
}
-impl<'a, 'w, 's, P: SystemParam> IntoIterator for &'a Extract<'w, 's, P>
+impl<'a, 'w, 's, P> IntoIterator for &'a Extract<'w, 's, P>
where
P: ReadOnlySystemParam,
&'a SystemParamItem<'w, 's, P>: IntoIterator,
From d24d2a9207797fd29a2fc8a4685ac45ea79e1aa2 Mon Sep 17 00:00:00 2001
From: JoJoJet <21144246+JoJoJet@users.noreply.github.com>
Date: Tue, 6 Dec 2022 20:05:02 -0500
Subject: [PATCH 03/49] Add a test case for ignored/marker type params
---
crates/bevy_ecs/src/system/system_param.rs | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/crates/bevy_ecs/src/system/system_param.rs b/crates/bevy_ecs/src/system/system_param.rs
index 2537462bf3dfc..a81aecd77bfc0 100644
--- a/crates/bevy_ecs/src/system/system_param.rs
+++ b/crates/bevy_ecs/src/system/system_param.rs
@@ -1597,4 +1597,11 @@ mod tests {
#[derive(SystemParam)]
pub struct UnitParam {}
+
+ #[derive(SystemParam)]
+ struct MyParam<'w, T: Resource, Marker: 'static> {
+ _foo: Res<'w, T>,
+ #[system_param(ignore)]
+ marker: PhantomData,
+ }
}
From c9d45d60e689afb58340a52480f653be99ab0b39 Mon Sep 17 00:00:00 2001
From: JoJoJet <21144246+JoJoJet@users.noreply.github.com>
Date: Tue, 6 Dec 2022 20:06:46 -0500
Subject: [PATCH 04/49] impl `SystemParam` for `PhantomData`
---
crates/bevy_ecs/src/system/system_param.rs | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/crates/bevy_ecs/src/system/system_param.rs b/crates/bevy_ecs/src/system/system_param.rs
index a81aecd77bfc0..228776396eb4d 100644
--- a/crates/bevy_ecs/src/system/system_param.rs
+++ b/crates/bevy_ecs/src/system/system_param.rs
@@ -1565,6 +1565,26 @@ unsafe impl<'_w, '_s, P: SystemParam + 'static> SystemParam for StaticSystemPara
}
}
+// SAFETY: PhantomData accesses no World data
+unsafe impl SystemParam for PhantomData {
+ type State = ();
+ type Item<'world, 'state> = Self;
+
+ fn init(_world: &mut World, _system_meta: &mut SystemMeta) -> Self::State {}
+
+ unsafe fn get_param<'world, 'state>(
+ _state: &'state mut Self::State,
+ _system_meta: &SystemMeta,
+ _world: &'world World,
+ _change_tick: u32,
+ ) -> Self::Item<'world, 'state> {
+ Self
+ }
+}
+
+// SAFETY: PhantomData accesses no World data
+unsafe impl ReadOnlySystemParam for PhantomData {}
+
#[cfg(test)]
mod tests {
use super::*;
From e6a21d0dc3870754be119f43015817788aef6a46 Mon Sep 17 00:00:00 2001
From: JoJoJet <21144246+JoJoJet@users.noreply.github.com>
Date: Tue, 6 Dec 2022 20:07:01 -0500
Subject: [PATCH 05/49] add a marker param
---
crates/bevy_ecs/macros/src/lib.rs | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/crates/bevy_ecs/macros/src/lib.rs b/crates/bevy_ecs/macros/src/lib.rs
index cc8533ff647a4..431a5dbafea84 100644
--- a/crates/bevy_ecs/macros/src/lib.rs
+++ b/crates/bevy_ecs/macros/src/lib.rs
@@ -466,13 +466,17 @@ pub fn derive_system_param(input: TokenStream) -> TokenStream {
#[doc(hidden)]
type State<'w, 's, #punctuated_generic_idents> = FetchState<
- (#(<#field_types as #path::system::SystemParam>::State,)*),
+ (
+ #(<#field_types as #path::system::SystemParam>::State,)*
+ (), // State for the `PhantomData` param.
+ ),
#punctuated_generic_idents
>;
#[doc(hidden)]
type FieldsTuple<'w, 's, #punctuated_generic_idents> = (
#(#field_types,)*
+ std::marker::PhantomData (#punctuated_generic_idents)>,
);
#[doc(hidden)]
From 1928bf6d2af5fcec98fc407676708e1c7e1f3de3 Mon Sep 17 00:00:00 2001
From: JoJoJet <21144246+JoJoJet@users.noreply.github.com>
Date: Tue, 6 Dec 2022 21:43:00 -0500
Subject: [PATCH 06/49] remove trivial `State` types
---
crates/bevy_ecs/src/system/system_param.rs | 209 ++++++---------------
crates/bevy_render/src/extract_param.rs | 8 +-
2 files changed, 58 insertions(+), 159 deletions(-)
diff --git a/crates/bevy_ecs/src/system/system_param.rs b/crates/bevy_ecs/src/system/system_param.rs
index 228776396eb4d..5cabdcd6717e8 100644
--- a/crates/bevy_ecs/src/system/system_param.rs
+++ b/crates/bevy_ecs/src/system/system_param.rs
@@ -130,7 +130,7 @@ use std::{
/// conflicting access across all [`SystemParam`]'s.
pub unsafe trait SystemParam: Sized {
type State: Send + Sync + 'static;
- type Item<'world, 'state>;
+ type Item<'world, 'state>: SystemParam;
fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self::State;
@@ -377,20 +377,13 @@ where
}
}
-/// The [`SystemParamState`] of [`Res`].
-#[doc(hidden)]
-pub struct ResState {
- component_id: ComponentId,
- marker: PhantomData,
-}
-
// SAFETY: Res only reads a single World resource
unsafe impl<'a, T: Resource> ReadOnlySystemParam for Res<'a, T> {}
// SAFETY: Res ComponentId and ArchetypeComponentId access is applied to SystemMeta. If this Res
// conflicts with any prior access, a panic will occur.
unsafe impl<'a, T: Resource> SystemParam for Res<'a, T> {
- type State = ResState;
+ type State = ComponentId;
type Item<'w, 's> = Res<'w, T>;
fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self::State {
@@ -412,21 +405,19 @@ unsafe impl<'a, T: Resource> SystemParam for Res<'a, T> {
system_meta
.archetype_component_access
.add_read(archetype_component_id);
- ResState {
- component_id,
- marker: PhantomData,
- }
+
+ component_id
}
#[inline]
unsafe fn get_param<'w, 's>(
- state: &'s mut Self::State,
+ &mut component_id: &'s mut Self::State,
system_meta: &SystemMeta,
world: &'w World,
change_tick: u32,
) -> Self::Item<'w, 's> {
let (ptr, ticks) = world
- .get_resource_with_ticks(state.component_id)
+ .get_resource_with_ticks(component_id)
.unwrap_or_else(|| {
panic!(
"Resource requested by {} does not exist: {}",
@@ -444,33 +435,25 @@ unsafe impl<'a, T: Resource> SystemParam for Res<'a, T> {
}
}
-/// The [`SystemParamState`] of [`Option>`].
-/// See: [`Res`]
-#[doc(hidden)]
-pub struct OptionResState(ResState);
-
-// SAFETY: Only reads a single World resource
-unsafe impl<'a, T: Resource> ReadOnlySystemParam for Option> {}
-
// SAFETY: this impl defers to `ResState`, which initializes
// and validates the correct world access
unsafe impl<'a, T: Resource> SystemParam for Option> {
- type State = OptionResState;
+ type State = ComponentId;
type Item<'w, 's> = Option>;
fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self::State {
- OptionResState(Res::init(world, system_meta))
+ Res::::init(world, system_meta)
}
#[inline]
unsafe fn get_param<'w, 's>(
- state: &'s mut Self::State,
+ &mut component_id: &'s mut Self::State,
system_meta: &SystemMeta,
world: &'w World,
change_tick: u32,
) -> Self::Item<'w, 's> {
world
- .get_resource_with_ticks(state.0.component_id)
+ .get_resource_with_ticks(component_id)
.map(|(ptr, ticks)| Res {
value: ptr.deref(),
added: ticks.added.deref(),
@@ -481,17 +464,13 @@ unsafe impl<'a, T: Resource> SystemParam for Option> {
}
}
-/// The [`SystemParamState`] of [`ResMut`].
-#[doc(hidden)]
-pub struct ResMutState {
- component_id: ComponentId,
- marker: PhantomData,
-}
+// SAFETY: Only reads a single World resource
+unsafe impl<'a, T: Resource> ReadOnlySystemParam for Option> {}
// SAFETY: Res ComponentId and ArchetypeComponentId access is applied to SystemMeta. If this Res
// conflicts with any prior access, a panic will occur.
unsafe impl<'a, T: Resource> SystemParam for ResMut<'a, T> {
- type State = ResMutState;
+ type State = ComponentId;
type Item<'w, 's> = ResMut<'w, T>;
fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self::State {
@@ -516,21 +495,19 @@ unsafe impl<'a, T: Resource> SystemParam for ResMut<'a, T> {
system_meta
.archetype_component_access
.add_write(archetype_component_id);
- ResMutState {
- component_id,
- marker: PhantomData,
- }
+
+ component_id
}
#[inline]
unsafe fn get_param<'w, 's>(
- state: &'s mut Self::State,
+ &mut component_id: &'s mut Self::State,
system_meta: &SystemMeta,
world: &'w World,
change_tick: u32,
) -> Self::Item<'w, 's> {
let value = world
- .get_resource_unchecked_mut_with_id(state.component_id)
+ .get_resource_unchecked_mut_with_id(component_id)
.unwrap_or_else(|| {
panic!(
"Resource requested by {} does not exist: {}",
@@ -550,30 +527,25 @@ unsafe impl<'a, T: Resource> SystemParam for ResMut<'a, T> {
}
}
-/// The [`SystemParamState`] of [`Option>`].
-/// See: [`ResMut`]
-#[doc(hidden)]
-pub struct OptionResMutState(ResMutState);
-
// SAFETY: this impl defers to `ResMutState`, which initializes
// and validates the correct world access
unsafe impl<'a, T: Resource> SystemParam for Option> {
- type State = OptionResMutState;
+ type State = ComponentId;
type Item<'w, 's> = Option>;
fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self::State {
- OptionResMutState(ResMut::init(world, system_meta))
+ ResMut::::init(world, system_meta)
}
#[inline]
unsafe fn get_param<'w, 's>(
- state: &'s mut Self::State,
+ &mut component_id: &'s mut Self::State,
system_meta: &SystemMeta,
world: &'w World,
change_tick: u32,
) -> Self::Item<'w, 's> {
world
- .get_resource_unchecked_mut_with_id(state.0.component_id)
+ .get_resource_unchecked_mut_with_id(component_id)
.map(|value| ResMut {
value: value.value,
ticks: Ticks {
@@ -616,13 +588,9 @@ unsafe impl<'_w, '_s> SystemParam for Commands<'_w, '_s> {
/// SAFETY: only reads world
unsafe impl<'w> ReadOnlySystemParam for &'w World {}
-/// The [`SystemParamState`] of [`&World`](crate::world::World).
-#[doc(hidden)]
-pub struct WorldState;
-
// SAFETY: `read_all` access is set and conflicts result in a panic
unsafe impl<'_w> SystemParam for &'_w World {
- type State = WorldState;
+ type State = ();
type Item<'w, 's> = &'w World;
fn init(_world: &mut World, system_meta: &mut SystemMeta) -> Self::State {
@@ -647,8 +615,6 @@ unsafe impl<'_w> SystemParam for &'_w World {
panic!("&World conflicts with a previous mutable system parameter. Allowing this would break Rust's mutability rules");
}
system_meta.component_access_set.add(filtered_access);
-
- WorldState
}
unsafe fn get_param<'w, 's>(
@@ -940,17 +906,10 @@ impl<'a, T> From> for NonSend<'a, T> {
}
}
-/// The [`SystemParamState`] of [`NonSend`].
-#[doc(hidden)]
-pub struct NonSendState {
- component_id: ComponentId,
- marker: PhantomData T>,
-}
-
// SAFETY: NonSendComponentId and ArchetypeComponentId access is applied to SystemMeta. If this
// NonSend conflicts with any prior access, a panic will occur.
unsafe impl<'a, T: 'static> SystemParam for NonSend<'a, T> {
- type State = NonSendState;
+ type State = ComponentId;
type Item<'w, 's> = NonSend<'w, T>;
fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self::State {
@@ -974,22 +933,20 @@ unsafe impl<'a, T: 'static> SystemParam for NonSend<'a, T> {
system_meta
.archetype_component_access
.add_read(archetype_component_id);
- NonSendState {
- component_id,
- marker: PhantomData,
- }
+
+ component_id
}
#[inline]
unsafe fn get_param<'w, 's>(
- state: &'s mut Self::State,
+ &mut component_id: &'s mut Self::State,
system_meta: &SystemMeta,
world: &'w World,
change_tick: u32,
) -> Self::Item<'w, 's> {
world.validate_non_send_access::();
let (ptr, ticks) = world
- .get_resource_with_ticks(state.component_id)
+ .get_resource_with_ticks(component_id)
.unwrap_or_else(|| {
panic!(
"Non-send resource requested by {} does not exist: {}",
@@ -1007,34 +964,26 @@ unsafe impl<'a, T: 'static> SystemParam for NonSend<'a, T> {
}
}
-/// The [`SystemParamState`] of [`Option>`].
-/// See: [`NonSend`]
-#[doc(hidden)]
-pub struct OptionNonSendState(NonSendState);
-
-// SAFETY: Only reads a single non-send resource
-unsafe impl<'w, T: 'static> ReadOnlySystemParam for Option> {}
-
// SAFETY: this impl defers to `NonSendState`, which initializes
// and validates the correct world access
unsafe impl<'_w, T: 'static> SystemParam for Option> {
- type State = OptionNonSendState;
+ type State = ComponentId;
type Item<'w, 's> = Option>;
fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self::State {
- OptionNonSendState(NonSend::init(world, system_meta))
+ NonSend::::init(world, system_meta)
}
#[inline]
unsafe fn get_param<'w, 's>(
- state: &'s mut Self::State,
+ &mut component_id: &'s mut Self::State,
system_meta: &SystemMeta,
world: &'w World,
change_tick: u32,
) -> Self::Item<'w, 's> {
world.validate_non_send_access::();
world
- .get_resource_with_ticks(state.0.component_id)
+ .get_resource_with_ticks(component_id)
.map(|(ptr, ticks)| NonSend {
value: ptr.deref(),
ticks: ticks.read(),
@@ -1047,17 +996,10 @@ unsafe impl<'_w, T: 'static> SystemParam for Option> {
// SAFETY: Only reads a single non-send resource
unsafe impl<'a, T: 'static> ReadOnlySystemParam for NonSendMut<'a, T> {}
-/// The [`SystemParamState`] of [`NonSendMut`].
-#[doc(hidden)]
-pub struct NonSendMutState {
- component_id: ComponentId,
- marker: PhantomData T>,
-}
-
// SAFETY: NonSendMut ComponentId and ArchetypeComponentId access is applied to SystemMeta. If this
// NonSendMut conflicts with any prior access, a panic will occur.
unsafe impl<'a, T: 'static> SystemParam for NonSendMut<'a, T> {
- type State = NonSendMutState;
+ type State = ComponentId;
type Item<'w, 's> = NonSendMut<'w, T>;
fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self::State {
@@ -1084,22 +1026,20 @@ unsafe impl<'a, T: 'static> SystemParam for NonSendMut<'a, T> {
system_meta
.archetype_component_access
.add_write(archetype_component_id);
- NonSendMutState {
- component_id,
- marker: PhantomData,
- }
+
+ component_id
}
#[inline]
unsafe fn get_param<'w, 's>(
- state: &'s mut Self::State,
+ &mut component_id: &'s mut Self::State,
system_meta: &SystemMeta,
world: &'w World,
change_tick: u32,
) -> Self::Item<'w, 's> {
world.validate_non_send_access::();
let (ptr, ticks) = world
- .get_resource_with_ticks(state.component_id)
+ .get_resource_with_ticks(component_id)
.unwrap_or_else(|| {
panic!(
"Non-send resource requested by {} does not exist: {}",
@@ -1114,31 +1054,26 @@ unsafe impl<'a, T: 'static> SystemParam for NonSendMut<'a, T> {
}
}
-/// The [`SystemParamState`] of [`Option>`].
-/// See: [`NonSendMut`]
-#[doc(hidden)]
-pub struct OptionNonSendMutState(NonSendMutState);
-
// SAFETY: this impl defers to `NonSendMutState`, which initializes
// and validates the correct world access
unsafe impl<'a, T: 'static> SystemParam for Option> {
- type State = OptionNonSendMutState;
+ type State = ComponentId;
type Item<'w, 's> = Option>;
fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self::State {
- OptionNonSendMutState(NonSendMut::init(world, system_meta))
+ NonSendMut::::init(world, system_meta)
}
#[inline]
unsafe fn get_param<'w, 's>(
- state: &'s mut Self::State,
+ &mut component_id: &'s mut Self::State,
system_meta: &SystemMeta,
world: &'w World,
change_tick: u32,
) -> Self::Item<'w, 's> {
world.validate_non_send_access::();
world
- .get_resource_with_ticks(state.0.component_id)
+ .get_resource_with_ticks(component_id)
.map(|(ptr, ticks)| NonSendMut {
value: ptr.assert_unique().deref_mut(),
ticks: Ticks::from_tick_cells(ticks, system_meta.last_change_tick, change_tick),
@@ -1148,12 +1083,10 @@ unsafe impl<'a, T: 'static> SystemParam for Option> {
// SAFETY: no component value access
unsafe impl<'a> SystemParam for &'a Archetypes {
- type State = ArchetypesState;
+ type State = ();
type Item<'w, 's> = &'w Archetypes;
- fn init(_world: &mut World, _system_meta: &mut SystemMeta) -> Self::State {
- ArchetypesState
- }
+ fn init(_world: &mut World, _system_meta: &mut SystemMeta) -> Self::State {}
#[inline]
unsafe fn get_param<'w, 's>(
@@ -1169,18 +1102,12 @@ unsafe impl<'a> SystemParam for &'a Archetypes {
// SAFETY: Only reads World archetypes
unsafe impl<'a> ReadOnlySystemParam for &'a Archetypes {}
-/// The [`SystemParamState`] of [`Archetypes`].
-#[doc(hidden)]
-pub struct ArchetypesState;
-
// SAFETY: no component value access
unsafe impl<'a> SystemParam for &'a Components {
- type State = ComponentsState;
+ type State = ();
type Item<'w, 's> = &'w Components;
- fn init(_world: &mut World, _system_meta: &mut SystemMeta) -> Self::State {
- ComponentsState
- }
+ fn init(_world: &mut World, _system_meta: &mut SystemMeta) -> Self::State {}
#[inline]
unsafe fn get_param<'w, 's>(
@@ -1196,18 +1123,12 @@ unsafe impl<'a> SystemParam for &'a Components {
// SAFETY: Only reads World components
unsafe impl<'a> ReadOnlySystemParam for &'a Components {}
-/// The [`SystemParamState`] of [`Components`].
-#[doc(hidden)]
-pub struct ComponentsState;
-
// SAFETY: no component value access
unsafe impl<'a> SystemParam for &'a Entities {
- type State = EntitiesState;
+ type State = ();
type Item<'w, 's> = &'w Entities;
- fn init(_world: &mut World, _system_meta: &mut SystemMeta) -> Self::State {
- EntitiesState
- }
+ fn init(_world: &mut World, _system_meta: &mut SystemMeta) -> Self::State {}
#[inline]
unsafe fn get_param<'w, 's>(
@@ -1223,18 +1144,12 @@ unsafe impl<'a> SystemParam for &'a Entities {
// SAFETY: Only reads World entities
unsafe impl<'a> ReadOnlySystemParam for &'a Entities {}
-/// The [`SystemParamState`] of [`Entities`].
-#[doc(hidden)]
-pub struct EntitiesState;
-
// SAFETY: no component value access
unsafe impl<'a> SystemParam for &'a Bundles {
- type State = BundlesState;
+ type State = ();
type Item<'w, 's> = &'w Bundles;
- fn init(_world: &mut World, _system_meta: &mut SystemMeta) -> Self::State {
- BundlesState
- }
+ fn init(_world: &mut World, _system_meta: &mut SystemMeta) -> Self::State {}
#[inline]
unsafe fn get_param<'w, 's>(
@@ -1250,10 +1165,6 @@ unsafe impl<'a> SystemParam for &'a Bundles {
// SAFETY: Only reads World bundles
unsafe impl<'a> ReadOnlySystemParam for &'a Bundles {}
-/// The [`SystemParamState`] of [`Bundles`].
-#[doc(hidden)]
-pub struct BundlesState;
-
/// A [`SystemParam`] that reads the previous and current change ticks of the system.
///
/// A system's change ticks are updated each time it runs:
@@ -1288,12 +1199,10 @@ unsafe impl ReadOnlySystemParam for SystemChangeTick {}
// SAFETY: `SystemParamTickState` doesn't require any world access
unsafe impl SystemParam for SystemChangeTick {
- type State = SystemChangeTickState;
+ type State = ();
type Item<'w, 's> = SystemChangeTick;
- fn init(_world: &mut World, _system_meta: &mut SystemMeta) -> Self::State {
- SystemChangeTickState {}
- }
+ fn init(_world: &mut World, _system_meta: &mut SystemMeta) -> Self::State {}
unsafe fn get_param<'w, 's>(
_state: &'s mut Self::State,
@@ -1308,10 +1217,6 @@ unsafe impl SystemParam for SystemChangeTick {
}
}
-/// The [`SystemParamState`] of [`SystemChangeTick`].
-#[doc(hidden)]
-pub struct SystemChangeTickState {}
-
/// Name of the system that corresponds to this [`crate::system::SystemState`].
///
/// This is not a reliable identifier, it is more so useful for debugging
@@ -1527,10 +1432,6 @@ impl<'w, 's, P: SystemParam> StaticSystemParam<'w, 's, P> {
}
}
-/// The [`SystemParamState`] of [`StaticSystemParam`].
-#[doc(hidden)]
-pub struct StaticSystemParamState(S, PhantomData P>);
-
// SAFETY: This doesn't add any more reads, and the delegated fetch confirms it
unsafe impl<'w, 's, P: ReadOnlySystemParam + 'static> ReadOnlySystemParam
for StaticSystemParam<'w, 's, P>
@@ -1539,19 +1440,19 @@ unsafe impl<'w, 's, P: ReadOnlySystemParam + 'static> ReadOnlySystemParam
// SAFETY: all methods are just delegated to `S`'s `SystemParamState` implementation
unsafe impl<'_w, '_s, P: SystemParam + 'static> SystemParam for StaticSystemParam<'_w, '_s, P> {
- type State = StaticSystemParamState;
+ type State = P::State;
type Item<'world, 'state> = StaticSystemParam<'world, 'state, P>;
fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self::State {
- StaticSystemParamState(P::init(world, system_meta), PhantomData)
+ P::init(world, system_meta)
}
fn new_archetype(state: &mut Self::State, archetype: &Archetype, system_meta: &mut SystemMeta) {
- P::new_archetype(&mut state.0, archetype, system_meta);
+ P::new_archetype(state, archetype, system_meta);
}
fn apply(state: &mut Self::State, world: &mut World) {
- P::apply(&mut state.0, world);
+ P::apply(state, world);
}
unsafe fn get_param<'world, 'state>(
@@ -1561,7 +1462,7 @@ unsafe impl<'_w, '_s, P: SystemParam + 'static> SystemParam for StaticSystemPara
change_tick: u32,
) -> Self::Item<'world, 'state> {
// SAFETY: We properly delegate SystemParamState
- StaticSystemParam(P::get_param(&mut state.0, system_meta, world, change_tick))
+ StaticSystemParam(P::get_param(state, system_meta, world, change_tick))
}
}
diff --git a/crates/bevy_render/src/extract_param.rs b/crates/bevy_render/src/extract_param.rs
index ec71736747550..4b3334caf74a1 100644
--- a/crates/bevy_render/src/extract_param.rs
+++ b/crates/bevy_render/src/extract_param.rs
@@ -1,9 +1,7 @@
use crate::MainWorld;
use bevy_ecs::{
prelude::*,
- system::{
- ReadOnlySystemParam, ResState, SystemMeta, SystemParam, SystemParamItem, SystemState,
- },
+ system::{ReadOnlySystemParam, SystemMeta, SystemParam, SystemParamItem, SystemState},
};
use std::ops::{Deref, DerefMut};
@@ -61,7 +59,7 @@ where
let mut main_world = world.resource_mut::();
ExtractState {
state: SystemState::new(&mut main_world),
- main_world_state: Res::init(world, system_meta),
+ main_world_state: Res::::init(world, system_meta),
}
}
@@ -85,7 +83,7 @@ where
#[doc(hidden)]
pub struct ExtractState {
state: SystemState,
- main_world_state: ResState,
+ main_world_state: as SystemParam>::State,
}
impl<'w, 's, P> Deref for Extract<'w, 's, P>
From 2e3b75faf2ae55c00dfd2e8b163ebce0860d3ad0 Mon Sep 17 00:00:00 2001
From: JoJoJet <21144246+JoJoJet@users.noreply.github.com>
Date: Tue, 6 Dec 2022 21:56:50 -0500
Subject: [PATCH 07/49] don't generate state struct in the `SystemParam` derive
---
crates/bevy_ecs/macros/src/lib.rs | 29 +++++------------------------
1 file changed, 5 insertions(+), 24 deletions(-)
diff --git a/crates/bevy_ecs/macros/src/lib.rs b/crates/bevy_ecs/macros/src/lib.rs
index 431a5dbafea84..c0cc153498381 100644
--- a/crates/bevy_ecs/macros/src/lib.rs
+++ b/crates/bevy_ecs/macros/src/lib.rs
@@ -425,7 +425,6 @@ pub fn derive_system_param(input: TokenStream) -> TokenStream {
}
let struct_name = &ast.ident;
- let state_struct_visibility = &ast.vis;
TokenStream::from(quote! {
// We define the FetchState struct in an anonymous scope to avoid polluting the user namespace.
@@ -433,22 +432,19 @@ pub fn derive_system_param(input: TokenStream) -> TokenStream {
// as SystemParam>::State
const _: () = {
unsafe impl<'_w, '_s, #punctuated_generics> #path::system::SystemParam for #struct_name <#(#shadowed_lifetimes,)* #punctuated_generic_idents> #where_clause {
- type State = State<'_w, '_s, #punctuated_generic_idents>;
+ type State = as #path::system::SystemParam>::State;
type Item<'w, 's> = #struct_name #ty_generics;
fn init(world: &mut #path::world::World, system_meta: &mut #path::system::SystemMeta) -> Self::State {
- FetchState {
- state: >::init(world, system_meta),
- marker: std::marker::PhantomData,
- }
+ >::init(world, system_meta)
}
fn new_archetype(state: &mut Self::State, archetype: path::archetype::Archetype, system_meta: &mut #path::system::SystemMeta) {
- >::new_archetype(&mut state.state, archetype, system_meta)
+ >::new_archetype(state, archetype, system_meta)
}
fn apply(state: &mut Self::State, world: &mut #path::world::World) {
- >::apply(&mut state.state, world);
+ >::apply( state, world);
}
unsafe fn get_param<'w, 's>(
@@ -458,33 +454,18 @@ pub fn derive_system_param(input: TokenStream) -> TokenStream {
change_tick: u32,
) -> Self::Item<'w, 's> {
#struct_name {
- #(#fields: <#field_types as #path::system::SystemParam>::get_param(&mut state.state.#field_indices, system_meta, world, change_tick),)*
+ #(#fields: <#field_types as #path::system::SystemParam>::get_param(&mut state.#field_indices, system_meta, world, change_tick),)*
#(#ignored_fields: <#ignored_field_types>::default(),)*
}
}
}
- #[doc(hidden)]
- type State<'w, 's, #punctuated_generic_idents> = FetchState<
- (
- #(<#field_types as #path::system::SystemParam>::State,)*
- (), // State for the `PhantomData` param.
- ),
- #punctuated_generic_idents
- >;
-
#[doc(hidden)]
type FieldsTuple<'w, 's, #punctuated_generic_idents> = (
#(#field_types,)*
std::marker::PhantomData (#punctuated_generic_idents)>,
);
- #[doc(hidden)]
- #state_struct_visibility struct FetchState {
- state: TSystemParamState,
- marker: std::marker::PhantomData(#punctuated_generic_idents)>
- }
-
// Safety: The `ParamState` is `ReadOnlySystemParam`, so this can only read from the `World`
unsafe impl<'w, 's, #punctuated_generics> #path::system::ReadOnlySystemParam for #struct_name #ty_generics #read_only_where_clause {}
};
From d6a81dc27d154f155a07bb37a5fe47cf984afa88 Mon Sep 17 00:00:00 2001
From: JoJoJet <21144246+JoJoJet@users.noreply.github.com>
Date: Tue, 6 Dec 2022 22:07:14 -0500
Subject: [PATCH 08/49] remove `ParamSetState`
---
crates/bevy_ecs/macros/src/lib.rs | 10 +++++-----
crates/bevy_ecs/src/system/system_param.rs | 2 --
2 files changed, 5 insertions(+), 7 deletions(-)
diff --git a/crates/bevy_ecs/macros/src/lib.rs b/crates/bevy_ecs/macros/src/lib.rs
index c0cc153498381..cab703eb054c4 100644
--- a/crates/bevy_ecs/macros/src/lib.rs
+++ b/crates/bevy_ecs/macros/src/lib.rs
@@ -243,7 +243,7 @@ pub fn impl_param_set(_input: TokenStream) -> TokenStream {
for<'w, 's> #param::Item::<'w, 's>: SystemParam,
)*
{
- type State = ParamSetState<(#(#param::State,)*)>;
+ type State = (#(#param::State,)*);
type Item<'w, 's> = ParamSet<'w, 's, (#(#param::Item<'w, 's>,)*)>;
fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self::State {
@@ -263,18 +263,18 @@ pub fn impl_param_set(_input: TokenStream) -> TokenStream {
.archetype_component_access
.extend(meta.archetype_component_access);
)*
- ParamSetState((#(#param,)*))
+ (#(#param,)*)
}
fn new_archetype(state: &mut Self::State, archetype: &Archetype, system_meta: &mut SystemMeta) {
- let (#(#param,)*) = &mut state.0;
+ let (#(#param,)*) = state;
#(
<#param as SystemParam>::new_archetype(#param, archetype, system_meta);
)*
}
fn apply(state: &mut Self::State, world: &mut World) {
- <(#(#param,)*)>::apply(&mut state.0, world);
+ <(#(#param,)*)>::apply(state, world);
}
#[inline]
@@ -285,7 +285,7 @@ pub fn impl_param_set(_input: TokenStream) -> TokenStream {
change_tick: u32,
) -> Self::Item<'w, 's> {
ParamSet {
- param_states: &mut state.0,
+ param_states: state,
system_meta: system_meta.clone(),
world,
change_tick,
diff --git a/crates/bevy_ecs/src/system/system_param.rs b/crates/bevy_ecs/src/system/system_param.rs
index 5cabdcd6717e8..1bb777768b8d5 100644
--- a/crates/bevy_ecs/src/system/system_param.rs
+++ b/crates/bevy_ecs/src/system/system_param.rs
@@ -242,8 +242,6 @@ pub struct ParamSet<'w, 's, T: SystemParam> {
system_meta: SystemMeta,
change_tick: u32,
}
-/// The [`SystemParamState`] of [`ParamSet`].
-pub struct ParamSetState(T);
impl_param_set!();
From 2ffed09e727e62a111145b7b091c652e956f1903 Mon Sep 17 00:00:00 2001
From: JoJoJet <21144246+JoJoJet@users.noreply.github.com>
Date: Fri, 9 Dec 2022 22:16:18 -0500
Subject: [PATCH 09/49] reduce macro churn
---
crates/bevy_ecs/macros/src/lib.rs | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/crates/bevy_ecs/macros/src/lib.rs b/crates/bevy_ecs/macros/src/lib.rs
index cab703eb054c4..176714a973762 100644
--- a/crates/bevy_ecs/macros/src/lib.rs
+++ b/crates/bevy_ecs/macros/src/lib.rs
@@ -238,6 +238,11 @@ pub fn impl_param_set(_input: TokenStream) -> TokenStream {
let meta = &metas[0..param_count];
let param_fn_mut = ¶m_fn_muts[0..param_count];
tokens.extend(TokenStream::from(quote! {
+ // SAFETY: All parameters are constrained to ReadOnlySystemParam, so World is only read
+ unsafe impl<'w, 's, #(#param,)*> ReadOnlySystemParam for ParamSet<'w, 's, (#(#param,)*)>
+ where #(#param: ReadOnlySystemParam,)*
+ { }
+
unsafe impl<'_w, '_s, #(#param: SystemParam,)*> SystemParam for ParamSet<'_w, '_s, (#(#param,)*)>
where #(
for<'w, 's> #param::Item::<'w, 's>: SystemParam,
@@ -293,11 +298,6 @@ pub fn impl_param_set(_input: TokenStream) -> TokenStream {
}
}
- // SAFETY: All parameters are constrained to ReadOnlyState, so World is only read
- unsafe impl<'w, 's, #(#param,)*> ReadOnlySystemParam for ParamSet<'w, 's, (#(#param,)*)>
- where #(#param: ReadOnlySystemParam,)*
- { }
-
impl<'w, 's, #(#param: SystemParam,)*> ParamSet<'w, 's, (#(#param,)*)>
{
#(#param_fn_mut)*
@@ -466,7 +466,7 @@ pub fn derive_system_param(input: TokenStream) -> TokenStream {
std::marker::PhantomData