From 713c4a6056ca8ac139e270d400568eeea56f5cf3 Mon Sep 17 00:00:00 2001 From: Carter Anderson Date: Tue, 28 Apr 2020 11:25:24 -0700 Subject: [PATCH] move system function constructors to System --- crates/bevy_app/src/app_builder.rs | 50 +---------------- crates/bevy_app/src/lib.rs | 2 + crates/bevy_app/src/schedule_plan.rs | 30 +--------- crates/bevy_app/src/system.rs | 55 +++++++++++++++++++ .../legion_systems/src/system_fn.rs | 1 - examples/event.rs | 4 +- examples/spawner.rs | 2 +- examples/systems.rs | 34 ++++++++++++ src/prelude.rs | 4 +- 9 files changed, 101 insertions(+), 81 deletions(-) create mode 100644 crates/bevy_app/src/system.rs create mode 100644 examples/systems.rs diff --git a/crates/bevy_app/src/app_builder.rs b/crates/bevy_app/src/app_builder.rs index ce93b337a9..46c51e36b2 100644 --- a/crates/bevy_app/src/app_builder.rs +++ b/crates/bevy_app/src/app_builder.rs @@ -1,12 +1,10 @@ use crate::{ plugin::{load_plugin, AppPlugin}, - schedule_plan::{SchedulePlan, System}, - stage, App, AppExit, Events, + schedule_plan::SchedulePlan, + stage, App, AppExit, Events, System, }; -use legion::prelude::{Resources, Universe, World, IntoQuery, ResourceSet, into_system, into_resource_system}; -use legion::query::{View, DefaultFilter}; -use legion::filter::EntityFilter; +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."; @@ -239,46 +237,4 @@ impl AppBuilder { plugin.build(self); self } - - pub fn add_system_fn<'a, Q, F, R, X>(&mut self, name: &'static str, system: F) -> &mut Self - where - Q: IntoQuery + DefaultFilter, - >::Iter: Iterator + 'a, - F: FnMut(&mut X, Q) + Send + Sync + 'static, - R: EntityFilter + Sync + 'static, - X: ResourceSet + 'static, - { - self.add_system_fn_to_stage(stage::UPDATE, name, system) - } - - pub fn add_system_fn_to_stage<'a, Q, F, R, X>(&mut self, stage_name: &str, name: &'static str, system: F) -> &mut Self - where - Q: IntoQuery + DefaultFilter, - >::Iter: Iterator + 'a, - F: FnMut(&mut X, Q) + Send + Sync + 'static, - R: EntityFilter + Sync + 'static, - X: ResourceSet + 'static, - { - let system = into_system(name, system); - self.add_system_to_stage(stage_name, system); - self - } - - pub fn add_resource_system_fn<'a, F, X>(&mut self, name: &'static str, system: F) -> &mut Self - where - F: FnMut(&mut X) + Send + Sync + 'static, - X: ResourceSet + 'static, - { - self.add_resource_system_fn_to_stage(stage::UPDATE, name, system) - } - - pub fn add_resource_system_fn_to_stage<'a, F, X>(&mut self, stage_name: &str, name: &'static str, system: F) -> &mut Self - where - F: FnMut(&mut X) + Send + Sync + 'static, - X: ResourceSet + 'static, - { - let system = into_resource_system(name, system); - self.add_system_to_stage(stage_name, system); - self - } } diff --git a/crates/bevy_app/src/lib.rs b/crates/bevy_app/src/lib.rs index 7e8ed038be..d99035a664 100644 --- a/crates/bevy_app/src/lib.rs +++ b/crates/bevy_app/src/lib.rs @@ -3,6 +3,7 @@ mod app_builder; mod entity_archetype; mod event; mod plugin; +mod system; pub mod schedule_plan; pub mod schedule_runner; pub mod stage; @@ -12,3 +13,4 @@ pub use app_builder::*; pub use entity_archetype::*; pub use event::*; pub use plugin::*; +pub use system::*; diff --git a/crates/bevy_app/src/schedule_plan.rs b/crates/bevy_app/src/schedule_plan.rs index 82cb50acb2..3df1df62c7 100644 --- a/crates/bevy_app/src/schedule_plan.rs +++ b/crates/bevy_app/src/schedule_plan.rs @@ -1,32 +1,6 @@ -use legion::prelude::*; use std::{cmp::Ordering, collections::HashMap}; - -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)) - } -} +use crate::System; +use legion::prelude::Schedule; #[derive(Default)] pub struct SchedulePlan { diff --git a/crates/bevy_app/src/system.rs b/crates/bevy_app/src/system.rs new file mode 100644 index 0000000000..257143f7af --- /dev/null +++ b/crates/bevy_app/src/system.rs @@ -0,0 +1,55 @@ +use legion::{ + filter::EntityFilter, + prelude::{ + into_resource_system, into_system, IntoQuery, ResourceSet, Resources, Runnable, + Schedulable, World, + }, + query::{DefaultFilter, View}, +}; +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)) + } +} + +impl System { + pub fn resource_for<'a, Q, F, R, X>(name: &'static str, system: F) -> Self + where + Q: IntoQuery + DefaultFilter, + >::Iter: Iterator + 'a, + F: FnMut(&mut X, Q) + Send + Sync + 'static, + R: EntityFilter + Sync + 'static, + X: ResourceSet + 'static, + { + into_system(name, system).into() + } + + pub fn resource<'a, F, X>(name: &'static str, system: F) -> Self + where + F: FnMut(&mut X) + Send + Sync + 'static, + X: ResourceSet + 'static, + { + into_resource_system(name, system).into() + } +} diff --git a/crates/bevy_legion/legion_systems/src/system_fn.rs b/crates/bevy_legion/legion_systems/src/system_fn.rs index e04c8f8605..986fa3d3b8 100644 --- a/crates/bevy_legion/legion_systems/src/system_fn.rs +++ b/crates/bevy_legion/legion_systems/src/system_fn.rs @@ -13,7 +13,6 @@ use legion_core::{ use std::marker::PhantomData; use bit_set::BitSet; - pub fn into_system<'a, Q, F, R, X>(name: &'static str, mut system: F) -> Box where Q: IntoQuery + DefaultFilter, diff --git a/examples/event.rs b/examples/event.rs index 8bd8701966..0ac96034fc 100644 --- a/examples/event.rs +++ b/examples/event.rs @@ -6,8 +6,8 @@ fn main() { .add_event::() .add_resource(EventTriggerState::default()) .add_resource_init::() - .add_resource_system_fn("event_trigger", event_trigger_system) - .add_resource_system_fn("event_listener", event_listener_system) + .add_system(System::resource("event_trigger", event_trigger_system)) + .add_system(System::resource("event_listener", event_listener_system)) .run(); } diff --git a/examples/spawner.rs b/examples/spawner.rs index 4f39a9042a..036d143346 100644 --- a/examples/spawner.rs +++ b/examples/spawner.rs @@ -9,7 +9,7 @@ fn main() { ..Default::default() }) .add_startup_system(setup) - .add_system_fn("move", move_system) + .add_system(System::resource_for("move", move_system)) .run(); } diff --git a/examples/systems.rs b/examples/systems.rs new file mode 100644 index 0000000000..54ac2f452b --- /dev/null +++ b/examples/systems.rs @@ -0,0 +1,34 @@ +use bevy::{ + input::mouse::{MouseButtonInput, MouseMotion}, + prelude::*, +}; + +fn main() { + App::build() + .add_default_plugins() + .add_system_init(mouse_input_system) + .run(); +} + +/// prints out mouse events as they come in +pub fn mouse_input_system(resources: &mut Resources) -> Box { + let mut mouse_button_input_event_reader = resources.get_event_reader::(); + let mut mouse_motion_event_reader = resources.get_event_reader::(); + SystemBuilder::new("mouse_input") + .read_resource::>() + .read_resource::>() + .build( + move |_command_buffer, + _world, + (mouse_button_input_events, mouse_motion_events), + _queries| { + for event in mouse_button_input_event_reader.iter(&mouse_button_input_events) { + println!("{:?}", event); + } + + for event in mouse_motion_event_reader.iter(&mouse_motion_events) { + println!("{:?}", event); + } + }, + ) +} diff --git a/src/prelude.rs b/src/prelude.rs index 2aed5a73c4..bca12901b2 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -38,7 +38,7 @@ pub use crate::ui::{entity::*, Anchors, Margins, Node}; pub use crate::window::{Window, WindowDescriptor, WindowPlugin, Windows}; pub use crate::{ app::{ - stage, App, AppBuilder, AppPlugin, EntityArchetype, EventReader, Events, GetEventReader, + stage, App, AppBuilder, AppPlugin, EntityArchetype, EventReader, Events, GetEventReader, System }, math::{self, Mat3, Mat4, Quat, Vec2, Vec3, Vec4}, AddDefaultPlugins, @@ -54,7 +54,7 @@ pub use legion::{ bit_set::BitSet, resource::{ResourceSet, Resources, PreparedRead as Resource, PreparedWrite as ResourceMut}, schedule::{Executor, Runnable, Schedulable, Schedule}, - SubWorld, System, SystemBuilder, + SubWorld, SystemBuilder, into_system, into_resource_system }, world::{Universe, World},