From df332f78001e5a92809a86d64ecd493bee77720f Mon Sep 17 00:00:00 2001 From: Carter Anderson Date: Sat, 14 Nov 2020 13:43:01 -0800 Subject: [PATCH 1/7] result systems --- crates/bevy_ecs/macros/src/lib.rs | 4 +-- .../bevy_ecs/src/resource/resource_query.rs | 4 +-- .../src/schedule/parallel_executor.rs | 5 +++- crates/bevy_ecs/src/schedule/schedule.rs | 4 ++- crates/bevy_ecs/src/system/into_system.rs | 29 +++++++++---------- .../bevy_ecs/src/system/into_thread_local.rs | 4 ++- crates/bevy_ecs/src/system/system.rs | 12 ++++++-- 7 files changed, 37 insertions(+), 25 deletions(-) diff --git a/crates/bevy_ecs/macros/src/lib.rs b/crates/bevy_ecs/macros/src/lib.rs index 44d605aa8c9d3..a2b1b2ce97b72 100644 --- a/crates/bevy_ecs/macros/src/lib.rs +++ b/crates/bevy_ecs/macros/src/lib.rs @@ -408,12 +408,12 @@ pub fn derive_system_param(input: TokenStream) -> TokenStream { } let generics = ast.generics; - let (impl_generics, ty_generics, _where_clause) = generics.split_for_impl(); + let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); let struct_name = &ast.ident; TokenStream::from(quote! { - impl #impl_generics #path::SystemParam for #struct_name#ty_generics { + impl #impl_generics #path::SystemParam for #struct_name#ty_generics #where_clause { fn init(system_state: &mut #path::SystemState, world: &#path::World, resources: &mut #path::Resources) { #(<#field_types>::init(system_state, world, resources);)* } diff --git a/crates/bevy_ecs/src/resource/resource_query.rs b/crates/bevy_ecs/src/resource/resource_query.rs index c6e3c4bf61372..ef4d560dfd0bb 100644 --- a/crates/bevy_ecs/src/resource/resource_query.rs +++ b/crates/bevy_ecs/src/resource/resource_query.rs @@ -1,10 +1,10 @@ use super::FromResources; use crate::{Resource, ResourceIndex, Resources, SystemId}; -use core::{ +use std::{ + marker::PhantomData, ops::{Deref, DerefMut}, ptr::NonNull, }; -use std::marker::PhantomData; // TODO: align TypeAccess api with Query::Fetch diff --git a/crates/bevy_ecs/src/schedule/parallel_executor.rs b/crates/bevy_ecs/src/schedule/parallel_executor.rs index d0b9aec1af403..72eeb82a55d7e 100644 --- a/crates/bevy_ecs/src/schedule/parallel_executor.rs +++ b/crates/bevy_ecs/src/schedule/parallel_executor.rs @@ -402,7 +402,10 @@ impl ExecutorStage { #[cfg(feature = "trace")] let _system_guard = system_span.enter(); - system.run(world_ref, resources_ref); + // SAFETY: scheduler ensures safe world / resource access + unsafe { + system.run_unsafe(world_ref, resources_ref); + } } // Notify dependents that this task is done diff --git a/crates/bevy_ecs/src/schedule/schedule.rs b/crates/bevy_ecs/src/schedule/schedule.rs index 881991c282f8c..8fdc4fe95b5d3 100644 --- a/crates/bevy_ecs/src/schedule/schedule.rs +++ b/crates/bevy_ecs/src/schedule/schedule.rs @@ -150,7 +150,9 @@ impl Schedule { for system in stage_systems.iter_mut() { system.update(world); match system.thread_local_execution() { - ThreadLocalExecution::NextFlush => system.run(world, resources), + ThreadLocalExecution::NextFlush => { + system.run(world, resources); + } ThreadLocalExecution::Immediate => { system.run(world, resources); // NOTE: when this is made parallel a full sync is required here diff --git a/crates/bevy_ecs/src/system/into_system.rs b/crates/bevy_ecs/src/system/into_system.rs index 7fcfa1548476d..d7ddcac6d9299 100644 --- a/crates/bevy_ecs/src/system/into_system.rs +++ b/crates/bevy_ecs/src/system/into_system.rs @@ -1,7 +1,4 @@ -use crate::{ - ArchetypeComponent, Commands, QueryAccess, Resources, System, SystemId, SystemParam, - ThreadLocalExecution, TypeAccess, World, -}; +use crate::{ArchetypeComponent, Commands, QueryAccess, Resources, System, SystemId, SystemParam, ThreadLocalExecution, TypeAccess, World}; use parking_lot::Mutex; use std::{any::TypeId, borrow::Cow, sync::Arc}; @@ -73,9 +70,9 @@ impl SystemState { } } -pub struct FuncSystem +pub struct FuncSystem where - F: FnMut(&mut SystemState, &World, &Resources) + Send + Sync + 'static, + F: FnMut(&mut SystemState, &World, &Resources) -> Option + Send + Sync + 'static, Init: FnMut(&mut SystemState, &World, &mut Resources) + Send + Sync + 'static, ThreadLocalFunc: FnMut(&mut SystemState, &mut World, &mut Resources) + Send + Sync + 'static, { @@ -85,9 +82,9 @@ where state: SystemState, } -impl System for FuncSystem +impl System for FuncSystem where - F: FnMut(&mut SystemState, &World, &Resources) + Send + Sync + 'static, + F: FnMut(&mut SystemState, &World, &Resources) -> Option + Send + Sync + 'static, Init: FnMut(&mut SystemState, &World, &mut Resources) + Send + Sync + 'static, ThreadLocalFunc: FnMut(&mut SystemState, &mut World, &mut Resources) + Send + Sync + 'static, { @@ -115,7 +112,7 @@ where ThreadLocalExecution::NextFlush } - fn run(&mut self, world: &World, resources: &Resources) { + unsafe fn run_unsafe(&mut self, world: &World, resources: &Resources) -> Option { (self.func)(&mut self.state, world, resources) } @@ -133,19 +130,19 @@ where } } -pub trait IntoSystem { - fn system(self) -> Box; +pub trait IntoSystem { + fn system(self) -> Box>; } macro_rules! impl_into_system { ($($param: ident),*) => { - impl IntoSystem<($($param,)*)> for Func - where Func: FnMut($($param),*) + Send + Sync + 'static, + impl IntoSystem<($($param,)*), Return> for Func + where Func: FnMut($($param),*) -> Return + Send + Sync + 'static, Return: 'static { #[allow(unused_variables)] #[allow(unused_unsafe)] #[allow(non_snake_case)] - fn system(mut self) -> Box { + fn system(mut self) -> Box> { Box::new(FuncSystem { state: SystemState { name: std::any::type_name::().into(), @@ -165,7 +162,9 @@ macro_rules! impl_into_system { state.reset_indices(); unsafe { if let Some(($($param,)*)) = <($($param,)*)>::get_param(state, world, resources) { - self($($param),*); + Some(self($($param),*)) + } else { + None } } }, diff --git a/crates/bevy_ecs/src/system/into_thread_local.rs b/crates/bevy_ecs/src/system/into_thread_local.rs index 876cd94798b3f..d0df231f80f37 100644 --- a/crates/bevy_ecs/src/system/into_thread_local.rs +++ b/crates/bevy_ecs/src/system/into_thread_local.rs @@ -40,7 +40,9 @@ where ThreadLocalExecution::Immediate } - fn run(&mut self, _world: &World, _resources: &Resources) {} + unsafe fn run_unsafe(&mut self, _world: &World, _resources: &Resources) -> Option<()> { + Some(()) + } fn run_thread_local(&mut self, world: &mut World, resources: &mut Resources) { (self.func)(world, resources); diff --git a/crates/bevy_ecs/src/system/system.rs b/crates/bevy_ecs/src/system/system.rs index 24a5e015f9969..98f73a8eb6494 100644 --- a/crates/bevy_ecs/src/system/system.rs +++ b/crates/bevy_ecs/src/system/system.rs @@ -19,7 +19,7 @@ impl SystemId { } /// An ECS system that can be added to a [Schedule](crate::Schedule) -pub trait System: Send + Sync { +pub trait System: Send + Sync { fn name(&self) -> Cow<'static, str>; fn id(&self) -> SystemId; fn is_initialized(&self) -> bool; @@ -27,7 +27,13 @@ pub trait System: Send + Sync { fn archetype_component_access(&self) -> &TypeAccess; fn resource_access(&self) -> &TypeAccess; fn thread_local_execution(&self) -> ThreadLocalExecution; - fn run(&mut self, world: &World, resources: &Resources); + unsafe fn run_unsafe(&mut self, world: &World, resources: &Resources) -> Option; + fn run(&mut self, world: &mut World, resources: &mut Resources) -> Option { + // SAFE: world and resources are exclusively borrowed + unsafe { + self.run_unsafe(world, resources) + } + } fn run_thread_local(&mut self, world: &mut World, resources: &mut Resources); fn initialize(&mut self, _world: &mut World, _resources: &mut Resources) {} -} +} \ No newline at end of file From c08cfb7b1669eebe23098be0812c1d55e4e2a1c0 Mon Sep 17 00:00:00 2001 From: Carter Anderson Date: Sat, 14 Nov 2020 17:02:08 -0800 Subject: [PATCH 2/7] System Input, Chaining, and Filling --- crates/bevy_ecs/macros/src/lib.rs | 7 +- crates/bevy_ecs/src/lib.rs | 2 +- .../src/schedule/parallel_executor.rs | 4 +- crates/bevy_ecs/src/schedule/schedule.rs | 4 +- crates/bevy_ecs/src/system/into_system.rs | 41 ++++-- .../bevy_ecs/src/system/into_thread_local.rs | 2 +- crates/bevy_ecs/src/system/system.rs | 136 +++++++++++++++++- crates/bevy_ecs/src/system/system_param.rs | 55 +++++-- crates/bevy_render/src/draw.rs | 2 +- 9 files changed, 211 insertions(+), 42 deletions(-) diff --git a/crates/bevy_ecs/macros/src/lib.rs b/crates/bevy_ecs/macros/src/lib.rs index a2b1b2ce97b72..ded3e92a80197 100644 --- a/crates/bevy_ecs/macros/src/lib.rs +++ b/crates/bevy_ecs/macros/src/lib.rs @@ -413,18 +413,19 @@ pub fn derive_system_param(input: TokenStream) -> TokenStream { let struct_name = &ast.ident; TokenStream::from(quote! { - impl #impl_generics #path::SystemParam for #struct_name#ty_generics #where_clause { + impl #impl_generics #path::SystemParam<()> for #struct_name#ty_generics #where_clause { fn init(system_state: &mut #path::SystemState, world: &#path::World, resources: &mut #path::Resources) { - #(<#field_types>::init(system_state, world, resources);)* + #(<#field_types as SystemParam<()>>::init(system_state, world, resources);)* } unsafe fn get_param( + input: &mut Option<()>, system_state: &mut #path::SystemState, world: &#path::World, resources: &#path::Resources, ) -> Option { Some(#struct_name { - #(#fields: <#field_types>::get_param(system_state, world, resources)?,)* + #(#fields: <#field_types as SystemParam<()>>::get_param(input, system_state, world, resources)?,)* #(#ignored_fields: <#ignored_field_types>::default(),)* }) } diff --git a/crates/bevy_ecs/src/lib.rs b/crates/bevy_ecs/src/lib.rs index c90bf23688ada..a5adc053ca3fb 100644 --- a/crates/bevy_ecs/src/lib.rs +++ b/crates/bevy_ecs/src/lib.rs @@ -16,6 +16,6 @@ pub mod prelude { resource::{ChangedRes, FromResources, Local, Res, ResMut, Resource, Resources}, system::{Commands, IntoSystem, IntoThreadLocalSystem, Query, System}, Added, Bundle, Changed, Component, Entity, Mut, Mutated, Or, QuerySet, Ref, RefMut, With, - Without, World, + Without, World, AsChainSystem, FillSystemInput }; } diff --git a/crates/bevy_ecs/src/schedule/parallel_executor.rs b/crates/bevy_ecs/src/schedule/parallel_executor.rs index 72eeb82a55d7e..4479bc55cf901 100644 --- a/crates/bevy_ecs/src/schedule/parallel_executor.rs +++ b/crates/bevy_ecs/src/schedule/parallel_executor.rs @@ -404,7 +404,7 @@ impl ExecutorStage { // SAFETY: scheduler ensures safe world / resource access unsafe { - system.run_unsafe(world_ref, resources_ref); + system.run_unsafe((), world_ref, resources_ref); } } @@ -502,7 +502,7 @@ impl ExecutorStage { #[cfg(feature = "trace")] let _system_guard = system_span.enter(); - system.run(world, resources); + system.run((), world, resources); system.run_thread_local(world, resources); } diff --git a/crates/bevy_ecs/src/schedule/schedule.rs b/crates/bevy_ecs/src/schedule/schedule.rs index 8fdc4fe95b5d3..9de6fe17670b7 100644 --- a/crates/bevy_ecs/src/schedule/schedule.rs +++ b/crates/bevy_ecs/src/schedule/schedule.rs @@ -151,10 +151,10 @@ impl Schedule { system.update(world); match system.thread_local_execution() { ThreadLocalExecution::NextFlush => { - system.run(world, resources); + system.run((), world, resources); } ThreadLocalExecution::Immediate => { - system.run(world, resources); + system.run((), world, resources); // NOTE: when this is made parallel a full sync is required here system.run_thread_local(world, resources); } diff --git a/crates/bevy_ecs/src/system/into_system.rs b/crates/bevy_ecs/src/system/into_system.rs index d7ddcac6d9299..6493ebaa6386a 100644 --- a/crates/bevy_ecs/src/system/into_system.rs +++ b/crates/bevy_ecs/src/system/into_system.rs @@ -1,6 +1,6 @@ use crate::{ArchetypeComponent, Commands, QueryAccess, Resources, System, SystemId, SystemParam, ThreadLocalExecution, TypeAccess, World}; use parking_lot::Mutex; -use std::{any::TypeId, borrow::Cow, sync::Arc}; +use std::{any::TypeId, borrow::Cow, sync::Arc, marker::PhantomData}; pub struct SystemState { pub(crate) id: SystemId, @@ -70,9 +70,9 @@ impl SystemState { } } -pub struct FuncSystem +pub struct FuncSystem where - F: FnMut(&mut SystemState, &World, &Resources) -> Option + Send + Sync + 'static, + F: FnMut(Input, &mut SystemState, &World, &Resources) -> Option + Send + Sync + 'static, Init: FnMut(&mut SystemState, &World, &mut Resources) + Send + Sync + 'static, ThreadLocalFunc: FnMut(&mut SystemState, &mut World, &mut Resources) + Send + Sync + 'static, { @@ -80,11 +80,21 @@ where thread_local_func: ThreadLocalFunc, init_func: Init, state: SystemState, + marker: SendSyncPhantomData<(Input, Return)>, } -impl System for FuncSystem +struct SendSyncPhantomData(PhantomData); +impl Default for SendSyncPhantomData { + fn default() -> Self { + SendSyncPhantomData(Default::default()) + } +} +unsafe impl Send for SendSyncPhantomData {} +unsafe impl Sync for SendSyncPhantomData {} + +impl System for FuncSystem where - F: FnMut(&mut SystemState, &World, &Resources) -> Option + Send + Sync + 'static, + F: FnMut(Input, &mut SystemState, &World, &Resources) -> Option + Send + Sync + 'static, Init: FnMut(&mut SystemState, &World, &mut Resources) + Send + Sync + 'static, ThreadLocalFunc: FnMut(&mut SystemState, &mut World, &mut Resources) + Send + Sync + 'static, { @@ -112,8 +122,8 @@ where ThreadLocalExecution::NextFlush } - unsafe fn run_unsafe(&mut self, world: &World, resources: &Resources) -> Option { - (self.func)(&mut self.state, world, resources) + unsafe fn run_unsafe(&mut self, input: Input, world: &World, resources: &Resources) -> Option { + (self.func)(input, &mut self.state, world, resources) } fn run_thread_local(&mut self, world: &mut World, resources: &mut Resources) { @@ -130,19 +140,19 @@ where } } -pub trait IntoSystem { - fn system(self) -> Box>; +pub trait IntoSystem { + fn system(self) -> Box>; } macro_rules! impl_into_system { ($($param: ident),*) => { - impl IntoSystem<($($param,)*), Return> for Func - where Func: FnMut($($param),*) -> Return + Send + Sync + 'static, Return: 'static + impl),*> IntoSystem<($($param,)*), Input, Return> for Func + where Func: FnMut($($param),*) -> Return + Send + Sync + 'static, Return: 'static, Input: 'static { #[allow(unused_variables)] #[allow(unused_unsafe)] #[allow(non_snake_case)] - fn system(mut self) -> Box> { + fn system(mut self) -> Box> { Box::new(FuncSystem { state: SystemState { name: std::any::type_name::().into(), @@ -158,10 +168,11 @@ macro_rules! impl_into_system { query_type_names: Vec::new(), current_query_index: 0, }, - func: move |state, world, resources| { + func: move |input, state, world, resources| { state.reset_indices(); + let mut input = Some(input); unsafe { - if let Some(($($param,)*)) = <($($param,)*)>::get_param(state, world, resources) { + if let Some(($($param,)*)) = <($($param,)*)>::get_param(&mut input, state, world, resources) { Some(self($($param),*)) } else { None @@ -178,10 +189,10 @@ macro_rules! impl_into_system { init_func: |state, world, resources| { $($param::init(state, world, resources);)* }, + marker: Default::default(), }) } } - }; } diff --git a/crates/bevy_ecs/src/system/into_thread_local.rs b/crates/bevy_ecs/src/system/into_thread_local.rs index d0df231f80f37..fd3ac195d7102 100644 --- a/crates/bevy_ecs/src/system/into_thread_local.rs +++ b/crates/bevy_ecs/src/system/into_thread_local.rs @@ -40,7 +40,7 @@ where ThreadLocalExecution::Immediate } - unsafe fn run_unsafe(&mut self, _world: &World, _resources: &Resources) -> Option<()> { + unsafe fn run_unsafe(&mut self, input: (), _world: &World, _resources: &Resources) -> Option<()> { Some(()) } diff --git a/crates/bevy_ecs/src/system/system.rs b/crates/bevy_ecs/src/system/system.rs index 98f73a8eb6494..aab18e1364e5b 100644 --- a/crates/bevy_ecs/src/system/system.rs +++ b/crates/bevy_ecs/src/system/system.rs @@ -19,7 +19,7 @@ impl SystemId { } /// An ECS system that can be added to a [Schedule](crate::Schedule) -pub trait System: Send + Sync { +pub trait System: Send + Sync { fn name(&self) -> Cow<'static, str>; fn id(&self) -> SystemId; fn is_initialized(&self) -> bool; @@ -27,13 +27,141 @@ pub trait System: Send + Sync { fn archetype_component_access(&self) -> &TypeAccess; fn resource_access(&self) -> &TypeAccess; fn thread_local_execution(&self) -> ThreadLocalExecution; - unsafe fn run_unsafe(&mut self, world: &World, resources: &Resources) -> Option; - fn run(&mut self, world: &mut World, resources: &mut Resources) -> Option { + unsafe fn run_unsafe(&mut self, input: Input, world: &World, resources: &Resources) -> Option; + fn run(&mut self, input: Input, world: &mut World, resources: &mut Resources) -> Option { // SAFE: world and resources are exclusively borrowed unsafe { - self.run_unsafe(world, resources) + self.run_unsafe(input, world, resources) } } fn run_thread_local(&mut self, world: &mut World, resources: &mut Resources); fn initialize(&mut self, _world: &mut World, _resources: &mut Resources) {} +} + +pub struct ChainSystem { + a: Box>, + b: Box>, + name: Cow<'static, str>, + id: SystemId, + pub(crate) archetype_component_access: TypeAccess, + pub(crate) resource_access: TypeAccess, +} + +impl System for ChainSystem { + fn name(&self) -> Cow<'static, str> { + self.name.clone() + } + + fn id(&self) -> SystemId { + self.id + } + + fn is_initialized(&self) -> bool { + self.a.is_initialized() && self.b.is_initialized() + } + + fn update(&mut self, world: &World) { + self.archetype_component_access.clear(); + self.resource_access.clear(); + self.a.update(world); + self.b.update(world); + + self.archetype_component_access.union(self.a.archetype_component_access()); + self.resource_access.union(self.b.resource_access()); + } + + fn archetype_component_access(&self) -> &TypeAccess { + &self.archetype_component_access + } + + fn resource_access(&self) -> &TypeAccess { + &self.resource_access + } + + fn thread_local_execution(&self) -> ThreadLocalExecution { + ThreadLocalExecution::NextFlush + } + + unsafe fn run_unsafe(&mut self, input: AIn, world: &World, resources: &Resources) -> Option { + let out = self.a.run_unsafe(input, world, resources).unwrap(); + self.b.run_unsafe(out, world, resources) + } + + fn run_thread_local(&mut self, world: &mut World, resources: &mut Resources) { + self.a.run_thread_local(world, resources); + self.b.run_thread_local(world, resources); + } +} + +pub trait AsChainSystem { + fn chain(self, system: Box>) -> Box>; +} + +impl AsChainSystem for Box> { + fn chain(self, system: Box>) -> Box> { + Box::new(ChainSystem { + name: Cow::Owned(format!("Chain({}, {})", self.name(), system.name())), + a: self, + b: system, + archetype_component_access: Default::default(), + resource_access: Default::default(), + id: SystemId::new(), + }) + } +} + +pub struct FilledInputSystem { + system: Box>, + input: Input, +} + +impl System<(), Output> for FilledInputSystem { + fn name(&self) -> Cow<'static, str> { + self.system.name() + } + + fn id(&self) -> SystemId { + self.system.id() + } + + fn is_initialized(&self) -> bool { + self.system.is_initialized() + } + + fn update(&mut self, world: &World) { + self.system.update(world); + } + + fn archetype_component_access(&self) -> &TypeAccess { + self.system.archetype_component_access() + } + + fn resource_access(&self) -> &TypeAccess { + self.system.resource_access() + } + + fn thread_local_execution(&self) -> ThreadLocalExecution { + self.system.thread_local_execution() + } + + unsafe fn run_unsafe(&mut self, _input: (), world: &World, resources: &Resources) -> Option { + self.system.run_unsafe(self.input.clone(), world, resources) + } + + fn run_thread_local(&mut self, world: &mut World, resources: &mut Resources) { + self.system.run_thread_local(world, resources); + } +} + +pub trait FillSystemInput { + fn input(self, input: Input) -> Box>; +} + +impl FillSystemInput for Box> { + fn input(self, input: Input) -> Box> { + Box::new(FilledInputSystem { + system: self, + input, + }) + } } \ No newline at end of file diff --git a/crates/bevy_ecs/src/system/system_param.rs b/crates/bevy_ecs/src/system/system_param.rs index e727c5187780f..339f9e50cc5d1 100644 --- a/crates/bevy_ecs/src/system/system_param.rs +++ b/crates/bevy_ecs/src/system/system_param.rs @@ -6,21 +6,41 @@ use crate::{ use parking_lot::Mutex; use std::{any::TypeId, sync::Arc}; -pub trait SystemParam: Sized { +pub struct In(pub Input); + +impl SystemParam for In { + #[inline] + unsafe fn get_param( + input: &mut Option, + system_state: &mut SystemState, + world: &World, + _resources: &Resources, + ) -> Option { + Some(In(input.take().unwrap())) + } + + fn init(system_state: &mut SystemState, _world: &World, _resources: &mut Resources) { + } +} + + +pub trait SystemParam: Sized { fn init(system_state: &mut SystemState, world: &World, resources: &mut Resources); /// # 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( + input: &mut Option, system_state: &mut SystemState, world: &World, resources: &Resources, ) -> Option; } -impl<'a, Q: WorldQuery, F: QueryFilter> SystemParam for Query<'a, Q, F> { +impl<'a, Q: WorldQuery, F: QueryFilter, Input> SystemParam for Query<'a, Q, F> { #[inline] unsafe fn get_param( + input: &mut Option, system_state: &mut SystemState, world: &World, _resources: &Resources, @@ -45,9 +65,10 @@ impl<'a, Q: WorldQuery, F: QueryFilter> SystemParam for Query<'a, Q, F> { } } -impl SystemParam for QuerySet { +impl SystemParam for QuerySet { #[inline] unsafe fn get_param( + input: &mut Option, system_state: &mut SystemState, world: &World, _resources: &Resources, @@ -71,7 +92,7 @@ impl SystemParam for QuerySet { } } -impl<'a> SystemParam for &'a mut Commands { +impl<'a, Input> SystemParam for &'a mut Commands { fn init(system_state: &mut SystemState, world: &World, _resources: &mut Resources) { system_state .commands @@ -80,6 +101,7 @@ impl<'a> SystemParam for &'a mut Commands { #[inline] unsafe fn get_param( + input: &mut Option, system_state: &mut SystemState, _world: &World, _resources: &Resources, @@ -89,7 +111,7 @@ impl<'a> SystemParam for &'a mut Commands { } } -impl SystemParam for Arc> { +impl SystemParam for Arc> { fn init(system_state: &mut SystemState, world: &World, _resources: &mut Resources) { system_state.arc_commands.get_or_insert_with(|| { let mut commands = Commands::default(); @@ -100,6 +122,7 @@ impl SystemParam for Arc> { #[inline] unsafe fn get_param( + input: &mut Option, system_state: &mut SystemState, _world: &World, _resources: &Resources, @@ -108,7 +131,7 @@ impl SystemParam for Arc> { } } -impl<'a, T: Resource> SystemParam for Res<'a, T> { +impl<'a, T: Resource, Input> SystemParam for Res<'a, T> { fn init(system_state: &mut SystemState, _world: &World, _resources: &mut Resources) { if system_state.resource_access.is_write(&TypeId::of::()) { panic!( @@ -123,6 +146,7 @@ impl<'a, T: Resource> SystemParam for Res<'a, T> { #[inline] unsafe fn get_param( + input: &mut Option, _system_state: &mut SystemState, _world: &World, resources: &Resources, @@ -133,7 +157,7 @@ impl<'a, T: Resource> SystemParam for Res<'a, T> { } } -impl<'a, T: Resource> SystemParam for ResMut<'a, T> { +impl<'a, T: Resource, Input> SystemParam for ResMut<'a, T> { fn init(system_state: &mut SystemState, _world: &World, _resources: &mut Resources) { // If a system already has access to the resource in another parameter, then we fail early. // e.g. `fn(Res, ResMut)` or `fn(ResMut, ResMut)` must not be allowed. @@ -153,6 +177,7 @@ impl<'a, T: Resource> SystemParam for ResMut<'a, T> { #[inline] unsafe fn get_param( + input: &mut Option, _system_state: &mut SystemState, _world: &World, resources: &Resources, @@ -163,7 +188,7 @@ impl<'a, T: Resource> SystemParam for ResMut<'a, T> { } } -impl<'a, T: Resource> SystemParam for ChangedRes<'a, T> { +impl<'a, T: Resource, Input> SystemParam for ChangedRes<'a, T> { fn init(system_state: &mut SystemState, _world: &World, _resources: &mut Resources) { if system_state.resource_access.is_write(&TypeId::of::()) { panic!( @@ -178,6 +203,7 @@ impl<'a, T: Resource> SystemParam for ChangedRes<'a, T> { #[inline] unsafe fn get_param( + input: &mut Option, _system_state: &mut SystemState, _world: &World, resources: &Resources, @@ -193,7 +219,7 @@ impl<'a, T: Resource> SystemParam for ChangedRes<'a, T> { } } -impl<'a, T: Resource + FromResources> SystemParam for Local<'a, T> { +impl<'a, T: Resource + FromResources, Input> SystemParam for Local<'a, T> { fn init(system_state: &mut SystemState, _world: &World, resources: &mut Resources) { if system_state .local_resource_access @@ -221,6 +247,7 @@ impl<'a, T: Resource + FromResources> SystemParam for Local<'a, T> { #[inline] unsafe fn get_param( + input: &mut Option, system_state: &mut SystemState, _world: &World, resources: &Resources, @@ -232,38 +259,40 @@ impl<'a, T: Resource + FromResources> SystemParam for Local<'a, T> { macro_rules! impl_system_param_tuple { ($($param: ident),*) => { #[allow(unused_variables)] - impl<$($param: SystemParam),*> SystemParam for ($($param,)*) { + impl),*> SystemParam for ($($param,)*) { fn init(system_state: &mut SystemState, world: &World, resources: &mut Resources) { $($param::init(system_state, world, resources);)* } #[inline] unsafe fn get_param( + input: &mut Option, system_state: &mut SystemState, world: &World, resources: &Resources, ) -> Option { - Some(($($param::get_param(system_state, world, resources)?,)*)) + Some(($($param::get_param(input, system_state, world, resources)?,)*)) } } #[allow(unused_variables)] #[allow(unused_mut)] #[allow(non_snake_case)] - impl<$($param: SystemParam),*> SystemParam for Or<($(Option<$param>,)*)> { + impl),*> SystemParam for Or<($(Option<$param>,)*)> { fn init(system_state: &mut SystemState, world: &World, resources: &mut Resources) { $($param::init(system_state, world, resources);)* } #[inline] unsafe fn get_param( + input: &mut Option, system_state: &mut SystemState, world: &World, resources: &Resources, ) -> Option { let mut has_some = false; $( - let $param = $param::get_param(system_state, world, resources); + let $param = $param::get_param(input, system_state, world, resources); if $param.is_some() { has_some = true; } diff --git a/crates/bevy_render/src/draw.rs b/crates/bevy_render/src/draw.rs index b61e8d7b49ec1..d4562f08dc867 100644 --- a/crates/bevy_render/src/draw.rs +++ b/crates/bevy_render/src/draw.rs @@ -12,7 +12,7 @@ use crate::{ use bevy_asset::{Assets, Handle}; use bevy_ecs::{Query, Res, ResMut, SystemParam}; use bevy_property::Properties; -use std::{ops::Range, sync::Arc}; +use std::{ops::Range, sync::Arc, marker::PhantomData}; use thiserror::Error; /// A queued command for the renderer From 129724ecc61e4337a062f8ec4fc90e7616187f48 Mon Sep 17 00:00:00 2001 From: Carter Anderson Date: Mon, 16 Nov 2020 01:48:24 -0800 Subject: [PATCH 3/7] IntoSystem returns explicit type --- crates/bevy_app/src/app_builder.rs | 108 ++++------- crates/bevy_asset/src/assets.rs | 12 +- crates/bevy_asset/src/lib.rs | 5 +- crates/bevy_audio/src/lib.rs | 6 +- crates/bevy_core/src/lib.rs | 7 +- .../src/frame_time_diagnostics_plugin.rs | 6 +- .../src/print_diagnostics_plugin.rs | 9 +- crates/bevy_ecs/src/lib.rs | 4 +- .../src/schedule/parallel_executor.rs | 38 ++-- crates/bevy_ecs/src/schedule/schedule.rs | 55 +++++- crates/bevy_ecs/src/system/into_system.rs | 126 +++++++------ .../bevy_ecs/src/system/into_thread_local.rs | 37 ++-- crates/bevy_ecs/src/system/system.rs | 172 ++++++++++-------- crates/bevy_ecs/src/system/system_param.rs | 22 +-- crates/bevy_gilrs/src/lib.rs | 11 +- crates/bevy_input/src/lib.rs | 11 +- crates/bevy_pbr/src/lib.rs | 3 +- .../bevy_pbr/src/render_graph/lights_node.rs | 4 +- crates/bevy_render/src/draw.rs | 2 +- crates/bevy_render/src/lib.rs | 21 +-- crates/bevy_render/src/render_graph/graph.rs | 2 +- crates/bevy_render/src/render_graph/node.rs | 2 +- .../src/render_graph/nodes/camera_node.rs | 4 +- .../nodes/render_resources_node.rs | 8 +- crates/bevy_scene/src/lib.rs | 3 +- crates/bevy_sprite/src/lib.rs | 5 +- .../hierarchy/hierarchy_maintenance_system.rs | 16 +- crates/bevy_transform/src/lib.rs | 21 +-- .../src/transform_propagate_system.rs | 13 +- crates/bevy_ui/src/lib.rs | 13 +- .../wgpu_resource_diagnostics_plugin.rs | 6 +- crates/bevy_wgpu/src/lib.rs | 12 +- crates/bevy_window/src/lib.rs | 3 +- crates/bevy_winit/src/lib.rs | 4 +- examples/2d/contributors.rs | 10 +- examples/2d/sprite.rs | 2 +- examples/2d/sprite_sheet.rs | 4 +- examples/2d/texture_atlas.rs | 4 +- examples/3d/3d_scene.rs | 3 +- examples/3d/load_gltf.rs | 2 +- examples/3d/msaa.rs | 2 +- examples/3d/parenting.rs | 4 +- examples/3d/spawner.rs | 4 +- examples/3d/texture.rs | 2 +- examples/3d/z_sort_debug.rs | 6 +- examples/android/android.rs | 2 +- examples/app/custom_loop.rs | 2 +- examples/app/headless.rs | 4 +- examples/app/logs.rs | 2 +- examples/app/plugin.rs | 2 +- examples/app/plugin_group.rs | 4 +- examples/asset/asset_loading.rs | 2 +- examples/asset/custom_asset.rs | 4 +- examples/asset/hot_asset_reloading.rs | 2 +- examples/audio/audio.rs | 2 +- examples/diagnostics/custom_diagnostic.rs | 4 +- examples/ecs/ecs_guide.rs | 18 +- examples/ecs/event.rs | 4 +- examples/ecs/hierarchy.rs | 4 +- examples/ecs/parallel_query.rs | 6 +- examples/ecs/startup_system.rs | 4 +- examples/game/breakout.rs | 10 +- examples/hello_world.rs | 2 +- examples/input/char_input_events.rs | 2 +- examples/input/gamepad_input.rs | 4 +- examples/input/gamepad_input_events.rs | 2 +- examples/input/keyboard_input.rs | 2 +- examples/input/keyboard_input_events.rs | 2 +- examples/input/mouse_input.rs | 2 +- examples/input/mouse_input_events.rs | 2 +- examples/input/touch_input.rs | 2 +- examples/input/touch_input_events.rs | 2 +- examples/ios/src/lib.rs | 2 +- examples/scene/properties.rs | 2 +- examples/scene/scene.rs | 8 +- examples/shader/mesh_custom_attribute.rs | 2 +- examples/shader/shader_custom_material.rs | 2 +- examples/shader/shader_defs.rs | 4 +- examples/tools/bevymark.rs | 10 +- examples/ui/button.rs | 4 +- examples/ui/font_atlas_debug.rs | 6 +- examples/ui/text.rs | 4 +- examples/ui/text_debug.rs | 4 +- examples/ui/ui.rs | 2 +- examples/wasm/assets_wasm.rs | 4 +- examples/wasm/headless_wasm.rs | 4 +- examples/wasm/hello_wasm.rs | 2 +- examples/wasm/winit_wasm.rs | 6 +- examples/window/multiple_windows.rs | 2 +- examples/window/window_settings.rs | 4 +- 90 files changed, 483 insertions(+), 501 deletions(-) diff --git a/crates/bevy_app/src/app_builder.rs b/crates/bevy_app/src/app_builder.rs index 10113f5f69f65..13693076f2ca3 100644 --- a/crates/bevy_app/src/app_builder.rs +++ b/crates/bevy_app/src/app_builder.rs @@ -95,81 +95,40 @@ impl AppBuilder { self } - pub fn add_system(&mut self, system: Box) -> &mut Self { + pub fn add_system(&mut self, system: Sys) -> &mut Self + where + SystemType: System, + Sys: IntoSystem, + { self.add_system_to_stage(stage::UPDATE, system) } - pub fn add_systems(&mut self, systems: Vec>) -> &mut Self { - self.add_systems_to_stage(stage::UPDATE, systems) - } - - pub fn init_system( - &mut self, - build: impl FnMut(&mut Resources) -> Box, - ) -> &mut Self { - self.init_system_to_stage(stage::UPDATE, build) - } - - pub fn init_system_to_stage( - &mut self, - stage: &'static str, - mut build: impl FnMut(&mut Resources) -> Box, - ) -> &mut Self { - let system = build(&mut self.app.resources); - self.add_system_to_stage(stage, system) - } - - pub fn add_startup_system_to_stage( + pub fn add_startup_system_to_stage( &mut self, stage_name: &'static str, - system: Box, - ) -> &mut Self { + system: Sys, + ) -> &mut Self + where + SystemType: System, + Sys: IntoSystem, + { self.app .startup_schedule .add_system_to_stage(stage_name, system); self } - pub fn add_startup_systems_to_stage( - &mut self, - stage_name: &'static str, - systems: Vec>, - ) -> &mut Self { - for system in systems { - self.app - .startup_schedule - .add_system_to_stage(stage_name, system); - } - self - } - - pub fn add_startup_system(&mut self, system: Box) -> &mut Self { + pub fn add_startup_system(&mut self, system: Sys) -> &mut Self + where + SystemType: System, + Sys: IntoSystem, + { self.app .startup_schedule .add_system_to_stage(startup_stage::STARTUP, system); self } - pub fn add_startup_systems(&mut self, systems: Vec>) -> &mut Self { - self.add_startup_systems_to_stage(startup_stage::STARTUP, systems) - } - - pub fn init_startup_system( - &mut self, - build: impl FnMut(&mut Resources) -> Box, - ) -> &mut Self { - self.init_startup_system_to_stage(startup_stage::STARTUP, build) - } - - pub fn init_startup_system_to_stage( - &mut self, - stage: &'static str, - mut build: impl FnMut(&mut Resources) -> Box, - ) -> &mut Self { - let system = build(&mut self.app.resources); - self.add_startup_system_to_stage(stage, system) - } - pub fn add_default_stages(&mut self) -> &mut Self { self.add_startup_stage(startup_stage::PRE_STARTUP) .add_startup_stage(startup_stage::STARTUP) @@ -183,43 +142,40 @@ impl AppBuilder { .add_stage(stage::LAST) } - pub fn add_system_to_stage( + pub fn add_system_to_stage( &mut self, stage_name: &'static str, - system: Box, - ) -> &mut Self { + system: Sys, + ) -> &mut Self + where + SystemType: System, + Sys: IntoSystem, + { self.app.schedule.add_system_to_stage(stage_name, system); self } - pub fn add_system_to_stage_front( + pub fn add_system_to_stage_front( &mut self, stage_name: &'static str, - system: Box, - ) -> &mut Self { + system: Sys, + ) -> &mut Self + where + SystemType: System, + Sys: IntoSystem, + { self.app .schedule .add_system_to_stage_front(stage_name, system); self } - pub fn add_systems_to_stage( - &mut self, - stage_name: &'static str, - systems: Vec>, - ) -> &mut Self { - for system in systems { - self.app.schedule.add_system_to_stage(stage_name, system); - } - self - } - pub fn add_event(&mut self) -> &mut Self where T: Send + Sync + 'static, { self.add_resource(Events::::default()) - .add_system_to_stage(stage::EVENT, Events::::update_system.system()) + .add_system_to_stage(stage::EVENT, Events::::update_system) } /// Adds a resource to the current [App] and overwrites any resource previously added of the same type. diff --git a/crates/bevy_asset/src/assets.rs b/crates/bevy_asset/src/assets.rs index 4b756cf02f341..e3fd86c20a478 100644 --- a/crates/bevy_asset/src/assets.rs +++ b/crates/bevy_asset/src/assets.rs @@ -2,7 +2,7 @@ use crate::{ update_asset_storage_system, Asset, AssetLoader, AssetServer, Handle, HandleId, RefChange, }; use bevy_app::{prelude::Events, AppBuilder}; -use bevy_ecs::{FromResources, IntoSystem, ResMut}; +use bevy_ecs::{FromResources, ResMut}; use bevy_type_registry::RegisterType; use bevy_utils::HashMap; use crossbeam_channel::Sender; @@ -219,14 +219,8 @@ impl AddAsset for AppBuilder { self.add_resource(assets) .register_component::>() - .add_system_to_stage( - super::stage::ASSET_EVENTS, - Assets::::asset_event_system.system(), - ) - .add_system_to_stage( - crate::stage::LOAD_ASSETS, - update_asset_storage_system::.system(), - ) + .add_system_to_stage(super::stage::ASSET_EVENTS, Assets::::asset_event_system) + .add_system_to_stage(crate::stage::LOAD_ASSETS, update_asset_storage_system::) .add_event::>() } diff --git a/crates/bevy_asset/src/lib.rs b/crates/bevy_asset/src/lib.rs index 6f5098dede741..f97abe5e1826e 100644 --- a/crates/bevy_asset/src/lib.rs +++ b/crates/bevy_asset/src/lib.rs @@ -31,7 +31,6 @@ pub mod prelude { } use bevy_app::{prelude::Plugin, AppBuilder}; -use bevy_ecs::IntoSystem; use bevy_type_registry::RegisterType; /// Adds support for Assets to an App. Assets are typed collections with change tracking, which are added as App Resources. @@ -80,13 +79,13 @@ impl Plugin for AssetPlugin { .register_property::() .add_system_to_stage( bevy_app::stage::PRE_UPDATE, - asset_server::free_unused_assets_system.system(), + asset_server::free_unused_assets_system, ); #[cfg(all( feature = "filesystem_watcher", all(not(target_arch = "wasm32"), not(target_os = "android")) ))] - app.add_system_to_stage(stage::LOAD_ASSETS, io::filesystem_watcher_system.system()); + app.add_system_to_stage(stage::LOAD_ASSETS, io::filesystem_watcher_system); } } diff --git a/crates/bevy_audio/src/lib.rs b/crates/bevy_audio/src/lib.rs index dfe792ef5afaf..e2d6e4ef412d4 100644 --- a/crates/bevy_audio/src/lib.rs +++ b/crates/bevy_audio/src/lib.rs @@ -12,7 +12,6 @@ pub mod prelude { use bevy_app::prelude::*; use bevy_asset::AddAsset; -use bevy_ecs::IntoThreadLocalSystem; /// Adds support for audio playback to an App #[derive(Default)] @@ -24,9 +23,6 @@ impl Plugin for AudioPlugin { .add_asset::() .init_asset_loader::() .init_resource::>() - .add_system_to_stage( - stage::POST_UPDATE, - play_queued_audio_system::.thread_local_system(), - ); + .add_system_to_stage(stage::POST_UPDATE, play_queued_audio_system::); } } diff --git a/crates/bevy_core/src/lib.rs b/crates/bevy_core/src/lib.rs index be901f68140a0..3a5cb4f3c2429 100644 --- a/crates/bevy_core/src/lib.rs +++ b/crates/bevy_core/src/lib.rs @@ -15,7 +15,6 @@ pub mod prelude { } use bevy_app::prelude::*; -use bevy_ecs::prelude::*; use bevy_math::{Mat3, Mat4, Quat, Vec2, Vec3}; use bevy_type_registry::RegisterType; @@ -40,8 +39,8 @@ impl Plugin for CorePlugin { .register_property::() .register_property::() .register_property::>() - .add_system_to_stage(stage::FIRST, time_system.system()) - .add_system_to_stage(stage::FIRST, timer_system.system()) - .add_system_to_stage(stage::PRE_UPDATE, entity_labels_system.system()); + .add_system_to_stage(stage::FIRST, time_system) + .add_system_to_stage(stage::FIRST, timer_system) + .add_system_to_stage(stage::PRE_UPDATE, entity_labels_system); } } diff --git a/crates/bevy_diagnostic/src/frame_time_diagnostics_plugin.rs b/crates/bevy_diagnostic/src/frame_time_diagnostics_plugin.rs index bbafb39c8e38a..aaabf1b6ac700 100644 --- a/crates/bevy_diagnostic/src/frame_time_diagnostics_plugin.rs +++ b/crates/bevy_diagnostic/src/frame_time_diagnostics_plugin.rs @@ -1,7 +1,7 @@ use crate::{Diagnostic, DiagnosticId, Diagnostics}; use bevy_app::prelude::*; use bevy_core::Time; -use bevy_ecs::{IntoSystem, Res, ResMut}; +use bevy_ecs::{Res, ResMut}; /// Adds "frame time" diagnostic to an App, specifically "frame time", "fps" and "frame count" #[derive(Default)] @@ -13,9 +13,9 @@ pub struct FrameTimeDiagnosticsState { impl Plugin for FrameTimeDiagnosticsPlugin { fn build(&self, app: &mut bevy_app::AppBuilder) { - app.add_startup_system(Self::setup_system.system()) + app.add_startup_system(Self::setup_system) .add_resource(FrameTimeDiagnosticsState { frame_count: 0.0 }) - .add_system(Self::diagnostic_system.system()); + .add_system(Self::diagnostic_system); } } diff --git a/crates/bevy_diagnostic/src/print_diagnostics_plugin.rs b/crates/bevy_diagnostic/src/print_diagnostics_plugin.rs index cefc750bf68f3..523139b2ec53b 100644 --- a/crates/bevy_diagnostic/src/print_diagnostics_plugin.rs +++ b/crates/bevy_diagnostic/src/print_diagnostics_plugin.rs @@ -1,7 +1,7 @@ use super::{Diagnostic, DiagnosticId, Diagnostics}; use bevy_app::prelude::*; use bevy_core::{Time, Timer}; -use bevy_ecs::{IntoSystem, Res, ResMut}; +use bevy_ecs::{Res, ResMut}; use std::time::Duration; /// An App Plugin that prints diagnostics to the console @@ -35,12 +35,9 @@ impl Plugin for PrintDiagnosticsPlugin { }); if self.debug { - app.add_system_to_stage( - stage::POST_UPDATE, - Self::print_diagnostics_debug_system.system(), - ); + app.add_system_to_stage(stage::POST_UPDATE, Self::print_diagnostics_debug_system); } else { - app.add_system_to_stage(stage::POST_UPDATE, Self::print_diagnostics_system.system()); + app.add_system_to_stage(stage::POST_UPDATE, Self::print_diagnostics_system); } } } diff --git a/crates/bevy_ecs/src/lib.rs b/crates/bevy_ecs/src/lib.rs index a5adc053ca3fb..bd17ac8a89b57 100644 --- a/crates/bevy_ecs/src/lib.rs +++ b/crates/bevy_ecs/src/lib.rs @@ -14,8 +14,8 @@ pub mod prelude { pub use crate::{ core::WorldBuilderSource, resource::{ChangedRes, FromResources, Local, Res, ResMut, Resource, Resources}, - system::{Commands, IntoSystem, IntoThreadLocalSystem, Query, System}, + system::{Commands, IntoSystem, Query, System}, Added, Bundle, Changed, Component, Entity, Mut, Mutated, Or, QuerySet, Ref, RefMut, With, - Without, World, AsChainSystem, FillSystemInput + Without, World, AsChainSystem }; } diff --git a/crates/bevy_ecs/src/schedule/parallel_executor.rs b/crates/bevy_ecs/src/schedule/parallel_executor.rs index 4479bc55cf901..94a10e872beeb 100644 --- a/crates/bevy_ecs/src/schedule/parallel_executor.rs +++ b/crates/bevy_ecs/src/schedule/parallel_executor.rs @@ -147,7 +147,7 @@ impl ExecutorStage { pub fn prepare_to_next_thread_local( &mut self, world: &World, - systems: &mut [Box], + systems: &mut [Box>], schedule_changed: bool, next_thread_local_index: usize, ) -> Range { @@ -329,7 +329,7 @@ impl ExecutorStage { &self, world: &World, resources: &Resources, - systems: &mut [Box], + systems: &mut [Box>], prepared_system_range: Range, compute_pool: &TaskPool, ) { @@ -422,7 +422,7 @@ impl ExecutorStage { &mut self, world: &mut World, resources: &mut Resources, - systems: &mut [Box], + systems: &mut [Box>], schedule_changed: bool, ) { let start_archetypes_generation = world.archetypes_generation(); @@ -555,7 +555,7 @@ mod tests { use crate::{ resource::{Res, ResMut, Resources}, schedule::Schedule, - system::{IntoSystem, IntoThreadLocalSystem, Query}, + system::Query, Commands, Entity, World, }; use bevy_tasks::{ComputeTaskPool, TaskPool}; @@ -592,8 +592,8 @@ mod tests { assert_eq!(1, entities.iter().count()); } - schedule.add_system_to_stage("PreArchetypeChange", insert.system()); - schedule.add_system_to_stage("PostArchetypeChange", read.system()); + schedule.add_system_to_stage("PreArchetypeChange", insert); + schedule.add_system_to_stage("PostArchetypeChange", read); let mut executor = ParallelExecutor::default(); schedule.initialize(&mut world, &mut resources); @@ -623,8 +623,8 @@ mod tests { assert_eq!(1, entities.iter().count()); } - schedule.add_system_to_stage("update", insert.thread_local_system()); - schedule.add_system_to_stage("update", read.system()); + schedule.add_system_to_stage("update", insert); + schedule.add_system_to_stage("update", read); schedule.initialize(&mut world, &mut resources); let mut executor = ParallelExecutor::default(); @@ -694,10 +694,10 @@ mod tests { completed_systems.insert(READ_U64_SYSTEM_NAME); } - schedule.add_system_to_stage("A", read_u32.system()); - schedule.add_system_to_stage("A", write_float.system()); - schedule.add_system_to_stage("A", read_u32_write_u64.system()); - schedule.add_system_to_stage("A", read_u64.system()); + schedule.add_system_to_stage("A", read_u32); + schedule.add_system_to_stage("A", write_float); + schedule.add_system_to_stage("A", read_u32_write_u64); + schedule.add_system_to_stage("A", read_u64); // B systems @@ -725,9 +725,9 @@ mod tests { completed_systems.insert(WRITE_F32_SYSTEM_NAME); } - schedule.add_system_to_stage("B", write_u64.system()); - schedule.add_system_to_stage("B", thread_local_system.thread_local_system()); - schedule.add_system_to_stage("B", write_f32.system()); + schedule.add_system_to_stage("B", write_u64); + schedule.add_system_to_stage("B", thread_local_system); + schedule.add_system_to_stage("B", write_f32); // C systems @@ -762,10 +762,10 @@ mod tests { completed_systems.insert(WRITE_F64_RES_SYSTEM_NAME); } - schedule.add_system_to_stage("C", read_f64_res.system()); - schedule.add_system_to_stage("C", read_isize_res.system()); - schedule.add_system_to_stage("C", read_isize_write_f64_res.system()); - schedule.add_system_to_stage("C", write_f64_res.system()); + schedule.add_system_to_stage("C", read_f64_res); + schedule.add_system_to_stage("C", read_isize_res); + schedule.add_system_to_stage("C", read_isize_write_f64_res); + schedule.add_system_to_stage("C", write_f64_res); schedule.initialize(&mut world, &mut resources); fn run_executor_and_validate( diff --git a/crates/bevy_ecs/src/schedule/schedule.rs b/crates/bevy_ecs/src/schedule/schedule.rs index 9de6fe17670b7..f07b99c7a8422 100644 --- a/crates/bevy_ecs/src/schedule/schedule.rs +++ b/crates/bevy_ecs/src/schedule/schedule.rs @@ -1,7 +1,7 @@ use crate::{ resource::Resources, system::{System, SystemId, ThreadLocalExecution}, - World, + IntoSystem, World, }; use bevy_utils::{HashMap, HashSet}; use std::{borrow::Cow, fmt}; @@ -11,7 +11,7 @@ use std::{borrow::Cow, fmt}; /// They are run on a given [World] and [Resources] reference. #[derive(Default)] pub struct Schedule { - pub(crate) stages: HashMap, Vec>>, + pub(crate) stages: HashMap, Vec>>>, pub(crate) stage_order: Vec>, pub(crate) system_ids: HashSet, generation: usize, @@ -96,10 +96,39 @@ impl Schedule { self.stage_order.insert(target_index, stage); } - pub fn add_system_to_stage( + pub fn add_system_to_stage( &mut self, stage_name: impl Into>, - system: Box, + system: Sys, + ) -> &mut Self + where + SystemType: System, + Sys: IntoSystem, + { + let stage_name = stage_name.into(); + let systems = self + .stages + .get_mut(&stage_name) + .unwrap_or_else(|| panic!("Stage does not exist: {}", stage_name)); + let system = system.system(); + if self.system_ids.contains(&system.id()) { + panic!( + "System with id {:?} ({}) already exists", + system.id(), + system.name() + ); + } + self.system_ids.insert(system.id()); + systems.push(Box::new(system)); + + self.generation += 1; + self + } + + pub fn add_boxed_system_to_stage( + &mut self, + stage_name: impl Into>, + system: Box>, ) -> &mut Self { let stage_name = stage_name.into(); let systems = self @@ -120,16 +149,21 @@ impl Schedule { self } - pub fn add_system_to_stage_front( + pub fn add_system_to_stage_front( &mut self, stage_name: impl Into>, - system: Box, - ) -> &mut Self { + system: Sys, + ) -> &mut Self + where + SystemType: System, + Sys: IntoSystem, + { let stage_name = stage_name.into(); let systems = self .stages .get_mut(&stage_name) .unwrap_or_else(|| panic!("Stage does not exist: {}", stage_name)); + let system = system.system(); if self.system_ids.contains(&system.id()) { panic!( "System with id {:?} ({}) already exists", @@ -138,7 +172,7 @@ impl Schedule { ); } self.system_ids.insert(system.id()); - systems.insert(0, system); + systems.insert(0, Box::new(system)); self.generation += 1; self @@ -197,7 +231,10 @@ impl Schedule { self.generation } - pub fn run_on_systems(&mut self, mut func: impl FnMut(&mut dyn System)) { + pub fn run_on_systems( + &mut self, + mut func: impl FnMut(&mut dyn System), + ) { for stage_name in self.stage_order.iter() { if let Some(stage_systems) = self.stages.get_mut(stage_name) { for system in stage_systems.iter_mut() { diff --git a/crates/bevy_ecs/src/system/into_system.rs b/crates/bevy_ecs/src/system/into_system.rs index 6493ebaa6386a..57303abcf61a4 100644 --- a/crates/bevy_ecs/src/system/into_system.rs +++ b/crates/bevy_ecs/src/system/into_system.rs @@ -1,6 +1,9 @@ -use crate::{ArchetypeComponent, Commands, QueryAccess, Resources, System, SystemId, SystemParam, ThreadLocalExecution, TypeAccess, World}; +use crate::{ + ArchetypeComponent, Commands, QueryAccess, Resources, System, SystemId, SystemParam, + ThreadLocalExecution, TypeAccess, World, +}; use parking_lot::Mutex; -use std::{any::TypeId, borrow::Cow, sync::Arc, marker::PhantomData}; +use std::{any::TypeId, borrow::Cow, sync::Arc}; pub struct SystemState { pub(crate) id: SystemId, @@ -70,34 +73,23 @@ impl SystemState { } } -pub struct FuncSystem -where - F: FnMut(Input, &mut SystemState, &World, &Resources) -> Option + Send + Sync + 'static, - Init: FnMut(&mut SystemState, &World, &mut Resources) + Send + Sync + 'static, - ThreadLocalFunc: FnMut(&mut SystemState, &mut World, &mut Resources) + Send + Sync + 'static, -{ - func: F, - thread_local_func: ThreadLocalFunc, - init_func: Init, +pub struct FuncSystem { + func: Box< + dyn FnMut(Input, &mut SystemState, &World, &Resources) -> Option + + Send + + Sync + + 'static, + >, + thread_local_func: + Box, + init_func: Box, state: SystemState, - marker: SendSyncPhantomData<(Input, Return)>, } -struct SendSyncPhantomData(PhantomData); -impl Default for SendSyncPhantomData { - fn default() -> Self { - SendSyncPhantomData(Default::default()) - } -} -unsafe impl Send for SendSyncPhantomData {} -unsafe impl Sync for SendSyncPhantomData {} - -impl System for FuncSystem -where - F: FnMut(Input, &mut SystemState, &World, &Resources) -> Option + Send + Sync + 'static, - Init: FnMut(&mut SystemState, &World, &mut Resources) + Send + Sync + 'static, - ThreadLocalFunc: FnMut(&mut SystemState, &mut World, &mut Resources) + Send + Sync + 'static, -{ +impl System for FuncSystem { + type Input = Input; + type Output = Output; + fn name(&self) -> std::borrow::Cow<'static, str> { self.state.name.clone() } @@ -122,7 +114,12 @@ where ThreadLocalExecution::NextFlush } - unsafe fn run_unsafe(&mut self, input: Input, world: &World, resources: &Resources) -> Option { + unsafe fn run_unsafe( + &mut self, + input: Input, + world: &World, + resources: &Resources, + ) -> Option { (self.func)(input, &mut self.state, world, resources) } @@ -140,20 +137,20 @@ where } } -pub trait IntoSystem { - fn system(self) -> Box>; +pub trait IntoSystem { + fn system(self) -> SystemType; } macro_rules! impl_into_system { ($($param: ident),*) => { - impl),*> IntoSystem<($($param,)*), Input, Return> for Func + impl),*> IntoSystem<($($param,)*), FuncSystem> for Func where Func: FnMut($($param),*) -> Return + Send + Sync + 'static, Return: 'static, Input: 'static { #[allow(unused_variables)] #[allow(unused_unsafe)] #[allow(non_snake_case)] - fn system(mut self) -> Box> { - Box::new(FuncSystem { + fn system(mut self) -> FuncSystem { + FuncSystem { state: SystemState { name: std::any::type_name::().into(), archetype_component_access: TypeAccess::default(), @@ -168,7 +165,7 @@ macro_rules! impl_into_system { query_type_names: Vec::new(), current_query_index: 0, }, - func: move |input, state, world, resources| { + func: Box::new(move |input, state, world, resources| { state.reset_indices(); let mut input = Some(input); unsafe { @@ -178,19 +175,18 @@ macro_rules! impl_into_system { None } } - }, - thread_local_func: |state, world, resources| { + }), + thread_local_func: Box::new(|state, world, resources| { state.commands.apply(world, resources); if let Some(ref commands) = state.arc_commands { let mut commands = commands.lock(); commands.apply(world, resources); } - }, - init_func: |state, world, resources| { + }), + init_func: Box::new(|state, world, resources| { $($param::init(state, world, resources);)* - }, - marker: Default::default(), - }) + }), + } } } }; @@ -283,7 +279,7 @@ mod tests { world.spawn((A, C)); world.spawn((A, D)); - run_system(&mut world, &mut resources, query_system.system()); + run_system(&mut world, &mut resources, query_system); assert!(*resources.get::().unwrap(), "system ran"); } @@ -314,7 +310,7 @@ mod tests { resources.insert(false); world.spawn((A, B)); - run_system(&mut world, &mut resources, query_system.system()); + run_system(&mut world, &mut resources, query_system); assert!(*resources.get::().unwrap(), "system ran"); } @@ -334,7 +330,7 @@ mod tests { let mut schedule = Schedule::default(); schedule.add_stage("update"); - schedule.add_system_to_stage("update", incr_e_on_flip.system()); + schedule.add_system_to_stage("update", incr_e_on_flip); schedule.initialize(&mut world, &mut resources); schedule.run(&mut world, &mut resources); @@ -367,7 +363,7 @@ mod tests { let mut schedule = Schedule::default(); schedule.add_stage("update"); - schedule.add_system_to_stage("update", incr_e_on_flip.system()); + schedule.add_system_to_stage("update", incr_e_on_flip); schedule.initialize(&mut world, &mut resources); schedule.run(&mut world, &mut resources); @@ -397,7 +393,7 @@ mod tests { let mut resources = Resources::default(); world.spawn((A,)); - run_system(&mut world, &mut resources, sys.system()); + run_system(&mut world, &mut resources, sys); } #[test] @@ -409,7 +405,7 @@ mod tests { let mut resources = Resources::default(); world.spawn((A,)); - run_system(&mut world, &mut resources, sys.system()); + run_system(&mut world, &mut resources, sys); } #[test] @@ -420,7 +416,7 @@ mod tests { let mut resources = Resources::default(); world.spawn((A,)); - run_system(&mut world, &mut resources, sys.system()); + run_system(&mut world, &mut resources, sys); } #[test] @@ -432,7 +428,7 @@ mod tests { let mut resources = Resources::default(); world.spawn((A,)); - run_system(&mut world, &mut resources, sys.system()); + run_system(&mut world, &mut resources, sys); } #[test] @@ -443,10 +439,18 @@ mod tests { let mut world = World::default(); let mut resources = Resources::default(); world.spawn((A,)); - run_system(&mut world, &mut resources, sys.system()); + run_system(&mut world, &mut resources, sys); } - fn run_system(world: &mut World, resources: &mut Resources, system: Box) { + fn run_system< + Params, + SystemType: System, + Sys: IntoSystem, + >( + world: &mut World, + resources: &mut Resources, + system: Sys, + ) { let mut schedule = Schedule::default(); schedule.add_stage("update"); schedule.add_system_to_stage("update", system); @@ -460,7 +464,13 @@ mod tests { _buffer: Vec, } - fn test_for_conflicting_resources(sys: Box) { + fn test_for_conflicting_resources< + Params, + SystemType: System, + Sys: IntoSystem, + >( + sys: Sys, + ) { let mut world = World::default(); let mut resources = Resources::default(); resources.insert(BufferRes::default()); @@ -473,21 +483,21 @@ mod tests { #[should_panic] fn conflicting_system_resources() { fn sys(_: ResMut, _: Res) {} - test_for_conflicting_resources(sys.system()) + test_for_conflicting_resources(sys) } #[test] #[should_panic] fn conflicting_system_resources_reverse_order() { fn sys(_: Res, _: ResMut) {} - test_for_conflicting_resources(sys.system()) + test_for_conflicting_resources(sys) } #[test] #[should_panic] fn conflicting_system_resources_multiple_mutable() { fn sys(_: ResMut, _: ResMut) {} - test_for_conflicting_resources(sys.system()) + test_for_conflicting_resources(sys) } #[test] @@ -495,19 +505,19 @@ mod tests { fn conflicting_changed_and_mutable_resource() { // A tempting pattern, but unsound if allowed. fn sys(_: ResMut, _: ChangedRes) {} - test_for_conflicting_resources(sys.system()) + test_for_conflicting_resources(sys) } #[test] #[should_panic] fn conflicting_system_local_resources() { fn sys(_: Local, _: Local) {} - test_for_conflicting_resources(sys.system()) + test_for_conflicting_resources(sys) } #[test] fn nonconflicting_system_resources() { fn sys(_: Local, _: ResMut, _: Local, _: ResMut) {} - test_for_conflicting_resources(sys.system()) + test_for_conflicting_resources(sys) } } diff --git a/crates/bevy_ecs/src/system/into_thread_local.rs b/crates/bevy_ecs/src/system/into_thread_local.rs index fd3ac195d7102..543ff8a4504a7 100644 --- a/crates/bevy_ecs/src/system/into_thread_local.rs +++ b/crates/bevy_ecs/src/system/into_thread_local.rs @@ -2,26 +2,23 @@ pub use super::Query; use crate::{ resource::Resources, system::{System, SystemId, ThreadLocalExecution}, - ArchetypeComponent, TypeAccess, World, + ArchetypeComponent, IntoSystem, TypeAccess, World, }; use std::{any::TypeId, borrow::Cow}; -#[derive(Debug)] -pub(crate) struct ThreadLocalSystemFn -where - Func: FnMut(&mut World, &mut Resources) + Send + Sync, +pub struct ThreadLocalSystemFn { - pub func: Func, + pub func: Box, pub resource_access: TypeAccess, pub archetype_component_access: TypeAccess, pub name: Cow<'static, str>, pub id: SystemId, } -impl System for ThreadLocalSystemFn -where - Func: FnMut(&mut World, &mut Resources) + Send + Sync, +impl System for ThreadLocalSystemFn { + type Input = (); + type Output = (); fn name(&self) -> Cow<'static, str> { self.name.clone() } @@ -40,7 +37,12 @@ where ThreadLocalExecution::Immediate } - unsafe fn run_unsafe(&mut self, input: (), _world: &World, _resources: &Resources) -> Option<()> { + unsafe fn run_unsafe( + &mut self, + _input: (), + _world: &World, + _resources: &Resources, + ) -> Option<()> { Some(()) } @@ -59,22 +61,17 @@ where } } -/// Converts `Self` into a thread local system -pub trait IntoThreadLocalSystem { - fn thread_local_system(self) -> Box; -} - -impl IntoThreadLocalSystem for F +impl IntoSystem<(&mut World, &mut Resources), ThreadLocalSystemFn> for F where F: FnMut(&mut World, &mut Resources) + Send + Sync + 'static, { - fn thread_local_system(mut self) -> Box { - Box::new(ThreadLocalSystemFn { - func: move |world, resources| (self)(world, resources), + fn system(mut self) -> ThreadLocalSystemFn { + ThreadLocalSystemFn { + func: Box::new(move |world, resources| (self)(world, resources)), name: core::any::type_name::().into(), id: SystemId::new(), resource_access: TypeAccess::default(), archetype_component_access: TypeAccess::default(), - }) + } } } diff --git a/crates/bevy_ecs/src/system/system.rs b/crates/bevy_ecs/src/system/system.rs index aab18e1364e5b..bc40977148184 100644 --- a/crates/bevy_ecs/src/system/system.rs +++ b/crates/bevy_ecs/src/system/system.rs @@ -19,7 +19,9 @@ impl SystemId { } /// An ECS system that can be added to a [Schedule](crate::Schedule) -pub trait System: Send + Sync { +pub trait System: Send + Sync + 'static { + type Input; + type Output; fn name(&self) -> Cow<'static, str>; fn id(&self) -> SystemId; fn is_initialized(&self) -> bool; @@ -27,27 +29,38 @@ pub trait System: Send + Sync { fn archetype_component_access(&self) -> &TypeAccess; fn resource_access(&self) -> &TypeAccess; fn thread_local_execution(&self) -> ThreadLocalExecution; - unsafe fn run_unsafe(&mut self, input: Input, world: &World, resources: &Resources) -> Option; - fn run(&mut self, input: Input, world: &mut World, resources: &mut Resources) -> Option { + unsafe fn run_unsafe( + &mut self, + input: Self::Input, + world: &World, + resources: &Resources, + ) -> Option; + fn run( + &mut self, + input: Self::Input, + world: &mut World, + resources: &mut Resources, + ) -> Option { // SAFE: world and resources are exclusively borrowed - unsafe { - self.run_unsafe(input, world, resources) - } + unsafe { self.run_unsafe(input, world, resources) } } fn run_thread_local(&mut self, world: &mut World, resources: &mut Resources); fn initialize(&mut self, _world: &mut World, _resources: &mut Resources) {} } -pub struct ChainSystem { - a: Box>, - b: Box>, +pub struct ChainSystem { + a: SystemA, + b: SystemB, name: Cow<'static, str>, id: SystemId, pub(crate) archetype_component_access: TypeAccess, pub(crate) resource_access: TypeAccess, } -impl System for ChainSystem { +impl> System for ChainSystem { + type Input = SystemA::Input; + type Output = SystemB::Output; + fn name(&self) -> Cow<'static, str> { self.name.clone() } @@ -66,7 +79,8 @@ impl System for ChainSystem { self.a.update(world); self.b.update(world); - self.archetype_component_access.union(self.a.archetype_component_access()); + self.archetype_component_access + .union(self.a.archetype_component_access()); self.resource_access.union(self.b.resource_access()); } @@ -82,7 +96,12 @@ impl System for ChainSystem { ThreadLocalExecution::NextFlush } - unsafe fn run_unsafe(&mut self, input: AIn, world: &World, resources: &Resources) -> Option { + unsafe fn run_unsafe( + &mut self, + input: Self::Input, + world: &World, + resources: &Resources, + ) -> Option { let out = self.a.run_unsafe(input, world, resources).unwrap(); self.b.run_unsafe(out, world, resources) } @@ -93,75 +112,82 @@ impl System for ChainSystem { } } -pub trait AsChainSystem { - fn chain(self, system: Box>) -> Box>; +pub trait AsChainSystem>: System + Sized { + fn chain(self, system: SystemB) -> ChainSystem; } -impl AsChainSystem for Box> { - fn chain(self, system: Box>) -> Box> { - Box::new(ChainSystem { +impl> AsChainSystem for SystemA { + fn chain(self, system: SystemB) -> ChainSystem { + ChainSystem { name: Cow::Owned(format!("Chain({}, {})", self.name(), system.name())), a: self, b: system, archetype_component_access: Default::default(), resource_access: Default::default(), id: SystemId::new(), - }) - } -} - -pub struct FilledInputSystem { - system: Box>, - input: Input, -} - -impl System<(), Output> for FilledInputSystem { - fn name(&self) -> Cow<'static, str> { - self.system.name() - } - - fn id(&self) -> SystemId { - self.system.id() - } - - fn is_initialized(&self) -> bool { - self.system.is_initialized() - } - - fn update(&mut self, world: &World) { - self.system.update(world); - } - - fn archetype_component_access(&self) -> &TypeAccess { - self.system.archetype_component_access() - } - - fn resource_access(&self) -> &TypeAccess { - self.system.resource_access() - } - - fn thread_local_execution(&self) -> ThreadLocalExecution { - self.system.thread_local_execution() - } - - unsafe fn run_unsafe(&mut self, _input: (), world: &World, resources: &Resources) -> Option { - self.system.run_unsafe(self.input.clone(), world, resources) - } - - fn run_thread_local(&mut self, world: &mut World, resources: &mut Resources) { - self.system.run_thread_local(world, resources); + } } } -pub trait FillSystemInput { - fn input(self, input: Input) -> Box>; -} - -impl FillSystemInput for Box> { - fn input(self, input: Input) -> Box> { - Box::new(FilledInputSystem { - system: self, - input, - }) - } -} \ No newline at end of file +// pub struct FilledInputSystem { +// system: Box>, +// input: Input, +// } + +// impl System<(), Output> for FilledInputSystem { +// fn name(&self) -> Cow<'static, str> { +// self.system.name() +// } + +// fn id(&self) -> SystemId { +// self.system.id() +// } + +// fn is_initialized(&self) -> bool { +// self.system.is_initialized() +// } + +// fn update(&mut self, world: &World) { +// self.system.update(world); +// } + +// fn archetype_component_access(&self) -> &TypeAccess { +// self.system.archetype_component_access() +// } + +// fn resource_access(&self) -> &TypeAccess { +// self.system.resource_access() +// } + +// fn thread_local_execution(&self) -> ThreadLocalExecution { +// self.system.thread_local_execution() +// } + +// unsafe fn run_unsafe( +// &mut self, +// _input: (), +// world: &World, +// resources: &Resources, +// ) -> Option { +// self.system.run_unsafe(self.input.clone(), world, resources) +// } + +// fn run_thread_local(&mut self, world: &mut World, resources: &mut Resources) { +// self.system.run_thread_local(world, resources); +// } +// } + +// pub trait FillSystemInput { +// fn input(self, input: Input) -> Box>; +// } + +// impl FillSystemInput +// for Box> +// { +// fn input(self, input: Input) -> Box> { +// Box::new(FilledInputSystem { +// system: self, +// input, +// }) +// } +// } diff --git a/crates/bevy_ecs/src/system/system_param.rs b/crates/bevy_ecs/src/system/system_param.rs index 339f9e50cc5d1..a0a1de2fefed2 100644 --- a/crates/bevy_ecs/src/system/system_param.rs +++ b/crates/bevy_ecs/src/system/system_param.rs @@ -12,14 +12,14 @@ impl SystemParam for In { #[inline] unsafe fn get_param( input: &mut Option, - system_state: &mut SystemState, - world: &World, + _system_state: &mut SystemState, + _world: &World, _resources: &Resources, ) -> Option { Some(In(input.take().unwrap())) } - fn init(system_state: &mut SystemState, _world: &World, _resources: &mut Resources) { + fn init(_system_state: &mut SystemState, _world: &World, _resources: &mut Resources) { } } @@ -40,7 +40,7 @@ pub trait SystemParam: Sized { impl<'a, Q: WorldQuery, F: QueryFilter, Input> SystemParam for Query<'a, Q, F> { #[inline] unsafe fn get_param( - input: &mut Option, + _input: &mut Option, system_state: &mut SystemState, world: &World, _resources: &Resources, @@ -68,7 +68,7 @@ impl<'a, Q: WorldQuery, F: QueryFilter, Input> SystemParam for Query<'a, impl SystemParam for QuerySet { #[inline] unsafe fn get_param( - input: &mut Option, + _input: &mut Option, system_state: &mut SystemState, world: &World, _resources: &Resources, @@ -101,7 +101,7 @@ impl<'a, Input> SystemParam for &'a mut Commands { #[inline] unsafe fn get_param( - input: &mut Option, + _input: &mut Option, system_state: &mut SystemState, _world: &World, _resources: &Resources, @@ -122,7 +122,7 @@ impl SystemParam for Arc> { #[inline] unsafe fn get_param( - input: &mut Option, + _input: &mut Option, system_state: &mut SystemState, _world: &World, _resources: &Resources, @@ -146,7 +146,7 @@ impl<'a, T: Resource, Input> SystemParam for Res<'a, T> { #[inline] unsafe fn get_param( - input: &mut Option, + _input: &mut Option, _system_state: &mut SystemState, _world: &World, resources: &Resources, @@ -177,7 +177,7 @@ impl<'a, T: Resource, Input> SystemParam for ResMut<'a, T> { #[inline] unsafe fn get_param( - input: &mut Option, + _input: &mut Option, _system_state: &mut SystemState, _world: &World, resources: &Resources, @@ -203,7 +203,7 @@ impl<'a, T: Resource, Input> SystemParam for ChangedRes<'a, T> { #[inline] unsafe fn get_param( - input: &mut Option, + _input: &mut Option, _system_state: &mut SystemState, _world: &World, resources: &Resources, @@ -247,7 +247,7 @@ impl<'a, T: Resource + FromResources, Input> SystemParam for Local<'a, T> #[inline] unsafe fn get_param( - input: &mut Option, + _input: &mut Option, system_state: &mut SystemState, _world: &World, resources: &Resources, diff --git a/crates/bevy_gilrs/src/lib.rs b/crates/bevy_gilrs/src/lib.rs index 3e3a0d5b99b25..f07d925709f37 100644 --- a/crates/bevy_gilrs/src/lib.rs +++ b/crates/bevy_gilrs/src/lib.rs @@ -2,7 +2,6 @@ mod converter; mod gilrs_system; use bevy_app::{prelude::*, startup_stage::PRE_STARTUP}; -use bevy_ecs::prelude::*; use bevy_utils::tracing::error; use gilrs::GilrsBuilder; use gilrs_system::{gilrs_event_startup_system, gilrs_event_system}; @@ -19,14 +18,8 @@ impl Plugin for GilrsPlugin { { Ok(gilrs) => { app.add_thread_local_resource(gilrs) - .add_startup_system_to_stage( - PRE_STARTUP, - gilrs_event_startup_system.thread_local_system(), - ) - .add_system_to_stage( - stage::PRE_EVENT, - gilrs_event_system.thread_local_system(), - ); + .add_startup_system_to_stage(PRE_STARTUP, gilrs_event_startup_system) + .add_system_to_stage(stage::PRE_EVENT, gilrs_event_system); } Err(err) => error!("Failed to start Gilrs. {}", err), } diff --git a/crates/bevy_input/src/lib.rs b/crates/bevy_input/src/lib.rs index b3ced9c404fab..a21fbca1e4b69 100644 --- a/crates/bevy_input/src/lib.rs +++ b/crates/bevy_input/src/lib.rs @@ -28,7 +28,6 @@ use mouse::{mouse_button_input_system, MouseButton, MouseButtonInput, MouseMotio use touch::{touch_screen_input_system, TouchInput, Touches}; use bevy_app::startup_stage::STARTUP; -use bevy_ecs::IntoSystem; use gamepad::{ gamepad_event_system, GamepadAxis, GamepadButton, GamepadEvent, GamepadEventRaw, GamepadSettings, @@ -45,20 +44,20 @@ impl Plugin for InputPlugin { .add_event::() .add_event::() .init_resource::>() - .add_system_to_stage(bevy_app::stage::EVENT, keyboard_input_system.system()) + .add_system_to_stage(bevy_app::stage::EVENT, keyboard_input_system) .init_resource::>() - .add_system_to_stage(bevy_app::stage::EVENT, mouse_button_input_system.system()) + .add_system_to_stage(bevy_app::stage::EVENT, mouse_button_input_system) .add_event::() .add_event::() .init_resource::() .init_resource::>() .init_resource::>() .init_resource::>() - .add_system_to_stage(bevy_app::stage::EVENT, gamepad_event_system.system()) - .add_startup_system_to_stage(STARTUP, gamepad_event_system.system()) + .add_system_to_stage(bevy_app::stage::EVENT, gamepad_event_system) + .add_startup_system_to_stage(STARTUP, gamepad_event_system) .add_event::() .init_resource::() - .add_system_to_stage(bevy_app::stage::EVENT, touch_screen_input_system.system()); + .add_system_to_stage(bevy_app::stage::EVENT, touch_screen_input_system); } } diff --git a/crates/bevy_pbr/src/lib.rs b/crates/bevy_pbr/src/lib.rs index 4381a3863b2db..bf9577efce75f 100644 --- a/crates/bevy_pbr/src/lib.rs +++ b/crates/bevy_pbr/src/lib.rs @@ -14,7 +14,6 @@ pub mod prelude { use bevy_app::prelude::*; use bevy_asset::{AddAsset, Assets, Handle}; -use bevy_ecs::IntoSystem; use bevy_render::{prelude::Color, render_graph::RenderGraph, shader}; use bevy_type_registry::RegisterType; use light::Light; @@ -31,7 +30,7 @@ impl Plugin for PbrPlugin { .register_component::() .add_system_to_stage( stage::POST_UPDATE, - shader::asset_shader_defs_system::.system(), + shader::asset_shader_defs_system::, ) .init_resource::(); let resources = app.resources(); diff --git a/crates/bevy_pbr/src/render_graph/lights_node.rs b/crates/bevy_pbr/src/render_graph/lights_node.rs index 6e6a1191178ad..12b720a973a1a 100644 --- a/crates/bevy_pbr/src/render_graph/lights_node.rs +++ b/crates/bevy_pbr/src/render_graph/lights_node.rs @@ -51,7 +51,7 @@ struct LightCount { unsafe impl Byteable for LightCount {} impl SystemNode for LightsNode { - fn get_system(&self, commands: &mut Commands) -> Box { + fn get_system(&self, commands: &mut Commands) -> Box> { let system = lights_node_system.system(); commands.insert_local_resource( system.id(), @@ -62,7 +62,7 @@ impl SystemNode for LightsNode { staging_buffer: None, }, ); - system + Box::new(system) } } diff --git a/crates/bevy_render/src/draw.rs b/crates/bevy_render/src/draw.rs index d4562f08dc867..b61e8d7b49ec1 100644 --- a/crates/bevy_render/src/draw.rs +++ b/crates/bevy_render/src/draw.rs @@ -12,7 +12,7 @@ use crate::{ use bevy_asset::{Assets, Handle}; use bevy_ecs::{Query, Res, ResMut, SystemParam}; use bevy_property::Properties; -use std::{ops::Range, sync::Arc, marker::PhantomData}; +use std::{ops::Range, sync::Arc}; use thiserror::Error; /// A queued command for the renderer diff --git a/crates/bevy_render/src/lib.rs b/crates/bevy_render/src/lib.rs index a3b6d7e03ac58..823d0d05652eb 100644 --- a/crates/bevy_render/src/lib.rs +++ b/crates/bevy_render/src/lib.rs @@ -32,7 +32,6 @@ use crate::prelude::*; use base::{MainPass, Msaa}; use bevy_app::prelude::*; use bevy_asset::AddAsset; -use bevy_ecs::{IntoSystem, IntoThreadLocalSystem}; use camera::{ ActiveCameras, Camera, OrthographicProjection, PerspectiveProjection, VisibleEntities, }; @@ -123,42 +122,42 @@ impl Plugin for RenderPlugin { .init_resource::() .add_system_to_stage( bevy_app::stage::PRE_UPDATE, - draw::clear_draw_system.system(), + draw::clear_draw_system, ) .add_system_to_stage( bevy_app::stage::POST_UPDATE, - camera::active_cameras_system.system(), + camera::active_cameras_system, ) .add_system_to_stage( bevy_app::stage::POST_UPDATE, - camera::camera_system::.system(), + camera::camera_system::, ) .add_system_to_stage( bevy_app::stage::POST_UPDATE, - camera::camera_system::.system(), + camera::camera_system::, ) // registration order matters here. this must come after all camera_system:: systems .add_system_to_stage( bevy_app::stage::POST_UPDATE, - camera::visible_entities_system.system(), + camera::visible_entities_system, ) // TODO: turn these "resource systems" into graph nodes and remove the RENDER_RESOURCE stage .add_system_to_stage( stage::RENDER_RESOURCE, - mesh::mesh_resource_provider_system.system(), + mesh::mesh_resource_provider_system, ) .add_system_to_stage( stage::RENDER_RESOURCE, - Texture::texture_resource_system.system(), + Texture::texture_resource_system, ) .add_system_to_stage( stage::RENDER_GRAPH_SYSTEMS, - render_graph::render_graph_schedule_executor_system.thread_local_system(), + render_graph::render_graph_schedule_executor_system, ) - .add_system_to_stage(stage::DRAW, pipeline::draw_render_pipelines_system.system()) + .add_system_to_stage(stage::DRAW, pipeline::draw_render_pipelines_system) .add_system_to_stage( stage::POST_RENDER, - shader::clear_shader_defs_system.system(), + shader::clear_shader_defs_system, ); if app.resources().get::().is_none() { diff --git a/crates/bevy_render/src/render_graph/graph.rs b/crates/bevy_render/src/render_graph/graph.rs index 983b6fcd0a3a2..65c3319b50a46 100644 --- a/crates/bevy_render/src/render_graph/graph.rs +++ b/crates/bevy_render/src/render_graph/graph.rs @@ -43,7 +43,7 @@ impl RenderGraph { self.system_node_schedule .as_mut() .unwrap() - .add_system_to_stage("update", node.get_system(&mut self.commands)); + .add_boxed_system_to_stage("update", node.get_system(&mut self.commands)); self.add_node(name, node) } diff --git a/crates/bevy_render/src/render_graph/node.rs b/crates/bevy_render/src/render_graph/node.rs index 678c4be2cd8e6..3cf3aa13a6a6d 100644 --- a/crates/bevy_render/src/render_graph/node.rs +++ b/crates/bevy_render/src/render_graph/node.rs @@ -37,7 +37,7 @@ pub trait Node: Downcast + Send + Sync + 'static { impl_downcast!(Node); pub trait SystemNode: Node { - fn get_system(&self, commands: &mut Commands) -> Box; + fn get_system(&self, commands: &mut Commands) -> Box>; } #[derive(Debug)] diff --git a/crates/bevy_render/src/render_graph/nodes/camera_node.rs b/crates/bevy_render/src/render_graph/nodes/camera_node.rs index bdc5217c75de8..574535f4f28c4 100644 --- a/crates/bevy_render/src/render_graph/nodes/camera_node.rs +++ b/crates/bevy_render/src/render_graph/nodes/camera_node.rs @@ -44,7 +44,7 @@ impl Node for CameraNode { } impl SystemNode for CameraNode { - fn get_system(&self, commands: &mut Commands) -> Box { + fn get_system(&self, commands: &mut Commands) -> Box> { let system = camera_node_system.system(); commands.insert_local_resource( system.id(), @@ -55,7 +55,7 @@ impl SystemNode for CameraNode { staging_buffer: None, }, ); - system + Box::new(system) } } diff --git a/crates/bevy_render/src/render_graph/nodes/render_resources_node.rs b/crates/bevy_render/src/render_graph/nodes/render_resources_node.rs index 44958a20fb37c..0235c7407240d 100644 --- a/crates/bevy_render/src/render_graph/nodes/render_resources_node.rs +++ b/crates/bevy_render/src/render_graph/nodes/render_resources_node.rs @@ -387,7 +387,7 @@ impl SystemNode for RenderResourcesNode where T: renderer::RenderResources, { - fn get_system(&self, commands: &mut Commands) -> Box { + fn get_system(&self, commands: &mut Commands) -> Box> { let system = render_resources_node_system::.system(); commands.insert_local_resource( system.id(), @@ -398,7 +398,7 @@ where }, ); - system + Box::new(system) } } @@ -527,7 +527,7 @@ impl SystemNode for AssetRenderResourcesNode where T: renderer::RenderResources + Asset, { - fn get_system(&self, commands: &mut Commands) -> Box { + fn get_system(&self, commands: &mut Commands) -> Box> { let system = asset_render_resources_node_system::.system(); commands.insert_local_resource( system.id(), @@ -538,7 +538,7 @@ where }, ); - system + Box::new(system) } } diff --git a/crates/bevy_scene/src/lib.rs b/crates/bevy_scene/src/lib.rs index b850c8a733f3a..6fec4e5b6a660 100644 --- a/crates/bevy_scene/src/lib.rs +++ b/crates/bevy_scene/src/lib.rs @@ -17,7 +17,6 @@ pub mod prelude { use bevy_app::prelude::*; use bevy_asset::AddAsset; -use bevy_ecs::IntoThreadLocalSystem; #[derive(Default)] pub struct ScenePlugin; @@ -31,6 +30,6 @@ impl Plugin for ScenePlugin { .init_asset_loader::() .init_resource::() .add_stage_after(stage::EVENT, SCENE_STAGE) - .add_system_to_stage(SCENE_STAGE, scene_spawner_system.thread_local_system()); + .add_system_to_stage(SCENE_STAGE, scene_spawner_system); } } diff --git a/crates/bevy_sprite/src/lib.rs b/crates/bevy_sprite/src/lib.rs index 4fecd67d29006..2bad06938efb0 100644 --- a/crates/bevy_sprite/src/lib.rs +++ b/crates/bevy_sprite/src/lib.rs @@ -26,7 +26,6 @@ pub mod prelude { use bevy_app::prelude::*; use bevy_asset::{AddAsset, Assets, Handle}; -use bevy_ecs::IntoSystem; use bevy_math::Vec2; use bevy_render::{ mesh::{shape, Mesh}, @@ -45,10 +44,10 @@ impl Plugin for SpritePlugin { fn build(&self, app: &mut AppBuilder) { app.add_asset::() .add_asset::() - .add_system_to_stage(stage::POST_UPDATE, sprite_system.system()) + .add_system_to_stage(stage::POST_UPDATE, sprite_system) .add_system_to_stage( stage::POST_UPDATE, - asset_shader_defs_system::.system(), + asset_shader_defs_system::, ); let resources = app.resources_mut(); diff --git a/crates/bevy_transform/src/hierarchy/hierarchy_maintenance_system.rs b/crates/bevy_transform/src/hierarchy/hierarchy_maintenance_system.rs index e79ba91421652..7350bf105f414 100644 --- a/crates/bevy_transform/src/hierarchy/hierarchy_maintenance_system.rs +++ b/crates/bevy_transform/src/hierarchy/hierarchy_maintenance_system.rs @@ -1,5 +1,5 @@ use crate::components::*; -use bevy_ecs::{Changed, Commands, Entity, IntoSystem, Query, System, Without}; +use bevy_ecs::{Changed, Commands, Entity, Query, Without}; use bevy_utils::HashMap; use smallvec::SmallVec; @@ -64,15 +64,12 @@ pub fn parent_update_system( commands.insert_one(*k, Children::with(v)); }); } - -pub fn hierarchy_maintenance_systems() -> Vec> { - vec![parent_update_system.system()] -} - #[cfg(test)] mod test { use super::*; - use crate::{hierarchy::BuildChildren, transform_systems}; + use crate::{ + hierarchy::BuildChildren, transform_propagate_system::transform_propagate_system, + }; use bevy_ecs::{Resources, Schedule, World}; use bevy_math::Vec3; @@ -83,9 +80,8 @@ mod test { let mut schedule = Schedule::default(); schedule.add_stage("update"); - for system in transform_systems() { - schedule.add_system_to_stage("update", system); - } + schedule.add_system_to_stage("update", parent_update_system); + schedule.add_system_to_stage("update", transform_propagate_system); // Add parent entities let mut commands = Commands::default(); diff --git a/crates/bevy_transform/src/lib.rs b/crates/bevy_transform/src/lib.rs index 98582a8b0d205..fe8dc696c996e 100644 --- a/crates/bevy_transform/src/lib.rs +++ b/crates/bevy_transform/src/lib.rs @@ -7,18 +7,8 @@ pub mod prelude { } use bevy_app::prelude::*; -use bevy_ecs::prelude::*; use bevy_type_registry::RegisterType; -use prelude::{Children, GlobalTransform, Parent, Transform}; - -pub(crate) fn transform_systems() -> Vec> { - let mut systems = Vec::with_capacity(5); - - systems.append(&mut hierarchy::hierarchy_maintenance_systems()); - systems.push(transform_propagate_system::transform_propagate_system.system()); - - systems -} +use prelude::{parent_update_system, Children, GlobalTransform, Parent, Transform}; #[derive(Default)] pub struct TransformPlugin; @@ -30,7 +20,12 @@ impl Plugin for TransformPlugin { .register_component::() .register_component::() // add transform systems to startup so the first update is "correct" - .add_startup_systems(transform_systems()) - .add_systems_to_stage(stage::POST_UPDATE, transform_systems()); + .add_startup_system(parent_update_system) + .add_startup_system(transform_propagate_system::transform_propagate_system) + .add_system_to_stage(stage::POST_UPDATE, parent_update_system) + .add_system_to_stage( + stage::POST_UPDATE, + transform_propagate_system::transform_propagate_system, + ); } } diff --git a/crates/bevy_transform/src/transform_propagate_system.rs b/crates/bevy_transform/src/transform_propagate_system.rs index c85e3c214cb61..a22b7edc044c2 100644 --- a/crates/bevy_transform/src/transform_propagate_system.rs +++ b/crates/bevy_transform/src/transform_propagate_system.rs @@ -50,7 +50,7 @@ fn propagate_recursive( #[cfg(test)] mod test { use super::*; - use crate::{hierarchy::BuildChildren, transform_systems}; + use crate::hierarchy::{BuildChildren, parent_update_system}; use bevy_ecs::{Resources, Schedule, World}; use bevy_math::Vec3; @@ -61,9 +61,8 @@ mod test { let mut schedule = Schedule::default(); schedule.add_stage("update"); - for system in transform_systems() { - schedule.add_system_to_stage("update", system); - } + schedule.add_system_to_stage("update", parent_update_system); + schedule.add_system_to_stage("update", transform_propagate_system); // Root entity let parent = world.spawn(( @@ -111,9 +110,9 @@ mod test { let mut schedule = Schedule::default(); schedule.add_stage("update"); - for system in transform_systems() { - schedule.add_system_to_stage("update", system); - } + schedule.add_system_to_stage("update", parent_update_system); + schedule.add_system_to_stage("update", transform_propagate_system); + // Root entity let mut commands = Commands::default(); diff --git a/crates/bevy_ui/src/lib.rs b/crates/bevy_ui/src/lib.rs index 21b9c4d80a954..9152ac306e91a 100644 --- a/crates/bevy_ui/src/lib.rs +++ b/crates/bevy_ui/src/lib.rs @@ -25,7 +25,6 @@ pub mod prelude { } use bevy_app::prelude::*; -use bevy_ecs::IntoSystem; use bevy_render::render_graph::RenderGraph; use update::ui_z_system; @@ -40,13 +39,13 @@ impl Plugin for UiPlugin { fn build(&self, app: &mut AppBuilder) { app.init_resource::() .add_stage_before(bevy_app::stage::POST_UPDATE, stage::UI) - .add_system_to_stage(bevy_app::stage::PRE_UPDATE, ui_focus_system.system()) + .add_system_to_stage(bevy_app::stage::PRE_UPDATE, ui_focus_system) // add these stages to front because these must run before transform update systems - .add_system_to_stage(stage::UI, widget::text_system.system()) - .add_system_to_stage(stage::UI, widget::image_node_system.system()) - .add_system_to_stage(stage::UI, ui_z_system.system()) - .add_system_to_stage(stage::UI, flex_node_system.system()) - .add_system_to_stage(bevy_render::stage::DRAW, widget::draw_text_system.system()); + .add_system_to_stage(stage::UI, widget::text_system) + .add_system_to_stage(stage::UI, widget::image_node_system) + .add_system_to_stage(stage::UI, ui_z_system) + .add_system_to_stage(stage::UI, flex_node_system) + .add_system_to_stage(bevy_render::stage::DRAW, widget::draw_text_system); let resources = app.resources(); let mut render_graph = resources.get_mut::().unwrap(); diff --git a/crates/bevy_wgpu/src/diagnostic/wgpu_resource_diagnostics_plugin.rs b/crates/bevy_wgpu/src/diagnostic/wgpu_resource_diagnostics_plugin.rs index 079332c93cf89..0af3f94fc915c 100644 --- a/crates/bevy_wgpu/src/diagnostic/wgpu_resource_diagnostics_plugin.rs +++ b/crates/bevy_wgpu/src/diagnostic/wgpu_resource_diagnostics_plugin.rs @@ -1,7 +1,7 @@ use crate::renderer::WgpuRenderResourceContext; use bevy_app::prelude::*; use bevy_diagnostic::{Diagnostic, DiagnosticId, Diagnostics}; -use bevy_ecs::{IntoSystem, Res, ResMut}; +use bevy_ecs::{Res, ResMut}; use bevy_render::renderer::RenderResourceContext; #[derive(Default)] @@ -9,8 +9,8 @@ pub struct WgpuResourceDiagnosticsPlugin; impl Plugin for WgpuResourceDiagnosticsPlugin { fn build(&self, app: &mut AppBuilder) { - app.add_startup_system(Self::setup_system.system()) - .add_system(Self::diagnostic_system.system()); + app.add_startup_system(Self::setup_system) + .add_system(Self::diagnostic_system); } } diff --git a/crates/bevy_wgpu/src/lib.rs b/crates/bevy_wgpu/src/lib.rs index 8cb2c7db69da6..27c1b3e802575 100644 --- a/crates/bevy_wgpu/src/lib.rs +++ b/crates/bevy_wgpu/src/lib.rs @@ -11,7 +11,7 @@ pub use wgpu_renderer::*; pub use wgpu_resources::*; use bevy_app::prelude::*; -use bevy_ecs::{IntoSystem, IntoThreadLocalSystem, Resources, World}; +use bevy_ecs::{Resources, World}; use bevy_render::renderer::{free_shared_buffers_system, RenderResourceContext, SharedBuffers}; use renderer::WgpuRenderResourceContext; @@ -21,14 +21,8 @@ pub struct WgpuPlugin; impl Plugin for WgpuPlugin { fn build(&self, app: &mut AppBuilder) { let render_system = get_wgpu_render_system(app.resources_mut()); - app.add_system_to_stage( - bevy_render::stage::RENDER, - render_system.thread_local_system(), - ) - .add_system_to_stage( - bevy_render::stage::POST_RENDER, - free_shared_buffers_system.system(), - ); + app.add_system_to_stage(bevy_render::stage::RENDER, render_system) + .add_system_to_stage(bevy_render::stage::POST_RENDER, free_shared_buffers_system); } } diff --git a/crates/bevy_window/src/lib.rs b/crates/bevy_window/src/lib.rs index 36f7a736ef10f..0c07496c0028c 100644 --- a/crates/bevy_window/src/lib.rs +++ b/crates/bevy_window/src/lib.rs @@ -13,7 +13,6 @@ pub mod prelude { } use bevy_app::prelude::*; -use bevy_ecs::IntoSystem; pub struct WindowPlugin { pub add_primary_window: bool, @@ -54,7 +53,7 @@ impl Plugin for WindowPlugin { } if self.exit_on_close { - app.add_system(exit_on_window_close_system.system()); + app.add_system(exit_on_window_close_system); } } } diff --git a/crates/bevy_winit/src/lib.rs b/crates/bevy_winit/src/lib.rs index 484e8796450c7..e0c001fe07b99 100644 --- a/crates/bevy_winit/src/lib.rs +++ b/crates/bevy_winit/src/lib.rs @@ -10,7 +10,7 @@ pub use winit_config::*; pub use winit_windows::*; use bevy_app::{prelude::*, AppExit}; -use bevy_ecs::{IntoThreadLocalSystem, Resources, World}; +use bevy_ecs::{Resources, World}; use bevy_math::Vec2; use bevy_utils::tracing::trace; use bevy_window::{ @@ -36,7 +36,7 @@ impl Plugin for WinitPlugin { // .add_event::() .init_resource::() .set_runner(winit_runner) - .add_system(change_window.thread_local_system()); + .add_system(change_window); } } diff --git a/examples/2d/contributors.rs b/examples/2d/contributors.rs index ec326bc39e107..c13361e8c3e19 100644 --- a/examples/2d/contributors.rs +++ b/examples/2d/contributors.rs @@ -9,11 +9,11 @@ use std::{ fn main() { App::build() .add_plugins(DefaultPlugins) - .add_startup_system(setup.system()) - .add_system(velocity_system.system()) - .add_system(move_system.system()) - .add_system(collision_system.system()) - .add_system(select_system.system()) + .add_startup_system(setup) + .add_system(velocity_system) + .add_system(move_system) + .add_system(collision_system) + .add_system(select_system) .run(); } diff --git a/examples/2d/sprite.rs b/examples/2d/sprite.rs index 2d8f298c3e1da..9cd245cbf7a1d 100644 --- a/examples/2d/sprite.rs +++ b/examples/2d/sprite.rs @@ -3,7 +3,7 @@ use bevy::prelude::*; fn main() { App::build() .add_plugins(DefaultPlugins) - .add_startup_system(setup.system()) + .add_startup_system(setup) .run(); } diff --git a/examples/2d/sprite_sheet.rs b/examples/2d/sprite_sheet.rs index 91a38bd541d70..04fa883409820 100644 --- a/examples/2d/sprite_sheet.rs +++ b/examples/2d/sprite_sheet.rs @@ -3,8 +3,8 @@ use bevy::prelude::*; fn main() { App::build() .add_plugins(DefaultPlugins) - .add_startup_system(setup.system()) - .add_system(animate_sprite_system.system()) + .add_startup_system(setup) + .add_system(animate_sprite_system) .run(); } diff --git a/examples/2d/texture_atlas.rs b/examples/2d/texture_atlas.rs index 3a324b2c266ce..4879641926e5d 100644 --- a/examples/2d/texture_atlas.rs +++ b/examples/2d/texture_atlas.rs @@ -5,8 +5,8 @@ fn main() { App::build() .init_resource::() .add_plugins(DefaultPlugins) - .add_startup_system(setup.system()) - .add_system(load_atlas.system()) + .add_startup_system(setup) + .add_system(load_atlas) .run(); } diff --git a/examples/3d/3d_scene.rs b/examples/3d/3d_scene.rs index 4a47609c31531..bf03b134c8ed4 100644 --- a/examples/3d/3d_scene.rs +++ b/examples/3d/3d_scene.rs @@ -4,10 +4,11 @@ fn main() { App::build() .add_resource(Msaa { samples: 4 }) .add_plugins(DefaultPlugins) - .add_startup_system(setup.system()) + .add_startup_system(setup) .run(); } + /// set up a simple 3D scene fn setup( commands: &mut Commands, diff --git a/examples/3d/load_gltf.rs b/examples/3d/load_gltf.rs index e374970f3038d..fb64e4cadeab9 100644 --- a/examples/3d/load_gltf.rs +++ b/examples/3d/load_gltf.rs @@ -4,7 +4,7 @@ fn main() { App::build() .add_resource(Msaa { samples: 4 }) .add_plugins(DefaultPlugins) - .add_startup_system(setup.system()) + .add_startup_system(setup) .run(); } diff --git a/examples/3d/msaa.rs b/examples/3d/msaa.rs index f3c2f51584cbe..ef3767fde14dd 100644 --- a/examples/3d/msaa.rs +++ b/examples/3d/msaa.rs @@ -7,7 +7,7 @@ fn main() { App::build() .add_resource(Msaa { samples: 4 }) .add_plugins(DefaultPlugins) - .add_startup_system(setup.system()) + .add_startup_system(setup) .run(); } diff --git a/examples/3d/parenting.rs b/examples/3d/parenting.rs index 5d2f6425135e8..03c0c826835ec 100644 --- a/examples/3d/parenting.rs +++ b/examples/3d/parenting.rs @@ -6,8 +6,8 @@ fn main() { App::build() .add_resource(Msaa { samples: 4 }) .add_plugins(DefaultPlugins) - .add_startup_system(setup.system()) - .add_system(rotator_system.system()) + .add_startup_system(setup) + .add_system(rotator_system) .run(); } diff --git a/examples/3d/spawner.rs b/examples/3d/spawner.rs index 242ef42efe209..20a7552bc43df 100644 --- a/examples/3d/spawner.rs +++ b/examples/3d/spawner.rs @@ -13,8 +13,8 @@ fn main() { .add_plugins(DefaultPlugins) .add_plugin(FrameTimeDiagnosticsPlugin::default()) .add_plugin(PrintDiagnosticsPlugin::default()) - .add_startup_system(setup.system()) - .add_system(move_cubes.system()) + .add_startup_system(setup) + .add_system(move_cubes) .run(); } diff --git a/examples/3d/texture.rs b/examples/3d/texture.rs index 8a3b20eb40b6b..8d853eace397a 100644 --- a/examples/3d/texture.rs +++ b/examples/3d/texture.rs @@ -4,7 +4,7 @@ use bevy::prelude::*; fn main() { App::build() .add_plugins(DefaultPlugins) - .add_startup_system(setup.system()) + .add_startup_system(setup) .run(); } diff --git a/examples/3d/z_sort_debug.rs b/examples/3d/z_sort_debug.rs index 215e32eea86e4..08c4cd6b762d8 100644 --- a/examples/3d/z_sort_debug.rs +++ b/examples/3d/z_sort_debug.rs @@ -10,9 +10,9 @@ use bevy::{ fn main() { App::build() .add_plugins(DefaultPlugins) - .add_startup_system(setup.system()) - .add_system(rotator_system.system()) - .add_system(camera_order_color_system.system()) + .add_startup_system(setup) + .add_system(rotator_system) + .add_system(camera_order_color_system) .run(); } diff --git a/examples/android/android.rs b/examples/android/android.rs index 915c6c870eda9..15fbd04583467 100644 --- a/examples/android/android.rs +++ b/examples/android/android.rs @@ -6,7 +6,7 @@ fn main() { App::build() .add_resource(Msaa { samples: 2 }) .add_plugins(DefaultPlugins) - .add_startup_system(setup.system()) + .add_startup_system(setup) .run(); } diff --git a/examples/app/custom_loop.rs b/examples/app/custom_loop.rs index 4ca46dee35665..647f23eaba89b 100644 --- a/examples/app/custom_loop.rs +++ b/examples/app/custom_loop.rs @@ -26,6 +26,6 @@ fn main() { App::build() .add_resource(Input(String::new())) .set_runner(my_runner) - .add_system(print_system.system()) + .add_system(print_system) .run(); } diff --git a/examples/app/headless.rs b/examples/app/headless.rs index 9b13f8fe415c5..4e5af376605b6 100644 --- a/examples/app/headless.rs +++ b/examples/app/headless.rs @@ -14,7 +14,7 @@ fn main() { App::build() .add_resource(ScheduleRunnerSettings::run_once()) .add_plugins(MinimalPlugins) - .add_system(hello_world_system.system()) + .add_system(hello_world_system) .run(); // this app loops forever at 60 fps @@ -23,7 +23,7 @@ fn main() { 1.0 / 60.0, ))) .add_plugins(MinimalPlugins) - .add_system(counter.system()) + .add_system(counter) .run(); } diff --git a/examples/app/logs.rs b/examples/app/logs.rs index 532e6932ebf46..3046a51fc2738 100644 --- a/examples/app/logs.rs +++ b/examples/app/logs.rs @@ -9,7 +9,7 @@ fn main() { // filter: "wgpu=warn,bevy_ecs=info".to_string(), // }) .add_plugins(DefaultPlugins) - .add_system(log_system.system()) + .add_system(log_system) .run(); } diff --git a/examples/app/plugin.rs b/examples/app/plugin.rs index ff7b3a2800954..d5fb41e811ee6 100644 --- a/examples/app/plugin.rs +++ b/examples/app/plugin.rs @@ -30,7 +30,7 @@ impl Plugin for PrintMessagePlugin { timer: Timer::new(self.wait_duration, true), }; app.add_resource(state) - .add_system(print_message_system.system()); + .add_system(print_message_system); } } diff --git a/examples/app/plugin_group.rs b/examples/app/plugin_group.rs index 81cd0b2ef2201..fbe533ea154e9 100644 --- a/examples/app/plugin_group.rs +++ b/examples/app/plugin_group.rs @@ -29,7 +29,7 @@ pub struct PrintHelloPlugin; impl Plugin for PrintHelloPlugin { fn build(&self, app: &mut AppBuilder) { - app.add_system(print_hello_system.system()); + app.add_system(print_hello_system); } } @@ -41,7 +41,7 @@ pub struct PrintWorldPlugin; impl Plugin for PrintWorldPlugin { fn build(&self, app: &mut AppBuilder) { - app.add_system(print_world_system.system()); + app.add_system(print_world_system); } } diff --git a/examples/asset/asset_loading.rs b/examples/asset/asset_loading.rs index 793f4685046e0..5ad62e0af404a 100644 --- a/examples/asset/asset_loading.rs +++ b/examples/asset/asset_loading.rs @@ -5,7 +5,7 @@ fn main() { App::build() .add_resource(Msaa { samples: 4 }) .add_plugins(DefaultPlugins) - .add_startup_system(setup.system()) + .add_startup_system(setup) .run(); } diff --git a/examples/asset/custom_asset.rs b/examples/asset/custom_asset.rs index 1d7cd87da2124..c28c5f6bc8016 100644 --- a/examples/asset/custom_asset.rs +++ b/examples/asset/custom_asset.rs @@ -39,8 +39,8 @@ fn main() { .init_resource::() .add_asset::() .init_asset_loader::() - .add_startup_system(setup.system()) - .add_system(print_on_load.system()) + .add_startup_system(setup) + .add_system(print_on_load) .run(); } diff --git a/examples/asset/hot_asset_reloading.rs b/examples/asset/hot_asset_reloading.rs index cf542a48e9355..edcaa35dc56d1 100644 --- a/examples/asset/hot_asset_reloading.rs +++ b/examples/asset/hot_asset_reloading.rs @@ -6,7 +6,7 @@ use bevy::prelude::*; fn main() { App::build() .add_plugins(DefaultPlugins) - .add_startup_system(setup.system()) + .add_startup_system(setup) .run(); } diff --git a/examples/audio/audio.rs b/examples/audio/audio.rs index a8296ad95305b..ca72402afeea2 100644 --- a/examples/audio/audio.rs +++ b/examples/audio/audio.rs @@ -4,7 +4,7 @@ use bevy::prelude::*; fn main() { App::build() .add_plugins(DefaultPlugins) - .add_startup_system(setup.system()) + .add_startup_system(setup) .run(); } diff --git a/examples/diagnostics/custom_diagnostic.rs b/examples/diagnostics/custom_diagnostic.rs index 4b2e832467a44..58f22137fb7f1 100644 --- a/examples/diagnostics/custom_diagnostic.rs +++ b/examples/diagnostics/custom_diagnostic.rs @@ -9,8 +9,8 @@ fn main() { .add_plugins(DefaultPlugins) // The "print diagnostics" plugin is optional. It just visualizes our diagnostics in the console .add_plugin(PrintDiagnosticsPlugin::default()) - .add_startup_system(setup_diagnostic_system.system()) - .add_system(my_system.system()) + .add_startup_system(setup_diagnostic_system) + .add_system(my_system) .run(); } diff --git a/examples/ecs/ecs_guide.rs b/examples/ecs/ecs_guide.rs index 48dc5dd0483ed..067d57a699693 100644 --- a/examples/ecs/ecs_guide.rs +++ b/examples/ecs/ecs_guide.rs @@ -256,9 +256,9 @@ fn main() { .init_resource::() // Startup systems run exactly once BEFORE all other systems. These are generally used for // app initialization code (ex: adding entities and resources) - .add_startup_system(startup_system.system()) - // my_system.system() calls converts normal rust functions into ECS systems: - .add_system(print_message_system.system()) + .add_startup_system(startup_system) + // my_system calls converts normal rust functions into ECS systems: + .add_system(print_message_system) // // SYSTEM EXECUTION ORDER // @@ -276,18 +276,18 @@ fn main() { // This is where "stages" come in. A "stage" is a group of systems that execute (in parallel). Stages are executed in order, // and the next stage won't start until all systems in the current stage have finished. // add_system(system) adds systems to the UPDATE stage by default - // However we can manually specify the stage if we want to. The following is equivalent to add_system(score_system.system()) - .add_system_to_stage(stage::UPDATE, score_system.system()) + // However we can manually specify the stage if we want to. The following is equivalent to add_system(score_system) + .add_system_to_stage(stage::UPDATE, score_system) // We can also create new stages. Here is what our games stage order will look like: // "before_round": new_player_system, new_round_system // "update": print_message_system, score_system // "after_round": score_check_system, game_over_system .add_stage_before(stage::UPDATE, "before_round") .add_stage_after(stage::UPDATE, "after_round") - .add_system_to_stage("before_round", new_round_system.system()) - .add_system_to_stage("before_round", new_player_system.system()) - .add_system_to_stage("after_round", score_check_system.system()) - .add_system_to_stage("after_round", game_over_system.system()) + .add_system_to_stage("before_round", new_round_system) + .add_system_to_stage("before_round", new_player_system) + .add_system_to_stage("after_round", score_check_system) + .add_system_to_stage("after_round", game_over_system) // score_check_system will run before game_over_system because score_check_system modifies GameState and game_over_system // reads GameState. This works, but it's a bit confusing. In practice, it would be clearer to create a new stage that runs // before "after_round" diff --git a/examples/ecs/event.rs b/examples/ecs/event.rs index 89c227c6416d9..eb02927c064d6 100644 --- a/examples/ecs/event.rs +++ b/examples/ecs/event.rs @@ -7,8 +7,8 @@ fn main() { .add_plugins(DefaultPlugins) .add_event::() .init_resource::() - .add_system(event_trigger_system.system()) - .add_system(event_listener_system.system()) + .add_system(event_trigger_system) + .add_system(event_listener_system) .run(); } diff --git a/examples/ecs/hierarchy.rs b/examples/ecs/hierarchy.rs index 5de54e1ad14c8..9dbbccf19c07c 100644 --- a/examples/ecs/hierarchy.rs +++ b/examples/ecs/hierarchy.rs @@ -3,8 +3,8 @@ use bevy::prelude::*; fn main() { App::build() .add_plugins(DefaultPlugins) - .add_startup_system(setup.system()) - .add_system(rotate.system()) + .add_startup_system(setup) + .add_system(rotate) .run(); } diff --git a/examples/ecs/parallel_query.rs b/examples/ecs/parallel_query.rs index 4d74fac3fb2b7..066131972e2db 100644 --- a/examples/ecs/parallel_query.rs +++ b/examples/ecs/parallel_query.rs @@ -74,8 +74,8 @@ fn bounce_system( fn main() { App::build() .add_plugins(DefaultPlugins) - .add_startup_system(spawn_system.system()) - .add_system(move_system.system()) - .add_system(bounce_system.system()) + .add_startup_system(spawn_system) + .add_system(move_system) + .add_system(bounce_system) .run(); } diff --git a/examples/ecs/startup_system.rs b/examples/ecs/startup_system.rs index 395d69322b12d..682eb7a7cfc40 100644 --- a/examples/ecs/startup_system.rs +++ b/examples/ecs/startup_system.rs @@ -2,8 +2,8 @@ use bevy::prelude::*; fn main() { App::build() - .add_startup_system(startup_system.system()) - .add_system(normal_system.system()) + .add_startup_system(startup_system) + .add_system(normal_system) .run(); } diff --git a/examples/game/breakout.rs b/examples/game/breakout.rs index 918f264b05b62..bf89101da18e8 100644 --- a/examples/game/breakout.rs +++ b/examples/game/breakout.rs @@ -10,11 +10,11 @@ fn main() { .add_plugins(DefaultPlugins) .add_resource(Scoreboard { score: 0 }) .add_resource(ClearColor(Color::rgb(0.9, 0.9, 0.9))) - .add_startup_system(setup.system()) - .add_system(paddle_movement_system.system()) - .add_system(ball_collision_system.system()) - .add_system(ball_movement_system.system()) - .add_system(scoreboard_system.system()) + .add_startup_system(setup) + .add_system(paddle_movement_system) + .add_system(ball_collision_system) + .add_system(ball_movement_system) + .add_system(scoreboard_system) .run(); } diff --git a/examples/hello_world.rs b/examples/hello_world.rs index 5078ebb2e22d1..6cdfa3e0489e8 100644 --- a/examples/hello_world.rs +++ b/examples/hello_world.rs @@ -1,7 +1,7 @@ use bevy::prelude::*; fn main() { - App::build().add_system(hello_world_system.system()).run(); + App::build().add_system(hello_world_system).run(); } fn hello_world_system() { diff --git a/examples/input/char_input_events.rs b/examples/input/char_input_events.rs index 207fe1c91caee..73c163e17b17b 100644 --- a/examples/input/char_input_events.rs +++ b/examples/input/char_input_events.rs @@ -3,7 +3,7 @@ use bevy::{prelude::*, window::ReceivedCharacter}; fn main() { App::build() .add_plugins(DefaultPlugins) - .add_system(print_char_event_system.system()) + .add_system(print_char_event_system) .run(); } diff --git a/examples/input/gamepad_input.rs b/examples/input/gamepad_input.rs index dccf64b2def26..dd8630c51d840 100644 --- a/examples/input/gamepad_input.rs +++ b/examples/input/gamepad_input.rs @@ -8,8 +8,8 @@ fn main() { App::build() .add_plugins(DefaultPlugins) .init_resource::() - .add_system_to_stage(stage::PRE_UPDATE, connection_system.system()) - .add_system(gamepad_system.system()) + .add_system_to_stage(stage::PRE_UPDATE, connection_system) + .add_system(gamepad_system) .run(); } diff --git a/examples/input/gamepad_input_events.rs b/examples/input/gamepad_input_events.rs index 3f4db960d718f..ce6cb8012b43b 100644 --- a/examples/input/gamepad_input_events.rs +++ b/examples/input/gamepad_input_events.rs @@ -6,7 +6,7 @@ use bevy::{ fn main() { App::build() .add_plugins(DefaultPlugins) - .add_system(gamepad_events.system()) + .add_system(gamepad_events) .run(); } diff --git a/examples/input/keyboard_input.rs b/examples/input/keyboard_input.rs index 65a5072635624..86828ae652b4d 100644 --- a/examples/input/keyboard_input.rs +++ b/examples/input/keyboard_input.rs @@ -6,7 +6,7 @@ use bevy::{ fn main() { App::build() .add_plugins(DefaultPlugins) - .add_system(keyboard_input_system.system()) + .add_system(keyboard_input_system) .run(); } diff --git a/examples/input/keyboard_input_events.rs b/examples/input/keyboard_input_events.rs index fc0fe43c7090c..0c8f172933490 100644 --- a/examples/input/keyboard_input_events.rs +++ b/examples/input/keyboard_input_events.rs @@ -3,7 +3,7 @@ use bevy::{input::keyboard::KeyboardInput, prelude::*}; fn main() { App::build() .add_plugins(DefaultPlugins) - .add_system(print_keyboard_event_system.system()) + .add_system(print_keyboard_event_system) .run(); } diff --git a/examples/input/mouse_input.rs b/examples/input/mouse_input.rs index 61fcac5d75c3f..6c19d05d24307 100644 --- a/examples/input/mouse_input.rs +++ b/examples/input/mouse_input.rs @@ -3,7 +3,7 @@ use bevy::prelude::*; fn main() { App::build() .add_plugins(DefaultPlugins) - .add_system(mouse_click_system.system()) + .add_system(mouse_click_system) .run(); } diff --git a/examples/input/mouse_input_events.rs b/examples/input/mouse_input_events.rs index f9bab2fca06f1..5d539315c6887 100644 --- a/examples/input/mouse_input_events.rs +++ b/examples/input/mouse_input_events.rs @@ -7,7 +7,7 @@ use bevy::{ fn main() { App::build() .add_plugins(DefaultPlugins) - .add_system(print_mouse_events_system.system()) + .add_system(print_mouse_events_system) .run(); } diff --git a/examples/input/touch_input.rs b/examples/input/touch_input.rs index d517b45401948..2c9873a16ce55 100644 --- a/examples/input/touch_input.rs +++ b/examples/input/touch_input.rs @@ -3,7 +3,7 @@ use bevy::{input::touch::*, prelude::*}; fn main() { App::build() .add_plugins(DefaultPlugins) - .add_system(touch_system.system()) + .add_system(touch_system) .run(); } diff --git a/examples/input/touch_input_events.rs b/examples/input/touch_input_events.rs index bb6b57b33b8cd..474ef2b60209b 100644 --- a/examples/input/touch_input_events.rs +++ b/examples/input/touch_input_events.rs @@ -3,7 +3,7 @@ use bevy::{input::touch::*, prelude::*}; fn main() { App::build() .add_plugins(DefaultPlugins) - .add_system(touch_event_system.system()) + .add_system(touch_event_system) .run(); } diff --git a/examples/ios/src/lib.rs b/examples/ios/src/lib.rs index 47b5fe673ac81..56cbd1b050905 100644 --- a/examples/ios/src/lib.rs +++ b/examples/ios/src/lib.rs @@ -12,7 +12,7 @@ fn main() { }) .add_resource(Msaa { samples: 4 }) .add_plugins(DefaultPlugins) - .add_startup_system(setup.system()) + .add_startup_system(setup) .run(); } /// set up a simple 3D scene diff --git a/examples/scene/properties.rs b/examples/scene/properties.rs index 5b26e14a78b80..89b6274ea433e 100644 --- a/examples/scene/properties.rs +++ b/examples/scene/properties.rs @@ -16,7 +16,7 @@ fn main() { .register_property::() .register_property::() .register_property::() - .add_startup_system(setup.system()) + .add_startup_system(setup) .run(); } diff --git a/examples/scene/scene.rs b/examples/scene/scene.rs index d8fb3e2a4b93c..23d38df975ccf 100644 --- a/examples/scene/scene.rs +++ b/examples/scene/scene.rs @@ -11,10 +11,10 @@ fn main() { // The core Bevy plugins already register their components, so you only need this step for custom components. .register_component::() .register_component::() - .add_startup_system(save_scene_system.thread_local_system()) - .add_startup_system(load_scene_system.system()) - .add_startup_system(infotext_system.system()) - .add_system(print_system.system()) + .add_startup_system(save_scene_system) + .add_startup_system(load_scene_system) + .add_startup_system(infotext_system) + .add_system(print_system) .run(); } diff --git a/examples/shader/mesh_custom_attribute.rs b/examples/shader/mesh_custom_attribute.rs index 30cf4e0b2bad3..013dc9bb199b6 100644 --- a/examples/shader/mesh_custom_attribute.rs +++ b/examples/shader/mesh_custom_attribute.rs @@ -15,7 +15,7 @@ fn main() { App::build() .add_plugins(DefaultPlugins) .add_asset::() - .add_startup_system(setup.system()) + .add_startup_system(setup) .run(); } diff --git a/examples/shader/shader_custom_material.rs b/examples/shader/shader_custom_material.rs index aef71801a718b..92bcbcad1128b 100644 --- a/examples/shader/shader_custom_material.rs +++ b/examples/shader/shader_custom_material.rs @@ -15,7 +15,7 @@ fn main() { App::build() .add_plugins(DefaultPlugins) .add_asset::() - .add_startup_system(setup.system()) + .add_startup_system(setup) .run(); } diff --git a/examples/shader/shader_defs.rs b/examples/shader/shader_defs.rs index e68127dc07272..05ea7027c03a4 100644 --- a/examples/shader/shader_defs.rs +++ b/examples/shader/shader_defs.rs @@ -16,10 +16,10 @@ fn main() { App::build() .add_plugins(DefaultPlugins) .add_asset::() - .add_startup_system(setup.system()) + .add_startup_system(setup) .add_system_to_stage( stage::POST_UPDATE, - asset_shader_defs_system::.system(), + asset_shader_defs_system::, ) .run(); } diff --git a/examples/tools/bevymark.rs b/examples/tools/bevymark.rs index 0a91f7e8e018b..3994f5b83717f 100644 --- a/examples/tools/bevymark.rs +++ b/examples/tools/bevymark.rs @@ -40,11 +40,11 @@ fn main() { .add_plugin(FrameTimeDiagnosticsPlugin::default()) .add_resource(BevyCounter { count: 0 }) .init_resource::() - .add_startup_system(setup.system()) - .add_system(mouse_handler.system()) - .add_system(movement_system.system()) - .add_system(collision_system.system()) - .add_system(counter_system.system()) + .add_startup_system(setup) + .add_system(mouse_handler) + .add_system(movement_system) + .add_system(collision_system) + .add_system(counter_system) .run(); } diff --git a/examples/ui/button.rs b/examples/ui/button.rs index 7dde7534ce914..48be106c3ab5e 100644 --- a/examples/ui/button.rs +++ b/examples/ui/button.rs @@ -5,8 +5,8 @@ fn main() { App::build() .add_plugins(DefaultPlugins) .init_resource::() - .add_startup_system(setup.system()) - .add_system(button_system.system()) + .add_startup_system(setup) + .add_system(button_system) .run(); } diff --git a/examples/ui/font_atlas_debug.rs b/examples/ui/font_atlas_debug.rs index 014519318c92d..c4b991b752662 100644 --- a/examples/ui/font_atlas_debug.rs +++ b/examples/ui/font_atlas_debug.rs @@ -5,9 +5,9 @@ fn main() { App::build() .init_resource::() .add_plugins(DefaultPlugins) - .add_startup_system(setup.system()) - .add_system(text_update_system.system()) - .add_system(atlas_render_system.system()) + .add_startup_system(setup) + .add_system(text_update_system) + .add_system(atlas_render_system) .run(); } diff --git a/examples/ui/text.rs b/examples/ui/text.rs index 6c863db643d41..6c98e482cbcb5 100644 --- a/examples/ui/text.rs +++ b/examples/ui/text.rs @@ -8,8 +8,8 @@ fn main() { App::build() .add_plugins(DefaultPlugins) .add_plugin(FrameTimeDiagnosticsPlugin::default()) - .add_startup_system(setup.system()) - .add_system(text_update_system.system()) + .add_startup_system(setup) + .add_system(text_update_system) .run(); } diff --git a/examples/ui/text_debug.rs b/examples/ui/text_debug.rs index da182f3fc01bd..856e934efd0a8 100644 --- a/examples/ui/text_debug.rs +++ b/examples/ui/text_debug.rs @@ -5,8 +5,8 @@ extern crate rand; fn main() { App::build() .add_plugins(DefaultPlugins) - .add_startup_system(infotext_system.system()) - .add_system(change_text_system.system()) + .add_startup_system(infotext_system) + .add_system(change_text_system) .run(); } diff --git a/examples/ui/ui.rs b/examples/ui/ui.rs index 9e596f28227d0..7c4e45c5bd526 100644 --- a/examples/ui/ui.rs +++ b/examples/ui/ui.rs @@ -4,7 +4,7 @@ use bevy::prelude::*; fn main() { App::build() .add_plugins(DefaultPlugins) - .add_startup_system(setup.system()) + .add_startup_system(setup) .run(); } diff --git a/examples/wasm/assets_wasm.rs b/examples/wasm/assets_wasm.rs index e9742b513b841..a38fc3640518a 100644 --- a/examples/wasm/assets_wasm.rs +++ b/examples/wasm/assets_wasm.rs @@ -13,8 +13,8 @@ fn main() { .add_plugins(DefaultPlugins) .add_asset::() .init_asset_loader::() - .add_startup_system(load_asset.system()) - .add_system(print_asset.system()) + .add_startup_system(load_asset) + .add_system(print_asset) .run(); } diff --git a/examples/wasm/headless_wasm.rs b/examples/wasm/headless_wasm.rs index 02053302bc182..5190152fa6344 100644 --- a/examples/wasm/headless_wasm.rs +++ b/examples/wasm/headless_wasm.rs @@ -12,8 +12,8 @@ fn main() { ))) .add_plugin(ScheduleRunnerPlugin::default()) .add_plugin(LogPlugin::default()) - .add_startup_system(hello_world_system.system()) - .add_system(counter.system()) + .add_startup_system(hello_world_system) + .add_system(counter) .run(); } diff --git a/examples/wasm/hello_wasm.rs b/examples/wasm/hello_wasm.rs index c3fbef4bdaa84..22c6f0960bb48 100644 --- a/examples/wasm/hello_wasm.rs +++ b/examples/wasm/hello_wasm.rs @@ -3,7 +3,7 @@ use bevy::{log::LogPlugin, prelude::*}; fn main() { App::build() .add_plugin(LogPlugin::default()) - .add_system(hello_wasm_system.system()) + .add_system(hello_wasm_system) .run(); } diff --git a/examples/wasm/winit_wasm.rs b/examples/wasm/winit_wasm.rs index bf73c081ec5c9..cc63adc23438e 100644 --- a/examples/wasm/winit_wasm.rs +++ b/examples/wasm/winit_wasm.rs @@ -15,12 +15,12 @@ fn main() { }) .add_plugins(DefaultPlugins) // One time greet - .add_startup_system(hello_wasm_system.system()) + .add_startup_system(hello_wasm_system) // Track ticks (sanity check, whether game loop is running) - .add_system(counter.system()) + .add_system(counter) // Track input events .init_resource::() - .add_system(track_input_events.system()) + .add_system(track_input_events) .run(); } diff --git a/examples/window/multiple_windows.rs b/examples/window/multiple_windows.rs index f4948af5efbb9..e86cbd55e832c 100644 --- a/examples/window/multiple_windows.rs +++ b/examples/window/multiple_windows.rs @@ -17,7 +17,7 @@ fn main() { App::build() .add_resource(Msaa { samples: 4 }) .add_plugins(DefaultPlugins) - .add_startup_system(setup.system()) + .add_startup_system(setup) .run(); } diff --git a/examples/window/window_settings.rs b/examples/window/window_settings.rs index faa5e1907c8c5..5e35f0df2d811 100644 --- a/examples/window/window_settings.rs +++ b/examples/window/window_settings.rs @@ -12,8 +12,8 @@ fn main() { ..Default::default() }) .add_plugins(DefaultPlugins) - .add_system(change_title.system()) - .add_system(toggle_cursor.system()) + .add_system(change_title) + .add_system(toggle_cursor) .run(); } From 67030cce7125d57f7ad88fc4d8c529380de81e3a Mon Sep 17 00:00:00 2001 From: Carter Anderson Date: Mon, 16 Nov 2020 14:12:29 -0800 Subject: [PATCH 4/7] improved chaining and cleanup --- crates/bevy_app/src/app_builder.rs | 38 ++-- crates/bevy_ecs/src/lib.rs | 4 +- crates/bevy_ecs/src/schedule/schedule.rs | 60 +++--- crates/bevy_ecs/src/system/into_system.rs | 7 + .../bevy_ecs/src/system/into_thread_local.rs | 7 +- crates/bevy_ecs/src/system/mod.rs | 2 + crates/bevy_ecs/src/system/system.rs | 148 +------------- crates/bevy_ecs/src/system/system_chaining.rs | 182 ++++++++++++++++++ crates/bevy_ecs/src/system/system_param.rs | 4 +- crates/bevy_render/src/lib.rs | 25 +-- .../hierarchy/hierarchy_maintenance_system.rs | 4 +- .../src/transform_propagate_system.rs | 3 +- examples/3d/3d_scene.rs | 1 - examples/app/plugin.rs | 3 +- examples/shader/shader_defs.rs | 5 +- 15 files changed, 257 insertions(+), 236 deletions(-) create mode 100644 crates/bevy_ecs/src/system/system_chaining.rs diff --git a/crates/bevy_app/src/app_builder.rs b/crates/bevy_app/src/app_builder.rs index 13693076f2ca3..68e0063da74c7 100644 --- a/crates/bevy_app/src/app_builder.rs +++ b/crates/bevy_app/src/app_builder.rs @@ -95,22 +95,22 @@ impl AppBuilder { self } - pub fn add_system(&mut self, system: Sys) -> &mut Self + pub fn add_system(&mut self, system: IntoS) -> &mut Self where - SystemType: System, - Sys: IntoSystem, + S: System, + IntoS: IntoSystem, { self.add_system_to_stage(stage::UPDATE, system) } - pub fn add_startup_system_to_stage( + pub fn add_startup_system_to_stage( &mut self, stage_name: &'static str, - system: Sys, + system: IntoS, ) -> &mut Self where - SystemType: System, - Sys: IntoSystem, + S: System, + IntoS: IntoSystem, { self.app .startup_schedule @@ -118,10 +118,10 @@ impl AppBuilder { self } - pub fn add_startup_system(&mut self, system: Sys) -> &mut Self + pub fn add_startup_system(&mut self, system: IntoS) -> &mut Self where - SystemType: System, - Sys: IntoSystem, + S: System, + IntoS: IntoSystem, { self.app .startup_schedule @@ -142,31 +142,31 @@ impl AppBuilder { .add_stage(stage::LAST) } - pub fn add_system_to_stage( + pub fn add_system_to_stage( &mut self, stage_name: &'static str, - system: Sys, + system: IntoS, ) -> &mut Self where - SystemType: System, - Sys: IntoSystem, + S: System, + IntoS: IntoSystem, { self.app.schedule.add_system_to_stage(stage_name, system); self } - pub fn add_system_to_stage_front( + pub fn add_system_to_stage_front( &mut self, stage_name: &'static str, - system: Sys, + system: IntoS, ) -> &mut Self where - SystemType: System, - Sys: IntoSystem, + S: System, + IntoS: IntoSystem, { self.app .schedule - .add_system_to_stage_front(stage_name, system); + .add_system_to_stage_front(stage_name, system.system()); self } diff --git a/crates/bevy_ecs/src/lib.rs b/crates/bevy_ecs/src/lib.rs index bd17ac8a89b57..0900bcb5dda23 100644 --- a/crates/bevy_ecs/src/lib.rs +++ b/crates/bevy_ecs/src/lib.rs @@ -15,7 +15,7 @@ pub mod prelude { core::WorldBuilderSource, resource::{ChangedRes, FromResources, Local, Res, ResMut, Resource, Resources}, system::{Commands, IntoSystem, Query, System}, - Added, Bundle, Changed, Component, Entity, Mut, Mutated, Or, QuerySet, Ref, RefMut, With, - Without, World, AsChainSystem + Added, Bundle, Changed, Component, Entity, FillSystemInput, In, IntoChainSystem, Mut, + Mutated, Or, QuerySet, Ref, RefMut, With, Without, World, }; } diff --git a/crates/bevy_ecs/src/schedule/schedule.rs b/crates/bevy_ecs/src/schedule/schedule.rs index f07b99c7a8422..4a6f4d20e29c7 100644 --- a/crates/bevy_ecs/src/schedule/schedule.rs +++ b/crates/bevy_ecs/src/schedule/schedule.rs @@ -96,32 +96,16 @@ impl Schedule { self.stage_order.insert(target_index, stage); } - pub fn add_system_to_stage( + pub fn add_system_to_stage( &mut self, stage_name: impl Into>, - system: Sys, + system: IntoS, ) -> &mut Self where - SystemType: System, - Sys: IntoSystem, + S: System, + IntoS: IntoSystem, { - let stage_name = stage_name.into(); - let systems = self - .stages - .get_mut(&stage_name) - .unwrap_or_else(|| panic!("Stage does not exist: {}", stage_name)); - let system = system.system(); - if self.system_ids.contains(&system.id()) { - panic!( - "System with id {:?} ({}) already exists", - system.id(), - system.name() - ); - } - self.system_ids.insert(system.id()); - systems.push(Box::new(system)); - - self.generation += 1; + self.add_system_to_stage_internal(stage_name.into(), Box::new(system.system())); self } @@ -129,8 +113,15 @@ impl Schedule { &mut self, stage_name: impl Into>, system: Box>, - ) -> &mut Self { - let stage_name = stage_name.into(); + ) { + self.add_system_to_stage_internal(stage_name.into(), system); + } + + fn add_system_to_stage_internal( + &mut self, + stage_name: Cow<'static, str>, + system: Box>, + ) { let systems = self .stages .get_mut(&stage_name) @@ -146,24 +137,30 @@ impl Schedule { systems.push(system); self.generation += 1; - self } - pub fn add_system_to_stage_front( + pub fn add_system_to_stage_front( &mut self, stage_name: impl Into>, - system: Sys, + system: IntoS, ) -> &mut Self where - SystemType: System, - Sys: IntoSystem, + S: System, + IntoS: IntoSystem, { - let stage_name = stage_name.into(); + self.add_system_to_stage_front_internal(stage_name.into(), Box::new(system.system())); + self + } + + fn add_system_to_stage_front_internal( + &mut self, + stage_name: Cow<'static, str>, + system: Box>, + ) { let systems = self .stages .get_mut(&stage_name) .unwrap_or_else(|| panic!("Stage does not exist: {}", stage_name)); - let system = system.system(); if self.system_ids.contains(&system.id()) { panic!( "System with id {:?} ({}) already exists", @@ -172,10 +169,9 @@ impl Schedule { ); } self.system_ids.insert(system.id()); - systems.insert(0, Box::new(system)); + systems.insert(0, system); self.generation += 1; - self } pub fn run(&mut self, world: &mut World, resources: &mut Resources) { diff --git a/crates/bevy_ecs/src/system/into_system.rs b/crates/bevy_ecs/src/system/into_system.rs index 57303abcf61a4..3e52aec040bbd 100644 --- a/crates/bevy_ecs/src/system/into_system.rs +++ b/crates/bevy_ecs/src/system/into_system.rs @@ -141,6 +141,13 @@ pub trait IntoSystem { fn system(self) -> SystemType; } +// Systems implicitly implement IntoSystem +impl IntoSystem<(), Sys> for Sys { + fn system(self) -> Sys { + self + } +} + macro_rules! impl_into_system { ($($param: ident),*) => { impl),*> IntoSystem<($($param,)*), FuncSystem> for Func diff --git a/crates/bevy_ecs/src/system/into_thread_local.rs b/crates/bevy_ecs/src/system/into_thread_local.rs index 543ff8a4504a7..4fe61b3da74b0 100644 --- a/crates/bevy_ecs/src/system/into_thread_local.rs +++ b/crates/bevy_ecs/src/system/into_thread_local.rs @@ -6,8 +6,7 @@ use crate::{ }; use std::{any::TypeId, borrow::Cow}; -pub struct ThreadLocalSystemFn -{ +pub struct ThreadLocalSystemFn { pub func: Box, pub resource_access: TypeAccess, pub archetype_component_access: TypeAccess, @@ -15,10 +14,10 @@ pub struct ThreadLocalSystemFn pub id: SystemId, } -impl System for ThreadLocalSystemFn -{ +impl System for ThreadLocalSystemFn { type Input = (); type Output = (); + fn name(&self) -> Cow<'static, str> { self.name.clone() } diff --git a/crates/bevy_ecs/src/system/mod.rs b/crates/bevy_ecs/src/system/mod.rs index 85ecede4c3367..b0ca3e3728849 100644 --- a/crates/bevy_ecs/src/system/mod.rs +++ b/crates/bevy_ecs/src/system/mod.rs @@ -4,6 +4,7 @@ mod into_thread_local; mod query; #[allow(clippy::module_inception)] mod system; +mod system_chaining; mod system_param; pub use commands::*; @@ -11,4 +12,5 @@ pub use into_system::*; pub use into_thread_local::*; pub use query::*; pub use system::*; +pub use system_chaining::*; pub use system_param::*; diff --git a/crates/bevy_ecs/src/system/system.rs b/crates/bevy_ecs/src/system/system.rs index bc40977148184..d2b7bc07b2387 100644 --- a/crates/bevy_ecs/src/system/system.rs +++ b/crates/bevy_ecs/src/system/system.rs @@ -29,6 +29,10 @@ pub trait System: Send + Sync + 'static { fn archetype_component_access(&self) -> &TypeAccess; fn resource_access(&self) -> &TypeAccess; fn thread_local_execution(&self) -> ThreadLocalExecution; + /// # Safety + /// This might access World and Resources in an unsafe manner. This should only be called in one of the following contexts: + /// 1. This system is the only system running on the given World and Resources across all threads + /// 2. This system only runs in parallel with other systems that do not conflict with the `archetype_component_access()` or `resource_access()` unsafe fn run_unsafe( &mut self, input: Self::Input, @@ -47,147 +51,3 @@ pub trait System: Send + Sync + 'static { fn run_thread_local(&mut self, world: &mut World, resources: &mut Resources); fn initialize(&mut self, _world: &mut World, _resources: &mut Resources) {} } - -pub struct ChainSystem { - a: SystemA, - b: SystemB, - name: Cow<'static, str>, - id: SystemId, - pub(crate) archetype_component_access: TypeAccess, - pub(crate) resource_access: TypeAccess, -} - -impl> System for ChainSystem { - type Input = SystemA::Input; - type Output = SystemB::Output; - - fn name(&self) -> Cow<'static, str> { - self.name.clone() - } - - fn id(&self) -> SystemId { - self.id - } - - fn is_initialized(&self) -> bool { - self.a.is_initialized() && self.b.is_initialized() - } - - fn update(&mut self, world: &World) { - self.archetype_component_access.clear(); - self.resource_access.clear(); - self.a.update(world); - self.b.update(world); - - self.archetype_component_access - .union(self.a.archetype_component_access()); - self.resource_access.union(self.b.resource_access()); - } - - fn archetype_component_access(&self) -> &TypeAccess { - &self.archetype_component_access - } - - fn resource_access(&self) -> &TypeAccess { - &self.resource_access - } - - fn thread_local_execution(&self) -> ThreadLocalExecution { - ThreadLocalExecution::NextFlush - } - - unsafe fn run_unsafe( - &mut self, - input: Self::Input, - world: &World, - resources: &Resources, - ) -> Option { - let out = self.a.run_unsafe(input, world, resources).unwrap(); - self.b.run_unsafe(out, world, resources) - } - - fn run_thread_local(&mut self, world: &mut World, resources: &mut Resources) { - self.a.run_thread_local(world, resources); - self.b.run_thread_local(world, resources); - } -} - -pub trait AsChainSystem>: System + Sized { - fn chain(self, system: SystemB) -> ChainSystem; -} - -impl> AsChainSystem for SystemA { - fn chain(self, system: SystemB) -> ChainSystem { - ChainSystem { - name: Cow::Owned(format!("Chain({}, {})", self.name(), system.name())), - a: self, - b: system, - archetype_component_access: Default::default(), - resource_access: Default::default(), - id: SystemId::new(), - } - } -} - -// pub struct FilledInputSystem { -// system: Box>, -// input: Input, -// } - -// impl System<(), Output> for FilledInputSystem { -// fn name(&self) -> Cow<'static, str> { -// self.system.name() -// } - -// fn id(&self) -> SystemId { -// self.system.id() -// } - -// fn is_initialized(&self) -> bool { -// self.system.is_initialized() -// } - -// fn update(&mut self, world: &World) { -// self.system.update(world); -// } - -// fn archetype_component_access(&self) -> &TypeAccess { -// self.system.archetype_component_access() -// } - -// fn resource_access(&self) -> &TypeAccess { -// self.system.resource_access() -// } - -// fn thread_local_execution(&self) -> ThreadLocalExecution { -// self.system.thread_local_execution() -// } - -// unsafe fn run_unsafe( -// &mut self, -// _input: (), -// world: &World, -// resources: &Resources, -// ) -> Option { -// self.system.run_unsafe(self.input.clone(), world, resources) -// } - -// fn run_thread_local(&mut self, world: &mut World, resources: &mut Resources) { -// self.system.run_thread_local(world, resources); -// } -// } - -// pub trait FillSystemInput { -// fn input(self, input: Input) -> Box>; -// } - -// impl FillSystemInput -// for Box> -// { -// fn input(self, input: Input) -> Box> { -// Box::new(FilledInputSystem { -// system: self, -// input, -// }) -// } -// } diff --git a/crates/bevy_ecs/src/system/system_chaining.rs b/crates/bevy_ecs/src/system/system_chaining.rs new file mode 100644 index 0000000000000..e6b5718836d45 --- /dev/null +++ b/crates/bevy_ecs/src/system/system_chaining.rs @@ -0,0 +1,182 @@ +use crate::{ + ArchetypeComponent, IntoSystem, Resources, System, SystemId, ThreadLocalExecution, TypeAccess, + World, +}; +use std::{any::TypeId, borrow::Cow}; + +pub struct ChainSystem { + system_a: SystemA, + system_b: SystemB, + name: Cow<'static, str>, + id: SystemId, + pub(crate) archetype_component_access: TypeAccess, + pub(crate) resource_access: TypeAccess, +} + +impl> System + for ChainSystem +{ + type Input = SystemA::Input; + type Output = SystemB::Output; + + fn name(&self) -> Cow<'static, str> { + self.name.clone() + } + + fn id(&self) -> SystemId { + self.id + } + + fn is_initialized(&self) -> bool { + self.system_a.is_initialized() && self.system_b.is_initialized() + } + + fn update(&mut self, world: &World) { + self.archetype_component_access.clear(); + self.resource_access.clear(); + self.system_a.update(world); + self.system_b.update(world); + + self.archetype_component_access + .union(self.system_a.archetype_component_access()); + self.resource_access.union(self.system_b.resource_access()); + } + + fn archetype_component_access(&self) -> &TypeAccess { + &self.archetype_component_access + } + + fn resource_access(&self) -> &TypeAccess { + &self.resource_access + } + + fn thread_local_execution(&self) -> ThreadLocalExecution { + ThreadLocalExecution::NextFlush + } + + unsafe fn run_unsafe( + &mut self, + input: Self::Input, + world: &World, + resources: &Resources, + ) -> Option { + let out = self.system_a.run_unsafe(input, world, resources).unwrap(); + self.system_b.run_unsafe(out, world, resources) + } + + fn run_thread_local(&mut self, world: &mut World, resources: &mut Resources) { + self.system_a.run_thread_local(world, resources); + self.system_b.run_thread_local(world, resources); + } +} + +pub trait IntoChainSystem: + IntoSystem + Sized +where + IntoB: IntoSystem, + SystemA: System, + SystemB: System, +{ + fn chain(self, system: IntoB) -> ChainSystem; +} + +impl + IntoChainSystem for IntoA +where + SystemA: System, + SystemB: System, + IntoA: IntoSystem, + IntoB: IntoSystem, +{ + fn chain(self, system: IntoB) -> ChainSystem { + let system_a = self.system(); + let system_b = system.system(); + ChainSystem { + name: Cow::Owned(format!("Chain({}, {})", system_a.name(), system_b.name())), + system_a, + system_b, + archetype_component_access: Default::default(), + resource_access: Default::default(), + id: SystemId::new(), + } + } +} + +pub struct FilledInputSystem +where + S::Input: Clone, +{ + system: S, + input: S::Input, +} + +impl System for FilledInputSystem +where + S::Input: Clone + Send + Sync, +{ + type Input = (); + type Output = S::Output; + + fn name(&self) -> Cow<'static, str> { + self.system.name() + } + + fn id(&self) -> SystemId { + self.system.id() + } + + fn is_initialized(&self) -> bool { + self.system.is_initialized() + } + + fn update(&mut self, world: &World) { + self.system.update(world); + } + + fn archetype_component_access(&self) -> &TypeAccess { + self.system.archetype_component_access() + } + + fn resource_access(&self) -> &TypeAccess { + self.system.resource_access() + } + + fn thread_local_execution(&self) -> ThreadLocalExecution { + self.system.thread_local_execution() + } + + unsafe fn run_unsafe( + &mut self, + _input: (), + world: &World, + resources: &Resources, + ) -> Option { + self.system.run_unsafe(self.input.clone(), world, resources) + } + + fn run_thread_local(&mut self, world: &mut World, resources: &mut Resources) { + self.system.run_thread_local(world, resources); + } +} + +pub trait FillSystemInput +where + S: System, + S::Input: Clone + Send + Sync, + IntoS: IntoSystem, +{ + fn fill_input(self, input: S::Input) -> FilledInputSystem; +} + +impl FillSystemInput for IntoS +where + S::Input: Clone + Send + Sync, + IntoS: IntoSystem, +{ + fn fill_input(self, input: S::Input) -> FilledInputSystem { + FilledInputSystem { + system: self.system(), + input, + } + } +} diff --git a/crates/bevy_ecs/src/system/system_param.rs b/crates/bevy_ecs/src/system/system_param.rs index a0a1de2fefed2..4d36d6c007d18 100644 --- a/crates/bevy_ecs/src/system/system_param.rs +++ b/crates/bevy_ecs/src/system/system_param.rs @@ -19,11 +19,9 @@ impl SystemParam for In { Some(In(input.take().unwrap())) } - fn init(_system_state: &mut SystemState, _world: &World, _resources: &mut Resources) { - } + fn init(_system_state: &mut SystemState, _world: &World, _resources: &mut Resources) {} } - pub trait SystemParam: Sized { fn init(system_state: &mut SystemState, world: &World, resources: &mut Resources); /// # Safety diff --git a/crates/bevy_render/src/lib.rs b/crates/bevy_render/src/lib.rs index 823d0d05652eb..9fd0ecda6d35b 100644 --- a/crates/bevy_render/src/lib.rs +++ b/crates/bevy_render/src/lib.rs @@ -120,14 +120,8 @@ impl Plugin for RenderPlugin { .init_resource::() .init_resource::() .init_resource::() - .add_system_to_stage( - bevy_app::stage::PRE_UPDATE, - draw::clear_draw_system, - ) - .add_system_to_stage( - bevy_app::stage::POST_UPDATE, - camera::active_cameras_system, - ) + .add_system_to_stage(bevy_app::stage::PRE_UPDATE, draw::clear_draw_system) + .add_system_to_stage(bevy_app::stage::POST_UPDATE, camera::active_cameras_system) .add_system_to_stage( bevy_app::stage::POST_UPDATE, camera::camera_system::, @@ -142,23 +136,14 @@ impl Plugin for RenderPlugin { camera::visible_entities_system, ) // TODO: turn these "resource systems" into graph nodes and remove the RENDER_RESOURCE stage - .add_system_to_stage( - stage::RENDER_RESOURCE, - mesh::mesh_resource_provider_system, - ) - .add_system_to_stage( - stage::RENDER_RESOURCE, - Texture::texture_resource_system, - ) + .add_system_to_stage(stage::RENDER_RESOURCE, mesh::mesh_resource_provider_system) + .add_system_to_stage(stage::RENDER_RESOURCE, Texture::texture_resource_system) .add_system_to_stage( stage::RENDER_GRAPH_SYSTEMS, render_graph::render_graph_schedule_executor_system, ) .add_system_to_stage(stage::DRAW, pipeline::draw_render_pipelines_system) - .add_system_to_stage( - stage::POST_RENDER, - shader::clear_shader_defs_system, - ); + .add_system_to_stage(stage::POST_RENDER, shader::clear_shader_defs_system); if app.resources().get::().is_none() { app.init_resource::(); diff --git a/crates/bevy_transform/src/hierarchy/hierarchy_maintenance_system.rs b/crates/bevy_transform/src/hierarchy/hierarchy_maintenance_system.rs index 7350bf105f414..09f67b68e8b05 100644 --- a/crates/bevy_transform/src/hierarchy/hierarchy_maintenance_system.rs +++ b/crates/bevy_transform/src/hierarchy/hierarchy_maintenance_system.rs @@ -67,9 +67,7 @@ pub fn parent_update_system( #[cfg(test)] mod test { use super::*; - use crate::{ - hierarchy::BuildChildren, transform_propagate_system::transform_propagate_system, - }; + use crate::{hierarchy::BuildChildren, transform_propagate_system::transform_propagate_system}; use bevy_ecs::{Resources, Schedule, World}; use bevy_math::Vec3; diff --git a/crates/bevy_transform/src/transform_propagate_system.rs b/crates/bevy_transform/src/transform_propagate_system.rs index a22b7edc044c2..05e335edbf0e6 100644 --- a/crates/bevy_transform/src/transform_propagate_system.rs +++ b/crates/bevy_transform/src/transform_propagate_system.rs @@ -50,7 +50,7 @@ fn propagate_recursive( #[cfg(test)] mod test { use super::*; - use crate::hierarchy::{BuildChildren, parent_update_system}; + use crate::hierarchy::{parent_update_system, BuildChildren}; use bevy_ecs::{Resources, Schedule, World}; use bevy_math::Vec3; @@ -113,7 +113,6 @@ mod test { schedule.add_system_to_stage("update", parent_update_system); schedule.add_system_to_stage("update", transform_propagate_system); - // Root entity let mut commands = Commands::default(); commands.set_entity_reserver(world.get_entity_reserver()); diff --git a/examples/3d/3d_scene.rs b/examples/3d/3d_scene.rs index bf03b134c8ed4..fb5be88b72be8 100644 --- a/examples/3d/3d_scene.rs +++ b/examples/3d/3d_scene.rs @@ -8,7 +8,6 @@ fn main() { .run(); } - /// set up a simple 3D scene fn setup( commands: &mut Commands, diff --git a/examples/app/plugin.rs b/examples/app/plugin.rs index d5fb41e811ee6..67dea32aaf32d 100644 --- a/examples/app/plugin.rs +++ b/examples/app/plugin.rs @@ -29,8 +29,7 @@ impl Plugin for PrintMessagePlugin { message: self.message.clone(), timer: Timer::new(self.wait_duration, true), }; - app.add_resource(state) - .add_system(print_message_system); + app.add_resource(state).add_system(print_message_system); } } diff --git a/examples/shader/shader_defs.rs b/examples/shader/shader_defs.rs index 05ea7027c03a4..3a4abfec84f8b 100644 --- a/examples/shader/shader_defs.rs +++ b/examples/shader/shader_defs.rs @@ -17,10 +17,7 @@ fn main() { .add_plugins(DefaultPlugins) .add_asset::() .add_startup_system(setup) - .add_system_to_stage( - stage::POST_UPDATE, - asset_shader_defs_system::, - ) + .add_system_to_stage(stage::POST_UPDATE, asset_shader_defs_system::) .run(); } From 7f7685f763f9025470d0fa2d4a4c70cdd6831dc1 Mon Sep 17 00:00:00 2001 From: Carter Anderson Date: Mon, 16 Nov 2020 16:25:14 -0800 Subject: [PATCH 5/7] remove input filling --- crates/bevy_ecs/src/system/system_chaining.rs | 79 ------------------- 1 file changed, 79 deletions(-) diff --git a/crates/bevy_ecs/src/system/system_chaining.rs b/crates/bevy_ecs/src/system/system_chaining.rs index e6b5718836d45..e4d998796a480 100644 --- a/crates/bevy_ecs/src/system/system_chaining.rs +++ b/crates/bevy_ecs/src/system/system_chaining.rs @@ -101,82 +101,3 @@ where } } } - -pub struct FilledInputSystem -where - S::Input: Clone, -{ - system: S, - input: S::Input, -} - -impl System for FilledInputSystem -where - S::Input: Clone + Send + Sync, -{ - type Input = (); - type Output = S::Output; - - fn name(&self) -> Cow<'static, str> { - self.system.name() - } - - fn id(&self) -> SystemId { - self.system.id() - } - - fn is_initialized(&self) -> bool { - self.system.is_initialized() - } - - fn update(&mut self, world: &World) { - self.system.update(world); - } - - fn archetype_component_access(&self) -> &TypeAccess { - self.system.archetype_component_access() - } - - fn resource_access(&self) -> &TypeAccess { - self.system.resource_access() - } - - fn thread_local_execution(&self) -> ThreadLocalExecution { - self.system.thread_local_execution() - } - - unsafe fn run_unsafe( - &mut self, - _input: (), - world: &World, - resources: &Resources, - ) -> Option { - self.system.run_unsafe(self.input.clone(), world, resources) - } - - fn run_thread_local(&mut self, world: &mut World, resources: &mut Resources) { - self.system.run_thread_local(world, resources); - } -} - -pub trait FillSystemInput -where - S: System, - S::Input: Clone + Send + Sync, - IntoS: IntoSystem, -{ - fn fill_input(self, input: S::Input) -> FilledInputSystem; -} - -impl FillSystemInput for IntoS -where - S::Input: Clone + Send + Sync, - IntoS: IntoSystem, -{ - fn fill_input(self, input: S::Input) -> FilledInputSystem { - FilledInputSystem { - system: self.system(), - input, - } - } -} From 7229ae41c5fb15fa64c7e1e2a8f1a4c76d6eb99e Mon Sep 17 00:00:00 2001 From: Carter Anderson Date: Mon, 16 Nov 2020 16:29:55 -0800 Subject: [PATCH 6/7] fix export --- crates/bevy_ecs/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/bevy_ecs/src/lib.rs b/crates/bevy_ecs/src/lib.rs index 0900bcb5dda23..a8ead603feed2 100644 --- a/crates/bevy_ecs/src/lib.rs +++ b/crates/bevy_ecs/src/lib.rs @@ -15,7 +15,7 @@ pub mod prelude { core::WorldBuilderSource, resource::{ChangedRes, FromResources, Local, Res, ResMut, Resource, Resources}, system::{Commands, IntoSystem, Query, System}, - Added, Bundle, Changed, Component, Entity, FillSystemInput, In, IntoChainSystem, Mut, - Mutated, Or, QuerySet, Ref, RefMut, With, Without, World, + Added, Bundle, Changed, Component, Entity, In, IntoChainSystem, Mut, Mutated, Or, QuerySet, + Ref, RefMut, With, Without, World, }; } From f847a4c7fd1fb6bfcaf1c86b716cfe13db2acd41 Mon Sep 17 00:00:00 2001 From: Carter Anderson Date: Mon, 16 Nov 2020 17:22:44 -0800 Subject: [PATCH 7/7] add example --- Cargo.toml | 4 ++++ examples/ecs/system_chaining.rs | 25 +++++++++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 examples/ecs/system_chaining.rs diff --git a/Cargo.toml b/Cargo.toml index 2db7dbf7f5f86..b986a072a6a28 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -194,6 +194,10 @@ path = "examples/ecs/event.rs" name = "startup_system" path = "examples/ecs/startup_system.rs" +[[example]] +name = "system_chaining" +path = "examples/ecs/system_chaining.rs" + [[example]] name = "ecs_guide" path = "examples/ecs/ecs_guide.rs" diff --git a/examples/ecs/system_chaining.rs b/examples/ecs/system_chaining.rs new file mode 100644 index 0000000000000..5640a366822af --- /dev/null +++ b/examples/ecs/system_chaining.rs @@ -0,0 +1,25 @@ +use anyhow::Result; +use bevy::prelude::*; + +fn main() { + App::build() + .add_resource(Message("hello".to_string())) + .add_system(parse_message_system.chain(handler_system)) + .run(); +} + +struct Message(String); + +// this system produces a Result output by trying to parse the Message resource +fn parse_message_system(message: Res) -> Result { + Ok(message.0.parse::()?) +} + +// This system takes a Result input and either prints the parsed value or the error message +// Try changing the Message resource to something that isn't an integer. You should see the error message printed. +fn handler_system(In(result): In>) { + match result { + Ok(value) => println!("parsed message: {}", value), + Err(err) => println!("encountered an error: {:?}", err), + } +}