From dcd71d1b72474e5cdc7f60e9a3fdc94b55fc7d49 Mon Sep 17 00:00:00 2001 From: Carter Anderson Date: Wed, 15 Apr 2020 19:40:24 -0700 Subject: [PATCH] Rework AppBuilder system interfaces. Remove setup() in favor of startup_system --- bevy_app/src/app_builder.rs | 111 ++++++++++++-------------- bevy_app/src/schedule_plan.rs | 60 ++++++-------- bevy_render/src/lib.rs | 4 +- bevy_wgpu/src/lib.rs | 2 +- examples/entity_builder_comparison.rs | 5 +- examples/event.rs | 2 +- examples/hello_world.rs | 4 +- examples/input_keyboard.rs | 4 +- examples/input_mouse.rs | 2 +- examples/instancing.rs | 2 +- examples/multiple_windows.rs | 5 +- examples/parenting.rs | 2 +- examples/scene.rs | 5 +- examples/serializing.rs | 2 +- examples/shader_custom_material.rs | 2 +- examples/shader_defs.rs | 2 +- examples/spawner.rs | 4 +- examples/texture.rs | 5 +- examples/ui.rs | 5 +- examples/ui_bench.rs | 2 +- src/lib.rs | 4 +- 21 files changed, 115 insertions(+), 119 deletions(-) diff --git a/bevy_app/src/app_builder.rs b/bevy_app/src/app_builder.rs index 2f70915ee0..a43b4b7316 100644 --- a/bevy_app/src/app_builder.rs +++ b/bevy_app/src/app_builder.rs @@ -1,12 +1,10 @@ use crate::{ plugin::{load_plugin, AppPlugin}, - schedule_plan::SchedulePlan, + schedule_plan::{SchedulePlan, System}, stage, App, Events, }; -use legion::prelude::{ - CommandBuffer, Resources, Runnable, Schedulable, SystemBuilder, Universe, World, -}; +use legion::prelude::{Resources, Universe, World}; static APP_MISSING_MESSAGE: &str = "This AppBuilder no longer has an App. Check to see if you already called run(). A call to app_builder.run() consumes the AppBuilder's App."; @@ -71,20 +69,22 @@ impl AppBuilder { } pub fn build_and_run_startup_schedule(&mut self) -> &mut Self { - let mut startup_schedule = self.startup_schedule_plan.build(); + let resources = &mut self.app.as_mut().unwrap().resources; + let mut startup_schedule = self.startup_schedule_plan.build(resources); let app = self.app_mut(); startup_schedule.execute(&mut app.world, &mut app.resources); self } pub fn build_schedule(&mut self) -> &mut Self { - self.app_mut().schedule = Some(self.schedule_plan.build()); + let resources = &mut self.app.as_mut().unwrap().resources; + self.app_mut().schedule = Some(self.schedule_plan.build(resources)); self } pub fn run(&mut self) { - self.build_schedule(); self.build_and_run_startup_schedule(); + self.build_schedule(); self.app.take().unwrap().run(); } @@ -93,12 +93,6 @@ impl AppBuilder { self } - pub fn setup(&mut self, setup: impl Fn(&mut World, &mut Resources)) -> &mut Self { - let app = self.app_mut(); - setup(&mut app.world, &mut app.resources); - self - } - pub fn add_stage(&mut self, stage_name: &str) -> &mut Self { self.schedule_plan.add_stage(stage_name); self @@ -119,38 +113,67 @@ impl AppBuilder { self } - pub fn add_system(&mut self, system: Box) -> &mut Self { + pub fn add_system(&mut self, system: impl Into) -> &mut Self { self.add_system_to_stage(stage::UPDATE, system) } - pub fn add_system_fn( + pub fn add_system_init(&mut self, build: impl FnMut(&mut Resources) -> T) -> &mut Self + where + T: Into, + { + self.add_system_to_stage_init(stage::UPDATE, build) + } + + pub fn add_system_to_stage_init( &mut self, - name: &'static str, - system: impl Fn(&mut CommandBuffer) + Send + Sync + 'static, - ) -> &mut Self { - let built_system = SystemBuilder::new(name).build(move |command_buffer, _, _, _| { - system(command_buffer); - }); - self.add_system_to_stage(stage::UPDATE, built_system); - self + stage: &str, + mut build: impl FnMut(&mut Resources) -> T, + ) -> &mut Self + where + T: Into, + { + let system = build(self.resources_mut()); + self.add_system_to_stage(stage, system) } pub fn add_startup_system_to_stage( &mut self, stage_name: &str, - system: Box, + system: impl Into, ) -> &mut Self { self.startup_schedule_plan .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: impl Into) -> &mut Self { self.startup_schedule_plan .add_system_to_stage(stage::STARTUP, system); self } + pub fn add_startup_system_init( + &mut self, + build: impl FnMut(&mut Resources) -> T, + ) -> &mut Self + where + T: Into, + { + self.add_startup_system_to_stage_init(stage::STARTUP, build) + } + + pub fn add_startup_system_to_stage_init( + &mut self, + stage: &str, + mut build: impl FnMut(&mut Resources) -> T, + ) -> &mut Self + where + T: Into, + { + let system = build(self.resources_mut()); + self.add_startup_system_to_stage(stage, system) + } + pub fn add_default_stages(&mut self) -> &mut Self { self.add_startup_stage(stage::STARTUP) .add_stage(stage::FIRST) @@ -160,51 +183,15 @@ impl AppBuilder { .add_stage(stage::LAST) } - pub fn build_system(&mut self, build: F) -> &mut Self - where - F: Fn(&mut Resources) -> Box, - { - let system = build(self.resources_mut()); - self.add_system(system) - } - - pub fn build_system_on_stage(&mut self, stage_name: &str, build: F) -> &mut Self - where - F: Fn(&mut Resources) -> Box, - { - let system = build(self.resources_mut()); - self.add_system_to_stage(stage_name, system) - } - pub fn add_system_to_stage( &mut self, stage_name: &str, - system: Box, + system: impl Into, ) -> &mut Self { self.schedule_plan.add_system_to_stage(stage_name, system); self } - pub fn add_thread_local_to_stage( - &mut self, - stage_name: &str, - system: Box, - ) -> &mut Self { - self.schedule_plan - .add_thread_local_to_stage(stage_name, system); - self - } - - pub fn add_thread_local_fn_to_stage( - &mut self, - stage_name: &str, - f: impl FnMut(&mut World, &mut Resources) + 'static, - ) -> &mut Self { - self.schedule_plan - .add_thread_local_fn_to_stage(stage_name, f); - self - } - pub fn add_event(&mut self) -> &mut Self where T: Send + Sync + 'static, diff --git a/bevy_app/src/schedule_plan.rs b/bevy_app/src/schedule_plan.rs index 076a51f789..aeb3c5e1af 100644 --- a/bevy_app/src/schedule_plan.rs +++ b/bevy_app/src/schedule_plan.rs @@ -1,12 +1,33 @@ use legion::prelude::*; use std::{cmp::Ordering, collections::HashMap}; -enum System { +pub enum System { Schedulable(Box), ThreadLocal(Box), ThreadLocalFn(Box), } +impl From> for System { + fn from(system: Box) -> Self { + System::Schedulable(system) + } +} + +impl From> for System { + fn from(system: Box) -> Self { + System::ThreadLocal(system) + } +} + +impl From for System +where + T: FnMut(&mut World, &mut Resources) + 'static, +{ + fn from(system: T) -> Self { + System::ThreadLocalFn(Box::new(system)) + } +} + #[derive(Default)] pub struct SchedulePlan { stages: HashMap>, @@ -14,7 +35,7 @@ pub struct SchedulePlan { } impl SchedulePlan { - pub fn build(&mut self) -> Schedule { + pub fn build(&mut self, resources: &mut Resources) -> Schedule { let mut schedule_builder = Schedule::builder(); for stage in self.stage_order.drain(..) { @@ -89,44 +110,13 @@ impl SchedulePlan { pub fn add_system_to_stage( &mut self, stage_name: &str, - system: Box, + system: impl Into, ) -> &mut Self { - let system = System::Schedulable(system); let systems = self .stages .get_mut(stage_name) .unwrap_or_else(|| panic!("Stage does not exist: {}", stage_name)); - systems.push(system); - - self - } - - pub fn add_thread_local_to_stage( - &mut self, - stage_name: &str, - runnable: Box, - ) -> &mut Self { - let system = System::ThreadLocal(runnable); - let systems = self - .stages - .get_mut(stage_name) - .unwrap_or_else(|| panic!("Stage does not exist: {}", stage_name)); - systems.push(system); - - self - } - - pub fn add_thread_local_fn_to_stage( - &mut self, - stage_name: &str, - f: impl FnMut(&mut World, &mut Resources) + 'static, - ) -> &mut Self { - let system = System::ThreadLocalFn(Box::new(f)); - let systems = self - .stages - .get_mut(stage_name) - .unwrap_or_else(|| panic!("Stage does not exist: {}", stage_name)); - systems.push(system); + systems.push(system.into()); self } diff --git a/bevy_render/src/lib.rs b/bevy_render/src/lib.rs index a6be6bb1c0..c0c6c9b781 100644 --- a/bevy_render/src/lib.rs +++ b/bevy_render/src/lib.rs @@ -112,7 +112,7 @@ impl AppPlugin for RenderPlugin { .add_resource(asset_batchers) // core systems .add_system(build_entity_render_resource_assignments_system()) - .build_system_on_stage(stage::POST_UPDATE, camera::camera_update_system) + .add_system_to_stage_init(stage::POST_UPDATE, camera::camera_update_system) .add_system_to_stage(stage::POST_UPDATE, mesh::mesh_batcher_system()) .add_system_to_stage( stage::POST_UPDATE, @@ -123,7 +123,7 @@ impl AppPlugin for RenderPlugin { shader::asset_handle_batcher_system::(), ) // render resource provider systems - .build_system_on_stage(RENDER_RESOURCE_STAGE, mesh_resource_provider_system); + .add_system_to_stage_init(RENDER_RESOURCE_STAGE, mesh_resource_provider_system); RenderPlugin::setup_render_graph_defaults(app); } } diff --git a/bevy_wgpu/src/lib.rs b/bevy_wgpu/src/lib.rs index 0a86edf635..1974e98326 100644 --- a/bevy_wgpu/src/lib.rs +++ b/bevy_wgpu/src/lib.rs @@ -20,7 +20,7 @@ pub struct WgpuPlugin; impl AppPlugin for WgpuPlugin { fn build(&self, app: &mut AppBuilder) { let render_system = wgpu_render_system(app.resources_mut()); - app.add_thread_local_fn_to_stage(RENDER_STAGE, render_system); + app.add_system_to_stage(RENDER_STAGE, render_system); } } diff --git a/examples/entity_builder_comparison.rs b/examples/entity_builder_comparison.rs index fe74561e21..dbfbeb1fac 100644 --- a/examples/entity_builder_comparison.rs +++ b/examples/entity_builder_comparison.rs @@ -1,7 +1,10 @@ use bevy::prelude::*; fn main() { - App::build().add_default_plugins().setup(setup).run(); + App::build() + .add_default_plugins() + .add_startup_system(setup) + .run(); } #[allow(dead_code)] diff --git a/examples/event.rs b/examples/event.rs index 28507d6e8e..d04b9d03dd 100644 --- a/examples/event.rs +++ b/examples/event.rs @@ -9,7 +9,7 @@ fn main() { .add_default_plugins() .add_event::() .add_system(event_trigger_system()) - .build_system(event_listener_system) + .add_system_init(event_listener_system) .run(); } diff --git a/examples/hello_world.rs b/examples/hello_world.rs index 6f4df6ad16..64c149aafa 100644 --- a/examples/hello_world.rs +++ b/examples/hello_world.rs @@ -3,6 +3,8 @@ use bevy::prelude::*; fn main() { App::build() .add_default_plugins() - .add_system_fn("hello", |_| println!("hello world!")) + .add_system(|_: &mut World, _: &mut Resources| { + println!("hello world"); + }) .run(); } diff --git a/examples/input_keyboard.rs b/examples/input_keyboard.rs index 7a74e6ff8a..f9524db4bd 100644 --- a/examples/input_keyboard.rs +++ b/examples/input_keyboard.rs @@ -6,8 +6,8 @@ use bevy::{ fn main() { App::build() .add_default_plugins() - .build_system(move_on_input_system) - .setup(setup) + .add_system_init(move_on_input_system) + .add_startup_system(setup) .run(); } diff --git a/examples/input_mouse.rs b/examples/input_mouse.rs index 410d1a4c6f..035b002fc0 100644 --- a/examples/input_mouse.rs +++ b/examples/input_mouse.rs @@ -6,7 +6,7 @@ use bevy::{ fn main() { App::build() .add_default_plugins() - .build_system(mouse_input_system) + .add_system_init(mouse_input_system) .run(); } diff --git a/examples/instancing.rs b/examples/instancing.rs index d3c8fa9112..8d3d524a9f 100644 --- a/examples/instancing.rs +++ b/examples/instancing.rs @@ -4,12 +4,12 @@ use rand::{rngs::StdRng, Rng, SeedableRng}; fn main() { App::build() .add_default_plugins() + .add_startup_system(setup) .add_system(build_move_system()) .add_plugin(DiagnosticsPlugin { print_diagnostics: true, ..Default::default() }) - .setup(setup) .run(); } diff --git a/examples/multiple_windows.rs b/examples/multiple_windows.rs index 884020b4f4..50070da133 100644 --- a/examples/multiple_windows.rs +++ b/examples/multiple_windows.rs @@ -1,7 +1,10 @@ use bevy::{prelude::*, window::CreateWindow}; fn main() { - App::build().add_default_plugins().setup(setup).run(); + App::build() + .add_default_plugins() + .add_startup_system(setup) + .run(); } fn setup(_world: &mut World, resources: &mut Resources) { diff --git a/examples/parenting.rs b/examples/parenting.rs index eccae7e9ca..cb2522c97b 100644 --- a/examples/parenting.rs +++ b/examples/parenting.rs @@ -5,7 +5,7 @@ struct Rotator; fn main() { App::build() .add_default_plugins() - .setup(setup) + .add_startup_system(setup) .add_system(build_rotator_system()) .run(); } diff --git a/examples/scene.rs b/examples/scene.rs index ab323fddeb..2a72af61f3 100644 --- a/examples/scene.rs +++ b/examples/scene.rs @@ -1,7 +1,10 @@ use bevy::prelude::*; fn main() { - App::build().add_default_plugins().setup(setup).run(); + App::build() + .add_default_plugins() + .add_startup_system(setup) + .run(); } /// set up a simple scene diff --git a/examples/serializing.rs b/examples/serializing.rs index de8651939a..f963b0d93a 100644 --- a/examples/serializing.rs +++ b/examples/serializing.rs @@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize}; use type_uuid::TypeUuid; fn main() { let mut app = App::build(); - app.add_default_plugins().setup(setup); + app.add_default_plugins().add_startup_system(setup); let comp_registrations = [ComponentRegistration::of::()]; diff --git a/examples/shader_custom_material.rs b/examples/shader_custom_material.rs index 2cf54354b8..99e4f94012 100644 --- a/examples/shader_custom_material.rs +++ b/examples/shader_custom_material.rs @@ -3,11 +3,11 @@ use bevy::{prelude::*, render::shader}; fn main() { App::build() .add_default_plugins() + .add_startup_system(setup) .add_system_to_stage( stage::POST_UPDATE, shader::asset_handle_batcher_system::(), ) - .setup(setup) .run(); } diff --git a/examples/shader_defs.rs b/examples/shader_defs.rs index 7f53a97cf7..0222a42243 100644 --- a/examples/shader_defs.rs +++ b/examples/shader_defs.rs @@ -3,7 +3,7 @@ use bevy::{prelude::*, render::shader}; fn main() { App::build() .add_default_plugins() - .setup(setup) + .add_startup_system(setup) .add_system_to_stage( stage::POST_UPDATE, shader::asset_handle_batcher_system::(), diff --git a/examples/spawner.rs b/examples/spawner.rs index 4abfe7ff90..a19b1de289 100644 --- a/examples/spawner.rs +++ b/examples/spawner.rs @@ -4,12 +4,12 @@ use rand::{rngs::StdRng, Rng, SeedableRng}; fn main() { App::build() .add_default_plugins() - .add_system(build_move_system()) .add_plugin(DiagnosticsPlugin { print_diagnostics: true, ..Default::default() }) - .setup(setup) + .add_startup_system(setup) + .add_system(build_move_system()) .run(); } diff --git a/examples/texture.rs b/examples/texture.rs index 454f86f6f0..1c7ca8e3f7 100644 --- a/examples/texture.rs +++ b/examples/texture.rs @@ -1,7 +1,10 @@ use bevy::prelude::*; fn main() { - App::build().add_default_plugins().setup(setup).run(); + App::build() + .add_default_plugins() + .add_startup_system(setup) + .run(); } /// sets up a scene with textured entities diff --git a/examples/ui.rs b/examples/ui.rs index feaea8cea1..c9aa9d89e0 100644 --- a/examples/ui.rs +++ b/examples/ui.rs @@ -1,7 +1,10 @@ use bevy::prelude::*; fn main() { - App::build().add_default_plugins().setup(setup).run(); + App::build() + .add_default_plugins() + .add_startup_system(setup) + .run(); } fn setup(world: &mut World, resources: &mut Resources) { diff --git a/examples/ui_bench.rs b/examples/ui_bench.rs index c64f7de0d0..ba03427f1f 100644 --- a/examples/ui_bench.rs +++ b/examples/ui_bench.rs @@ -3,7 +3,7 @@ use bevy::prelude::*; fn main() { App::build() .add_default_plugins() - .setup(setup) + .add_startup_system(setup) .add_system(build_move_system()) .add_plugin(DiagnosticsPlugin { print_diagnostics: true, diff --git a/src/lib.rs b/src/lib.rs index 1675a51e13..8671c05c70 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,7 +14,9 @@ //!fn main() { //! App::build() //! .add_default_plugins() -//! .add_system_fn("hello", |_| println!("hello world!")) +//! .add_system(|_: &mut World, _: &mut Resources| { +//! println!("hello world"); +//! }) //! .run(); //!} //! ```