Rework AppBuilder system interfaces. Remove setup() in favor of startup_system

This commit is contained in:
Carter Anderson 2020-04-15 19:40:24 -07:00
parent b5ec8e78d8
commit dcd71d1b72
21 changed files with 115 additions and 119 deletions

View File

@ -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<dyn Schedulable>) -> &mut Self {
pub fn add_system(&mut self, system: impl Into<System>) -> &mut Self {
self.add_system_to_stage(stage::UPDATE, system)
}
pub fn add_system_fn(
pub fn add_system_init<T>(&mut self, build: impl FnMut(&mut Resources) -> T) -> &mut Self
where
T: Into<System>,
{
self.add_system_to_stage_init(stage::UPDATE, build)
}
pub fn add_system_to_stage_init<T>(
&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<System>,
{
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<dyn Schedulable>,
system: impl Into<System>,
) -> &mut Self {
self.startup_schedule_plan
.add_system_to_stage(stage_name, system);
self
}
pub fn add_startup_system(&mut self, system: Box<dyn Schedulable>) -> &mut Self {
pub fn add_startup_system(&mut self, system: impl Into<System>) -> &mut Self {
self.startup_schedule_plan
.add_system_to_stage(stage::STARTUP, system);
self
}
pub fn add_startup_system_init<T>(
&mut self,
build: impl FnMut(&mut Resources) -> T,
) -> &mut Self
where
T: Into<System>,
{
self.add_startup_system_to_stage_init(stage::STARTUP, build)
}
pub fn add_startup_system_to_stage_init<T>(
&mut self,
stage: &str,
mut build: impl FnMut(&mut Resources) -> T,
) -> &mut Self
where
T: Into<System>,
{
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<F>(&mut self, build: F) -> &mut Self
where
F: Fn(&mut Resources) -> Box<dyn Schedulable>,
{
let system = build(self.resources_mut());
self.add_system(system)
}
pub fn build_system_on_stage<F>(&mut self, stage_name: &str, build: F) -> &mut Self
where
F: Fn(&mut Resources) -> Box<dyn Schedulable>,
{
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<dyn Schedulable>,
system: impl Into<System>,
) -> &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<dyn Runnable>,
) -> &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<T>(&mut self) -> &mut Self
where
T: Send + Sync + 'static,

View File

@ -1,12 +1,33 @@
use legion::prelude::*;
use std::{cmp::Ordering, collections::HashMap};
enum System {
pub enum System {
Schedulable(Box<dyn Schedulable>),
ThreadLocal(Box<dyn Runnable>),
ThreadLocalFn(Box<dyn FnMut(&mut World, &mut Resources)>),
}
impl From<Box<dyn Schedulable>> for System {
fn from(system: Box<dyn Schedulable>) -> Self {
System::Schedulable(system)
}
}
impl From<Box<dyn Runnable>> for System {
fn from(system: Box<dyn Runnable>) -> Self {
System::ThreadLocal(system)
}
}
impl<T> From<T> 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<String, Vec<System>>,
@ -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<dyn Schedulable>,
system: impl Into<System>,
) -> &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<dyn Runnable>,
) -> &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
}

View File

@ -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::<StandardMaterial>(),
)
// 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);
}
}

View File

@ -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);
}
}

View File

@ -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)]

View File

@ -9,7 +9,7 @@ fn main() {
.add_default_plugins()
.add_event::<MyEvent>()
.add_system(event_trigger_system())
.build_system(event_listener_system)
.add_system_init(event_listener_system)
.run();
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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) {

View File

@ -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();
}

View File

@ -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

View File

@ -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::<Test>()];

View File

@ -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::<MyMaterial>(),
)
.setup(setup)
.run();
}

View File

@ -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::<MyMaterial>(),

View File

@ -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();
}

View File

@ -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

View File

@ -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) {

View File

@ -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,

View File

@ -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();
//!}
//! ```