Skip to content

Commit

Permalink
codedump
Browse files Browse the repository at this point in the history
  • Loading branch information
TheRawMeatball committed Sep 12, 2022
1 parent 1b97205 commit 9e526e7
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 17 deletions.
46 changes: 43 additions & 3 deletions crates/bevy_ecs/macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -374,13 +374,53 @@ pub fn derive_system_param(input: TokenStream) -> TokenStream {
let struct_name = &ast.ident;
let fetch_struct_visibility = &ast.vis;

// This exists so the macro doesn't depend on the built-in invocation of the system param tuple macro, which is capped at 16.
let tuple_independence_macro = {
let list = (0..field_types.len())
.map(|i| format!("T{i}"))
.map(|s| syn::Ident::new(&s, Span::call_site()))
.collect::<Punctuated<_, Token![,]>>();

quote! {
#[doc(hidden)]
#fetch_struct_visibility struct MyTuple<T>(T);

const _: () = {
use #path::{
archetype::Archetype,
world::World,
system::{
SystemParam, SystemParamFetch, SystemParamState, SystemMeta, ReadOnlySystemParamFetch, AsTuple,
},
};

impl<T> AsTuple for MyTuple<T> {
type Tuple = T;
fn as_tuple_mut(&mut self) -> &mut T {
&mut self.0
}
}

impl<T> From<T> for MyTuple<T> {
fn from(t: T) -> Self {
Self(t)
}
}

#path::system::impl_system_param_tuple_base!(MyTuple, #list);
};
}
};

TokenStream::from(quote! {
// We define the FetchState struct in an anonymous scope to avoid polluting the user namespace.
// The struct can still be accessed via SystemParam::Fetch, e.g. EventReaderState can be accessed via
// <EventReader<'static, 'static, T> as SystemParam>::Fetch
const _: () = {
#tuple_independence_macro

impl #impl_generics #path::system::SystemParam for #struct_name #ty_generics #where_clause {
type Fetch = FetchState <(#(<#field_types as #path::system::SystemParam>::Fetch,)*), #punctuated_generic_idents>;
type Fetch = FetchState <MyTuple<(#(<#field_types as #path::system::SystemParam>::Fetch,)*)>, #punctuated_generic_idents>;
}

#[doc(hidden)]
Expand All @@ -406,7 +446,7 @@ pub fn derive_system_param(input: TokenStream) -> TokenStream {
}
}

impl #impl_generics #path::system::SystemParamFetch<'w, 's> for FetchState <(#(<#field_types as #path::system::SystemParam>::Fetch,)*), #punctuated_generic_idents> #where_clause {
impl #impl_generics #path::system::SystemParamFetch<'w, 's> for FetchState <MyTuple<(#(<#field_types as #path::system::SystemParam>::Fetch,)*)>, #punctuated_generic_idents> #where_clause {
type Item = #struct_name #ty_generics;
unsafe fn get_param(
state: &'s mut Self,
Expand All @@ -415,7 +455,7 @@ pub fn derive_system_param(input: TokenStream) -> TokenStream {
change_tick: u32,
) -> Self::Item {
#struct_name {
#(#fields: <<#field_types as #path::system::SystemParam>::Fetch as #path::system::SystemParamFetch>::get_param(&mut state.state.#field_indices, system_meta, world, change_tick),)*
#(#fields: <<#field_types as #path::system::SystemParam>::Fetch as #path::system::SystemParamFetch>::get_param(&mut state.state.0.#field_indices, system_meta, world, change_tick),)*
#(#ignored_fields: <#ignored_field_types>::default(),)*
}
}
Expand Down
50 changes: 36 additions & 14 deletions crates/bevy_ecs/src/system/system_param.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1400,19 +1400,20 @@ impl<'w, 's> SystemParamFetch<'w, 's> for SystemNameState {
}
}

macro_rules! impl_system_param_tuple {
($($param: ident),*) => {
impl<$($param: SystemParam),*> SystemParam for ($($param,)*) {
type Fetch = ($($param::Fetch,)*);
#[macro_export]
macro_rules! impl_system_param_tuple_base {
($tuple:ident, $($param: ident),*) => {
impl<$($param: SystemParam),*> SystemParam for $tuple<($($param,)*)> {
type Fetch = $tuple<($($param::Fetch,)*)>;
}

// SAFETY: tuple consists only of ReadOnlySystemParamFetches
unsafe impl<$($param: ReadOnlySystemParamFetch),*> ReadOnlySystemParamFetch for ($($param,)*) {}
unsafe impl<$($param: ReadOnlySystemParamFetch),*> ReadOnlySystemParamFetch for $tuple<($($param,)*)> {}

#[allow(unused_variables)]
#[allow(non_snake_case)]
impl<'w, 's, $($param: SystemParamFetch<'w, 's>),*> SystemParamFetch<'w, 's> for ($($param,)*) {
type Item = ($($param::Item,)*);
impl<'w, 's, $($param: SystemParamFetch<'w, 's>),*> SystemParamFetch<'w, 's> for $tuple<($($param,)*)> {
type Item = $tuple<($($param::Item,)*)>;

#[inline]
#[allow(clippy::unused_unit)]
Expand All @@ -1422,36 +1423,57 @@ macro_rules! impl_system_param_tuple {
world: &'w World,
change_tick: u32,
) -> Self::Item {

let ($($param,)*) = state;
($($param::get_param($param, system_meta, world, change_tick),)*)
let ($($param,)*) = state.as_tuple_mut();
($($param::get_param($param, system_meta, world, change_tick),)*).into()
}
}

// 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: SystemParamState),*> SystemParamState for $tuple<($($param,)*)> {
#[inline]
fn init(_world: &mut World, _system_meta: &mut SystemMeta) -> Self {
(($($param::init(_world, _system_meta),)*))
(($($param::init(_world, _system_meta),)*)).into()
}

#[inline]
fn new_archetype(&mut self, _archetype: &Archetype, _system_meta: &mut SystemMeta) {
let ($($param,)*) = self;
let ($($param,)*) = self.as_tuple_mut();
$($param.new_archetype(_archetype, _system_meta);)*
}

#[inline]
fn apply(&mut self, _world: &mut World) {
let ($($param,)*) = self;
let ($($param,)*) = self.as_tuple_mut();
$($param.apply(_world);)*
}
}
};
}

pub use impl_system_param_tuple_base;

#[doc(hidden)]
pub trait AsTuple {
type Tuple;
fn as_tuple_mut(&mut self) -> &mut Self::Tuple;
}

type Identity<T> = T;
macro_rules! impl_system_param_tuple {
($($param: ident),*) => {
impl_system_param_tuple_base!(Identity, $($param),*);

impl<$($param,)*> AsTuple for ($($param,)*) {
type Tuple = Self;
fn as_tuple_mut(&mut self) -> &mut Self {
self
}
}
};
}

all_tuples!(impl_system_param_tuple, 0, 16, P);

pub mod lifetimeless {
Expand Down

0 comments on commit 9e526e7

Please sign in to comment.