mirror of
https://github.com/bevyengine/bevy
synced 2024-11-10 07:04:33 +00:00
allow up to 16 parameters for systems (#1805)
fixes #1772 1st commit: the limit was at 11 as the macro was not using a range including the upper end. I changed that as it feels the purpose of the macro is clearer that way. 2nd commit: as suggested in the `// TODO`, I added a `Config` trait to go to 16 elements tuples. This means that if someone has a custom system parameter with a config that is not a tuple or an `Option`, they will have to implement `Config` for it instead of the standard `Default`.
This commit is contained in:
parent
1df3b74d38
commit
276a81cc30
4 changed files with 100 additions and 9 deletions
|
@ -45,9 +45,9 @@ impl Parse for AllTuples {
|
|||
#[proc_macro]
|
||||
pub fn all_tuples(input: TokenStream) -> TokenStream {
|
||||
let input = parse_macro_input!(input as AllTuples);
|
||||
let len = input.end - input.start;
|
||||
let len = (input.start..=input.end).count();
|
||||
let mut ident_tuples = Vec::with_capacity(len);
|
||||
for i in input.start..input.end {
|
||||
for i in input.start..=input.end {
|
||||
let idents = input
|
||||
.idents
|
||||
.iter()
|
||||
|
@ -64,7 +64,7 @@ pub fn all_tuples(input: TokenStream) -> TokenStream {
|
|||
}
|
||||
|
||||
let macro_ident = &input.macro_ident;
|
||||
let invocations = (input.start..input.end).map(|i| {
|
||||
let invocations = (input.start..=input.end).map(|i| {
|
||||
let ident_tuples = &ident_tuples[0..i];
|
||||
quote! {
|
||||
#macro_ident!(#(#ident_tuples),*);
|
||||
|
@ -259,6 +259,8 @@ pub fn impl_query_set(_input: TokenStream) -> TokenStream {
|
|||
.extend(&#query.archetype_component_access);
|
||||
)*
|
||||
}
|
||||
|
||||
fn default_config() {}
|
||||
}
|
||||
|
||||
impl<'a, #(#query: WorldQuery + 'static,)* #(#filter: WorldQuery + 'static,)*> SystemParamFetch<'a> for QuerySetState<(#(QueryState<#query, #filter>,)*)>
|
||||
|
@ -394,6 +396,10 @@ pub fn derive_system_param(input: TokenStream) -> TokenStream {
|
|||
fn new_archetype(&mut self, archetype: &#path::archetype::Archetype, system_state: &mut #path::system::SystemState) {
|
||||
self.state.new_archetype(archetype, system_state)
|
||||
}
|
||||
|
||||
fn default_config() -> TSystemParamState::Config {
|
||||
TSystemParamState::default_config()
|
||||
}
|
||||
}
|
||||
|
||||
impl #impl_generics #path::system::SystemParamFetch<'a> for #fetch_struct_name <(#(<#field_types as SystemParam>::Fetch,)*), #punctuated_generic_idents> {
|
||||
|
|
|
@ -92,7 +92,7 @@ where
|
|||
FunctionSystem {
|
||||
func: self,
|
||||
param_state: None,
|
||||
config: Some(Default::default()),
|
||||
config: Some(<Param::Fetch as SystemParamState>::default_config()),
|
||||
system_state: SystemState::new::<F>(),
|
||||
marker: PhantomData,
|
||||
}
|
||||
|
@ -227,4 +227,4 @@ macro_rules! impl_system_function {
|
|||
};
|
||||
}
|
||||
|
||||
all_tuples!(impl_system_function, 0, 12, F);
|
||||
all_tuples!(impl_system_function, 0, 16, F);
|
||||
|
|
|
@ -38,6 +38,8 @@ mod tests {
|
|||
struct B;
|
||||
struct C;
|
||||
struct D;
|
||||
struct E;
|
||||
struct F;
|
||||
|
||||
#[test]
|
||||
fn simple_system() {
|
||||
|
@ -435,4 +437,52 @@ mod tests {
|
|||
let d_id = world.components().get_id(TypeId::of::<D>()).unwrap();
|
||||
assert_eq!(conflicts, vec![b_id, d_id]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn can_have_16_parameters() {
|
||||
fn sys_x(
|
||||
_: Res<A>,
|
||||
_: Res<B>,
|
||||
_: Res<C>,
|
||||
_: Res<D>,
|
||||
_: Res<E>,
|
||||
_: Res<F>,
|
||||
_: Query<&A>,
|
||||
_: Query<&B>,
|
||||
_: Query<&C>,
|
||||
_: Query<&D>,
|
||||
_: Query<&E>,
|
||||
_: Query<&F>,
|
||||
_: Query<(&A, &B)>,
|
||||
_: Query<(&C, &D)>,
|
||||
_: Query<(&E, &F)>,
|
||||
) {
|
||||
}
|
||||
fn sys_y(
|
||||
_: (
|
||||
Res<A>,
|
||||
Res<B>,
|
||||
Res<C>,
|
||||
Res<D>,
|
||||
Res<E>,
|
||||
Res<F>,
|
||||
Query<&A>,
|
||||
Query<&B>,
|
||||
Query<&C>,
|
||||
Query<&D>,
|
||||
Query<&E>,
|
||||
Query<&F>,
|
||||
Query<(&A, &B)>,
|
||||
Query<(&C, &D)>,
|
||||
Query<(&E, &F)>,
|
||||
),
|
||||
) {
|
||||
}
|
||||
let mut world = World::default();
|
||||
let mut x = sys_x.system();
|
||||
let mut y = sys_y.system();
|
||||
x.initialize(&mut world);
|
||||
y.initialize(&mut world);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,12 +42,13 @@ pub trait SystemParam: Sized {
|
|||
/// Additionally, it is the implementor's responsibility to ensure there is no
|
||||
/// conflicting access across all SystemParams.
|
||||
pub unsafe trait SystemParamState: Send + Sync + 'static {
|
||||
type Config: Default + Send + Sync;
|
||||
type Config: Send + Sync;
|
||||
fn init(world: &mut World, system_state: &mut SystemState, config: Self::Config) -> Self;
|
||||
#[inline]
|
||||
fn new_archetype(&mut self, _archetype: &Archetype, _system_state: &mut SystemState) {}
|
||||
#[inline]
|
||||
fn apply(&mut self, _world: &mut World) {}
|
||||
fn default_config() -> Self::Config;
|
||||
}
|
||||
|
||||
pub trait SystemParamFetch<'a>: SystemParamState {
|
||||
|
@ -105,6 +106,8 @@ where
|
|||
.archetype_component_access
|
||||
.extend(&self.archetype_component_access);
|
||||
}
|
||||
|
||||
fn default_config() {}
|
||||
}
|
||||
|
||||
impl<'a, Q: WorldQuery + 'static, F: WorldQuery + 'static> SystemParamFetch<'a> for QueryState<Q, F>
|
||||
|
@ -221,6 +224,8 @@ unsafe impl<T: Component> SystemParamState for ResState<T> {
|
|||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
fn default_config() {}
|
||||
}
|
||||
|
||||
impl<'a, T: Component> SystemParamFetch<'a> for ResState<T> {
|
||||
|
@ -262,6 +267,8 @@ unsafe impl<T: Component> SystemParamState for OptionResState<T> {
|
|||
fn init(world: &mut World, system_state: &mut SystemState, _config: Self::Config) -> Self {
|
||||
Self(ResState::init(world, system_state, ()))
|
||||
}
|
||||
|
||||
fn default_config() {}
|
||||
}
|
||||
|
||||
impl<'a, T: Component> SystemParamFetch<'a> for OptionResState<T> {
|
||||
|
@ -367,6 +374,8 @@ unsafe impl<T: Component> SystemParamState for ResMutState<T> {
|
|||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
fn default_config() {}
|
||||
}
|
||||
|
||||
impl<'a, T: Component> SystemParamFetch<'a> for ResMutState<T> {
|
||||
|
@ -408,6 +417,8 @@ unsafe impl<T: Component> SystemParamState for OptionResMutState<T> {
|
|||
fn init(world: &mut World, system_state: &mut SystemState, _config: Self::Config) -> Self {
|
||||
Self(ResMutState::init(world, system_state, ()))
|
||||
}
|
||||
|
||||
fn default_config() {}
|
||||
}
|
||||
|
||||
impl<'a, T: Component> SystemParamFetch<'a> for OptionResMutState<T> {
|
||||
|
@ -446,6 +457,8 @@ unsafe impl SystemParamState for CommandQueue {
|
|||
fn apply(&mut self, world: &mut World) {
|
||||
self.apply(world);
|
||||
}
|
||||
|
||||
fn default_config() {}
|
||||
}
|
||||
|
||||
impl<'a> SystemParamFetch<'a> for CommandQueue {
|
||||
|
@ -493,6 +506,10 @@ unsafe impl<T: Component + FromWorld> SystemParamState for LocalState<T> {
|
|||
fn init(world: &mut World, _system_state: &mut SystemState, config: Self::Config) -> Self {
|
||||
Self(config.unwrap_or_else(|| T::from_world(world)))
|
||||
}
|
||||
|
||||
fn default_config() -> Option<T> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: Component + FromWorld> SystemParamFetch<'a> for LocalState<T> {
|
||||
|
@ -541,6 +558,8 @@ unsafe impl<T: Component> SystemParamState for RemovedComponentsState<T> {
|
|||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
fn default_config() {}
|
||||
}
|
||||
|
||||
impl<'a, T: Component> SystemParamFetch<'a> for RemovedComponentsState<T> {
|
||||
|
@ -630,6 +649,8 @@ unsafe impl<T: 'static> SystemParamState for NonSendState<T> {
|
|||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
fn default_config() {}
|
||||
}
|
||||
|
||||
impl<'a, T: 'static> SystemParamFetch<'a> for NonSendState<T> {
|
||||
|
@ -748,6 +769,8 @@ unsafe impl<T: 'static> SystemParamState for NonSendMutState<T> {
|
|||
marker: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
fn default_config() {}
|
||||
}
|
||||
|
||||
impl<'a, T: 'static> SystemParamFetch<'a> for NonSendMutState<T> {
|
||||
|
@ -793,6 +816,8 @@ unsafe impl SystemParamState for ArchetypesState {
|
|||
fn init(_world: &mut World, _system_state: &mut SystemState, _config: Self::Config) -> Self {
|
||||
Self
|
||||
}
|
||||
|
||||
fn default_config() {}
|
||||
}
|
||||
|
||||
impl<'a> SystemParamFetch<'a> for ArchetypesState {
|
||||
|
@ -822,6 +847,8 @@ unsafe impl SystemParamState for ComponentsState {
|
|||
fn init(_world: &mut World, _system_state: &mut SystemState, _config: Self::Config) -> Self {
|
||||
Self
|
||||
}
|
||||
|
||||
fn default_config() {}
|
||||
}
|
||||
|
||||
impl<'a> SystemParamFetch<'a> for ComponentsState {
|
||||
|
@ -851,6 +878,8 @@ unsafe impl SystemParamState for EntitiesState {
|
|||
fn init(_world: &mut World, _system_state: &mut SystemState, _config: Self::Config) -> Self {
|
||||
Self
|
||||
}
|
||||
|
||||
fn default_config() {}
|
||||
}
|
||||
|
||||
impl<'a> SystemParamFetch<'a> for EntitiesState {
|
||||
|
@ -880,6 +909,8 @@ unsafe impl SystemParamState for BundlesState {
|
|||
fn init(_world: &mut World, _system_state: &mut SystemState, _config: Self::Config) -> Self {
|
||||
Self
|
||||
}
|
||||
|
||||
fn default_config() {}
|
||||
}
|
||||
|
||||
impl<'a> SystemParamFetch<'a> for BundlesState {
|
||||
|
@ -914,6 +945,8 @@ unsafe impl SystemParamState for SystemChangeTickState {
|
|||
fn init(_world: &mut World, _system_state: &mut SystemState, _config: Self::Config) -> Self {
|
||||
Self {}
|
||||
}
|
||||
|
||||
fn default_config() {}
|
||||
}
|
||||
|
||||
impl<'a> SystemParamFetch<'a> for SystemChangeTickState {
|
||||
|
@ -976,10 +1009,12 @@ macro_rules! impl_system_param_tuple {
|
|||
let ($($param,)*) = self;
|
||||
$($param.apply(_world);)*
|
||||
}
|
||||
|
||||
fn default_config() -> ($(<$param as SystemParamState>::Config,)*) {
|
||||
($(<$param as SystemParamState>::default_config(),)*)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// TODO: consider creating a Config trait with a default() function, then implementing that for
|
||||
// tuples. that would allow us to go past tuples of len 12
|
||||
all_tuples!(impl_system_param_tuple, 0, 12, P);
|
||||
all_tuples!(impl_system_param_tuple, 0, 16, P);
|
||||
|
|
Loading…
Reference in a new issue