Remove the SystemParamState trait and remove types like ResState (#6919)

Spiritual successor to #5205.
Actual successor to #6865.

# Objective

Currently, system params are defined using three traits: `SystemParam`, `ReadOnlySystemParam`, `SystemParamState`. The behavior for each param is specified by the `SystemParamState` trait, while `SystemParam` simply defers to the state.

Splitting the traits in this way makes it easier to implement within macros, but it increases the cognitive load. Worst of all, this approach requires each `MySystemParam` to have a public `MySystemParamState` type associated with it.

## Solution

* Merge the trait `SystemParamState` into `SystemParam`.
* Remove all trivial `SystemParam` state types. 
  * `OptionNonSendMutState<T>`: you will not be missed.

---

- [x] Fix/resolve the remaining test failure.

## Changelog

* Removed the trait `SystemParamState`, merging its functionality into `SystemParam`.

## Migration Guide

**Note**: this should replace the migration guide for #6865.
This is relative to Bevy 0.9, not main.

The traits `SystemParamState` and `SystemParamFetch` have been removed, and their functionality has been transferred to `SystemParam`.


```rust
// Before (0.9)
impl SystemParam for MyParam<'_, '_> {
    type State = MyParamState;
}
unsafe impl SystemParamState for MyParamState {
    fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self { ... }
}
unsafe impl<'w, 's> SystemParamFetch<'w, 's> for MyParamState {
    type Item = MyParam<'w, 's>;
    fn get_param(&mut self, ...) -> Self::Item;
}
unsafe impl ReadOnlySystemParamFetch for MyParamState { }

// After (0.10)
unsafe impl SystemParam for MyParam<'_, '_> {
    type State = MyParamState;
    type Item<'w, 's> = MyParam<'w, 's>;
    fn init_state(world: &mut World, system_meta: &mut SystemMeta) -> Self::State { ... }
    fn get_param<'w, 's>(state: &mut Self::State, ...) -> Self::Item<'w, 's>;
}
unsafe impl ReadOnlySystemParam for MyParam<'_, '_> { }
```

The trait `ReadOnlySystemParamFetch` has been replaced with `ReadOnlySystemParam`.

```rust
// Before
unsafe impl ReadOnlySystemParamFetch for MyParamState {}

// After
unsafe impl ReadOnlySystemParam for MyParam<'_, '_> {}
```
This commit is contained in:
JoJoJet 2023-01-07 23:20:32 +00:00
parent 076e6f780c
commit 1efdbb7e3e
7 changed files with 301 additions and 540 deletions

View File

@ -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() {
@ -238,7 +237,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::get_param(&mut self.param_states.#index, &self.system_meta, self.world, self.change_tick)
}
}
});
@ -246,36 +245,29 @@ pub fn impl_param_set(_input: TokenStream) -> TokenStream {
for param_count in 1..=max_params {
let param = &params[0..param_count];
let param_state = &params_state[0..param_count];
let meta = &metas[0..param_count];
let param_fn_mut = &param_fn_muts[0..param_count];
tokens.extend(TokenStream::from(quote! {
impl<'w, 's, #(#param: SystemParam,)*> SystemParam for ParamSet<'w, 's, (#(#param,)*)>
{
type State = ParamSetState<(#(#param::State,)*)>;
}
// SAFETY: All parameters are constrained to ReadOnlyState, so World is only read
// 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,)*
{ }
// 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,)*)>
unsafe impl<'_w, '_s, #(#param: SystemParam,)*> SystemParam for ParamSet<'_w, '_s, (#(#param,)*)>
{
type Item<'w, 's> = ParamSet<'w, 's, (#(<#param_state as SystemParamState>::Item::<'w, 's>,)*)>;
type State = (#(#param::State,)*);
type Item<'w, 's> = ParamSet<'w, 's, (#(#param,)*)>;
fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self {
fn init_state(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_state(world, &mut #meta);
let #param = #param::init_state(world, &mut system_meta.clone());
)*
#(
system_meta
@ -285,29 +277,26 @@ pub fn impl_param_set(_input: TokenStream) -> TokenStream {
.archetype_component_access
.extend(&#meta.archetype_component_access);
)*
ParamSetState((#(#param,)*))
(#(#param,)*)
}
fn new_archetype(&mut self, archetype: &Archetype, system_meta: &mut SystemMeta) {
let (#(#param,)*) = &mut self.0;
#(
#param.new_archetype(archetype, system_meta);
)*
fn new_archetype(state: &mut Self::State, archetype: &Archetype, system_meta: &mut SystemMeta) {
<(#(#param,)*) as SystemParam>::new_archetype(state, archetype, system_meta);
}
fn apply(&mut self, system_meta: &SystemMeta, world: &mut World) {
self.0.apply(system_meta, world)
fn apply(state: &mut Self::State, system_meta: &SystemMeta, world: &mut World) {
<(#(#param,)*) as SystemParam>::apply(state, system_meta, 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,
) -> Self::Item<'w, 's> {
ParamSet {
param_states: &mut state.0,
param_states: state,
system_meta: system_meta.clone(),
world,
change_tick,
@ -317,7 +306,6 @@ pub fn impl_param_set(_input: TokenStream) -> TokenStream {
impl<'w, 's, #(#param: SystemParam,)*> ParamSet<'w, 's, (#(#param,)*)>
{
#(#param_fn_mut)*
}
}));
@ -411,7 +399,7 @@ pub fn derive_system_param(input: TokenStream) -> TokenStream {
}
}
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
let (_impl_generics, ty_generics, where_clause) = generics.split_for_impl();
let lifetimeless_generics: Vec<_> = generics
.params
@ -419,6 +407,12 @@ pub fn derive_system_param(input: TokenStream) -> TokenStream {
.filter(|g| !matches!(g, GenericParam::Lifetime(_)))
.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 {
@ -432,15 +426,6 @@ pub fn derive_system_param(input: TokenStream) -> TokenStream {
_ => unreachable!(),
}));
let mut punctuated_generics_no_bounds = punctuated_generics.clone();
for g in &mut punctuated_generics_no_bounds {
match g {
GenericParam::Type(g) => g.bounds.clear(),
GenericParam::Lifetime(g) => g.bounds.clear(),
GenericParam::Const(_) => {}
}
}
let mut punctuated_generic_idents = Punctuated::<_, Token![,]>::new();
punctuated_generic_idents.extend(lifetimeless_generics.iter().map(|g| match g {
GenericParam::Type(g) => &g.ident,
@ -479,10 +464,6 @@ pub fn derive_system_param(input: TokenStream) -> TokenStream {
// The struct can still be accessed via SystemParam::State, e.g. EventReaderState can be accessed via
// <EventReader<'static, 'static, T> as SystemParam>::State
const _: () = {
impl #impl_generics #path::system::SystemParam for #struct_name #ty_generics #where_clause {
type State = FetchState<'static, 'static, #punctuated_generic_idents>;
}
#[doc(hidden)]
#state_struct_visibility struct FetchState <'w, 's, #(#lifetimeless_generics,)*> {
state: (#(<#tuple_types as #path::system::SystemParam>::State,)*),
@ -492,34 +473,33 @@ pub fn derive_system_param(input: TokenStream) -> TokenStream {
)>,
}
unsafe impl<#punctuated_generics> #path::system::SystemParamState for
FetchState<'static, 'static, #punctuated_generic_idents>
#where_clause {
type Item<'w, 's> = #struct_name #ty_generics;
unsafe impl<'w, 's, #punctuated_generics> #path::system::SystemParam for #struct_name #ty_generics #where_clause {
type State = FetchState<'static, 'static, #punctuated_generic_idents>;
type Item<'_w, '_s> = #struct_name <#(#shadowed_lifetimes,)* #punctuated_generic_idents>;
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_state(world: &mut #path::world::World, system_meta: &mut #path::system::SystemMeta) -> Self::State {
FetchState {
state: <(#(#tuple_types,)*) as #path::system::SystemParam>::init_state(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) {
<(#(#tuple_types,)*) as #path::system::SystemParam>::new_archetype(&mut state.state, archetype, system_meta)
}
fn apply(&mut self, system_meta: &#path::system::SystemMeta, world: &mut #path::world::World) {
self.state.apply(system_meta, world)
fn apply(state: &mut Self::State, system_meta: &#path::system::SystemMeta, world: &mut #path::world::World) {
<(#(#tuple_types,)*) as #path::system::SystemParam>::apply(&mut state.state, system_meta, world);
}
unsafe fn get_param<'w, 's>(
state: &'s mut Self,
unsafe fn get_param<'w2, 's2>(
state: &'s2 mut Self::State,
system_meta: &#path::system::SystemMeta,
world: &'w #path::world::World,
world: &'w2 #path::world::World,
change_tick: u32,
) -> Self::Item<'w, 's> {
) -> Self::Item<'w2, 's2> {
let (#(#tuple_patterns,)*) = <
<(#(#tuple_types,)*) as #path::system::SystemParam>::State as #path::system::SystemParamState
(#(#tuple_types,)*) as #path::system::SystemParam
>::get_param(&mut state.state, system_meta, world, change_tick);
#struct_name {
#(#fields: #field_locals,)*

View File

@ -5,14 +5,14 @@ use thread_local::ThreadLocal;
use crate::{
entity::Entities,
prelude::World,
system::{SystemMeta, SystemParam, SystemParamState},
system::{SystemMeta, SystemParam},
};
use super::{CommandQueue, Commands};
/// The internal [`SystemParam`] state of the [`ParallelCommands`] type
#[doc(hidden)]
#[derive(Default)]
/// The internal [`SystemParamState`] of the [`ParallelCommands`] type
pub struct ParallelCommandsState {
thread_local_storage: ThreadLocal<Cell<CommandQueue>>,
}
@ -48,30 +48,27 @@ 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_state(_: &mut World, _: &mut crate::system::SystemMeta) -> Self::State {
ParallelCommandsState::default()
}
fn apply(&mut self, _system_meta: &SystemMeta, world: &mut World) {
fn apply(state: &mut Self::State, _system_meta: &SystemMeta, world: &mut World) {
#[cfg(feature = "trace")]
let _system_span =
bevy_utils::tracing::info_span!("system_commands", name = _system_meta.name())
.entered();
for cq in &mut self.thread_local_storage {
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,

View File

@ -6,7 +6,7 @@ use crate::{
schedule::{SystemLabel, SystemLabelId},
system::{
check_system_change_tick, AsSystemLabel, ExclusiveSystemParam, ExclusiveSystemParamItem,
ExclusiveSystemParamState, IntoSystem, System, SystemMeta, SystemTypeIdLabel,
IntoSystem, System, SystemMeta, SystemTypeIdLabel,
},
world::{World, WorldId},
};
@ -94,7 +94,7 @@ where
let saved_last_tick = world.last_change_tick;
world.last_change_tick = self.system_meta.last_change_tick;
let params = <Param as ExclusiveSystemParam>::State::get_param(
let params = Param::get_param(
self.param_state.as_mut().expect(PARAM_MESSAGE),
&self.system_meta,
);
@ -122,17 +122,14 @@ where
#[inline]
fn apply_buffers(&mut self, world: &mut World) {
let param_state = self.param_state.as_mut().expect(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(<Param::State as ExclusiveSystemParamState>::init(
world,
&mut self.system_meta,
));
self.param_state = Some(Param::init(world, &mut self.system_meta));
}
fn update_archetype_component_access(&mut self, _world: &World) {}

View File

@ -1,108 +1,89 @@
use crate::{
prelude::{FromWorld, QueryState},
query::{ReadOnlyWorldQuery, WorldQuery},
system::{Local, LocalState, SystemMeta, SystemParam, SystemState},
system::{Local, SystemMeta, SystemParam, SystemState},
world::World,
};
use bevy_ecs_macros::all_tuples;
use bevy_utils::synccell::SyncCell;
pub trait ExclusiveSystemParam: Sized {
type State: ExclusiveSystemParamState;
}
type State: Send + Sync + 'static;
type Item<'s>: ExclusiveSystemParam<State = Self::State>;
pub type ExclusiveSystemParamItem<'s, P> =
<<P as ExclusiveSystemParam>::State as ExclusiveSystemParamState>::Item<'s>;
/// The state of a [`SystemParam`].
pub trait ExclusiveSystemParamState: Send + Sync + 'static {
type Item<'s>: ExclusiveSystemParam<State = Self>;
fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self;
fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self::State;
#[inline]
fn apply(&mut self, _world: &mut World) {}
fn apply(_state: &mut Self::State, _world: &mut World) {}
fn get_param<'s>(state: &'s mut Self, system_meta: &SystemMeta) -> Self::Item<'s>;
fn get_param<'s>(state: &'s mut Self::State, system_meta: &SystemMeta) -> Self::Item<'s>;
}
pub type ExclusiveSystemParamItem<'s, P> = <P as ExclusiveSystemParam>::Item<'s>;
impl<'a, Q: WorldQuery + 'static, F: ReadOnlyWorldQuery + 'static> ExclusiveSystemParam
for &'a mut QueryState<Q, F>
{
type State = QueryState<Q, F>;
}
impl<Q: WorldQuery + 'static, F: ReadOnlyWorldQuery + 'static> ExclusiveSystemParamState
for QueryState<Q, F>
{
type Item<'s> = &'s mut QueryState<Q, F>;
fn init(world: &mut World, _system_meta: &mut SystemMeta) -> Self {
fn init(world: &mut World, _system_meta: &mut SystemMeta) -> Self::State {
QueryState::new(world)
}
fn get_param<'s>(state: &'s mut Self, _system_meta: &SystemMeta) -> Self::Item<'s> {
fn get_param<'s>(state: &'s mut Self::State, _system_meta: &SystemMeta) -> Self::Item<'s> {
state
}
}
impl<'a, P: SystemParam + 'static> ExclusiveSystemParam for &'a mut SystemState<P> {
type State = SystemState<P>;
}
impl<P: SystemParam> ExclusiveSystemParamState for SystemState<P> {
type Item<'s> = &'s mut SystemState<P>;
fn init(world: &mut World, _system_meta: &mut SystemMeta) -> Self {
fn init(world: &mut World, _system_meta: &mut SystemMeta) -> Self::State {
SystemState::new(world)
}
fn get_param<'s>(state: &'s mut Self, _system_meta: &SystemMeta) -> Self::Item<'s> {
fn get_param<'s>(state: &'s mut Self::State, _system_meta: &SystemMeta) -> Self::Item<'s> {
state
}
}
impl<'s, T: FromWorld + Send + Sync + 'static> ExclusiveSystemParam for Local<'s, T> {
type State = LocalState<T>;
}
impl<T: FromWorld + Send + Sync> ExclusiveSystemParamState for LocalState<T> {
impl<'_s, T: FromWorld + Send + Sync + 'static> ExclusiveSystemParam for Local<'_s, T> {
type State = SyncCell<T>;
type Item<'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 {
SyncCell::new(T::from_world(world))
}
fn get_param<'s>(state: &'s mut Self, _system_meta: &SystemMeta) -> Self::Item<'s> {
Local(state.0.get())
fn get_param<'s>(state: &'s mut Self::State, _system_meta: &SystemMeta) -> Self::Item<'s> {
Local(state.get())
}
}
macro_rules! impl_exclusive_system_param_tuple {
($($param: ident),*) => {
impl<$($param: ExclusiveSystemParam),*> ExclusiveSystemParam for ($($param,)*) {
type State = ($($param::State,)*);
}
#[allow(unused_variables)]
#[allow(non_snake_case)]
impl<$($param: ExclusiveSystemParamState),*> ExclusiveSystemParamState for ($($param,)*) {
impl<$($param: ExclusiveSystemParam),*> ExclusiveSystemParam for ($($param,)*) {
type State = ($($param::State,)*);
type Item<'s> = ($($param::Item<'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 apply(&mut self, _world: &mut World) {
let ($($param,)*) = self;
$($param.apply(_world);)*
fn apply(state: &mut Self::State, _world: &mut World) {
let ($($param,)*) = state;
$($param::apply($param, _world);)*
}
#[inline]
#[allow(clippy::unused_unit)]
fn get_param<'s>(
state: &'s mut Self,
state: &'s mut Self::State,
system_meta: &SystemMeta,
) -> Self::Item<'s> {
@ -110,7 +91,6 @@ macro_rules! impl_exclusive_system_param_tuple {
($($param::get_param($param, system_meta),)*)
}
}
};
}

View File

@ -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;
@ -141,7 +138,7 @@ impl SystemMeta {
/// ```
pub struct SystemState<Param: SystemParam + 'static> {
meta: SystemMeta,
param_state: <Param as SystemParam>::State,
param_state: Param::State,
world_id: WorldId,
archetype_generation: ArchetypeGeneration,
}
@ -150,7 +147,7 @@ impl<Param: SystemParam> SystemState<Param> {
pub fn new(world: &mut World) -> Self {
let mut meta = SystemMeta::new::<Param>();
meta.last_change_tick = world.change_tick().wrapping_sub(MAX_CHANGE_AGE);
let param_state = <Param::State as SystemParamState>::init(world, &mut meta);
let param_state = Param::init_state(world, &mut meta);
Self {
meta,
param_state,
@ -188,7 +185,7 @@ impl<Param: SystemParam> SystemState<Param> {
/// 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(&self.meta, world);
Param::apply(&mut self.param_state, &self.meta, world);
}
#[inline]
@ -204,7 +201,8 @@ impl<Param: SystemParam> SystemState<Param> {
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,
);
@ -223,12 +221,7 @@ impl<Param: SystemParam> SystemState<Param> {
world: &'w World,
) -> SystemParamItem<'w, 's, Param> {
let change_tick = world.increment_change_tick();
let param = <Param::State as SystemParamState>::get_param(
&mut self.param_state,
&self.meta,
world,
change_tick,
);
let param = Param::get_param(&mut self.param_state, &self.meta, world, change_tick);
self.meta.last_change_tick = change_tick;
param
}
@ -400,7 +393,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 = <Param as SystemParam>::State::get_param(
let params = Param::get_param(
self.param_state.as_mut().expect(Self::PARAM_MESSAGE),
&self.system_meta,
world,
@ -422,17 +415,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(&self.system_meta, world);
Param::apply(param_state, &self.system_meta, 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(<Param::State as SystemParamState>::init(
world,
&mut self.system_meta,
));
self.param_state = Some(Param::init_state(world, &mut self.system_meta));
}
fn update_archetype_component_access(&mut self, world: &World) {
@ -443,7 +433,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,
);
@ -514,7 +506,7 @@ impl<T> Copy for SystemTypeIdLabel<T> {}
/// pub fn pipe<AIn, Shared, BOut, A, AParam, AMarker, B, BParam, BMarker>(
/// mut a: A,
/// mut b: B,
/// ) -> impl FnMut(In<AIn>, ParamSet<(SystemParamItem<AParam>, SystemParamItem<BParam>)>) -> BOut
/// ) -> impl FnMut(In<AIn>, ParamSet<(AParam, BParam)>) -> BOut
/// where
/// // We need A and B to be systems, add those bounds
/// A: SystemParamFunction<AIn, Shared, AParam, AMarker>,

File diff suppressed because it is too large Load Diff

View File

@ -1,10 +1,7 @@
use crate::MainWorld;
use bevy_ecs::{
prelude::*,
system::{
ReadOnlySystemParam, ResState, SystemMeta, SystemParam, SystemParamItem, SystemParamState,
SystemState,
},
system::{ReadOnlySystemParam, SystemMeta, SystemParam, SystemParamItem, SystemState},
};
use std::ops::{Deref, DerefMut};
@ -49,42 +46,36 @@ where
item: SystemParamItem<'w, 's, P>,
}
impl<'w, 's, P> SystemParam for Extract<'w, 's, P>
#[doc(hidden)]
pub struct ExtractState<P: SystemParam + 'static> {
state: SystemState<P>,
main_world_state: <Res<'static, MainWorld> as SystemParam>::State,
}
// SAFETY: only accesses MainWorld resource with read only system params using Res,
// which is initialized in init()
unsafe impl<P> SystemParam for Extract<'_, '_, P>
where
P: ReadOnlySystemParam,
{
type State = ExtractState<P>;
}
#[doc(hidden)]
pub struct ExtractState<P: SystemParam + 'static> {
state: SystemState<P>,
main_world_state: ResState<MainWorld>,
}
// SAFETY: only accesses MainWorld resource with read only system params using ResState,
// which is initialized in init()
unsafe impl<P: SystemParam + 'static> SystemParamState for ExtractState<P>
where
P: ReadOnlySystemParam + 'static,
{
type Item<'w, 's> = Extract<'w, 's, P>;
fn init(world: &mut World, system_meta: &mut SystemMeta) -> Self {
fn init_state(world: &mut World, system_meta: &mut SystemMeta) -> Self::State {
let mut main_world = world.resource_mut::<MainWorld>();
Self {
ExtractState {
state: SystemState::new(&mut main_world),
main_world_state: ResState::init(world, system_meta),
main_world_state: Res::<MainWorld>::init_state(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::<MainWorld>::get_param(
let main_world = Res::<MainWorld>::get_param(
&mut state.main_world_state,
system_meta,
world,
@ -95,7 +86,7 @@ where
}
}
impl<'w, 's, P: SystemParam> Deref for Extract<'w, 's, P>
impl<'w, 's, P> Deref for Extract<'w, 's, P>
where
P: ReadOnlySystemParam,
{
@ -107,7 +98,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,
{
@ -117,7 +108,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,