Skip to content

Commit

Permalink
System Inputs, Outputs, Chaining, and Registration Ergo (#876)
Browse files Browse the repository at this point in the history
System Inputs, Outputs, Chaining, and Registration Ergo
  • Loading branch information
cart authored Nov 17, 2020
1 parent 50c7e22 commit 3a6f6de
Show file tree
Hide file tree
Showing 95 changed files with 594 additions and 460 deletions.
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
110 changes: 33 additions & 77 deletions crates/bevy_app/src/app_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,81 +95,40 @@ impl AppBuilder {
self
}

pub fn add_system(&mut self, system: Box<dyn System>) -> &mut Self {
pub fn add_system<S, Params, IntoS>(&mut self, system: IntoS) -> &mut Self
where
S: System<Input = (), Output = ()>,
IntoS: IntoSystem<Params, S>,
{
self.add_system_to_stage(stage::UPDATE, system)
}

pub fn add_systems(&mut self, systems: Vec<Box<dyn System>>) -> &mut Self {
self.add_systems_to_stage(stage::UPDATE, systems)
}

pub fn init_system(
&mut self,
build: impl FnMut(&mut Resources) -> Box<dyn System>,
) -> &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<dyn System>,
) -> &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<S, Params, IntoS>(
&mut self,
stage_name: &'static str,
system: Box<dyn System>,
) -> &mut Self {
system: IntoS,
) -> &mut Self
where
S: System<Input = (), Output = ()>,
IntoS: IntoSystem<Params, S>,
{
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<Box<dyn System>>,
) -> &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<dyn System>) -> &mut Self {
pub fn add_startup_system<S, Params, IntoS>(&mut self, system: IntoS) -> &mut Self
where
S: System<Input = (), Output = ()>,
IntoS: IntoSystem<Params, S>,
{
self.app
.startup_schedule
.add_system_to_stage(startup_stage::STARTUP, system);
self
}

pub fn add_startup_systems(&mut self, systems: Vec<Box<dyn System>>) -> &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<dyn System>,
) -> &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<dyn System>,
) -> &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)
Expand All @@ -183,34 +142,31 @@ impl AppBuilder {
.add_stage(stage::LAST)
}

pub fn add_system_to_stage(
pub fn add_system_to_stage<S, Params, IntoS>(
&mut self,
stage_name: &'static str,
system: Box<dyn System>,
) -> &mut Self {
system: IntoS,
) -> &mut Self
where
S: System<Input = (), Output = ()>,
IntoS: IntoSystem<Params, S>,
{
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<S, Params, IntoS>(
&mut self,
stage_name: &'static str,
system: Box<dyn System>,
) -> &mut Self {
system: IntoS,
) -> &mut Self
where
S: System<Input = (), Output = ()>,
IntoS: IntoSystem<Params, S>,
{
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<Box<dyn System>>,
) -> &mut Self {
for system in systems {
self.app.schedule.add_system_to_stage(stage_name, system);
}
.add_system_to_stage_front(stage_name, system.system());
self
}

Expand All @@ -219,7 +175,7 @@ impl AppBuilder {
T: Send + Sync + 'static,
{
self.add_resource(Events::<T>::default())
.add_system_to_stage(stage::EVENT, Events::<T>::update_system.system())
.add_system_to_stage(stage::EVENT, Events::<T>::update_system)
}

/// Adds a resource to the current [App] and overwrites any resource previously added of the same type.
Expand Down
12 changes: 3 additions & 9 deletions crates/bevy_asset/src/assets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -219,14 +219,8 @@ impl AddAsset for AppBuilder {

self.add_resource(assets)
.register_component::<Handle<T>>()
.add_system_to_stage(
super::stage::ASSET_EVENTS,
Assets::<T>::asset_event_system.system(),
)
.add_system_to_stage(
crate::stage::LOAD_ASSETS,
update_asset_storage_system::<T>.system(),
)
.add_system_to_stage(super::stage::ASSET_EVENTS, Assets::<T>::asset_event_system)
.add_system_to_stage(crate::stage::LOAD_ASSETS, update_asset_storage_system::<T>)
.add_event::<AssetEvent<T>>()
}

Expand Down
5 changes: 2 additions & 3 deletions crates/bevy_asset/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -80,13 +79,13 @@ impl Plugin for AssetPlugin {
.register_property::<HandleId>()
.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);
}
}
6 changes: 1 addition & 5 deletions crates/bevy_audio/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand All @@ -24,9 +23,6 @@ impl Plugin for AudioPlugin {
.add_asset::<AudioSource>()
.init_asset_loader::<Mp3Loader>()
.init_resource::<Audio<AudioSource>>()
.add_system_to_stage(
stage::POST_UPDATE,
play_queued_audio_system::<AudioSource>.thread_local_system(),
);
.add_system_to_stage(stage::POST_UPDATE, play_queued_audio_system::<AudioSource>);
}
}
7 changes: 3 additions & 4 deletions crates/bevy_core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -40,8 +39,8 @@ impl Plugin for CorePlugin {
.register_property::<Mat4>()
.register_property::<Quat>()
.register_property::<Option<String>>()
.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);
}
}
6 changes: 3 additions & 3 deletions crates/bevy_diagnostic/src/frame_time_diagnostics_plugin.rs
Original file line number Diff line number Diff line change
@@ -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)]
Expand All @@ -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);
}
}

Expand Down
9 changes: 3 additions & 6 deletions crates/bevy_diagnostic/src/print_diagnostics_plugin.rs
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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);
}
}
}
Expand Down
9 changes: 5 additions & 4 deletions crates/bevy_ecs/macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -408,23 +408,24 @@ 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);)*
#(<#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<Self> {
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(),)*
})
}
Expand Down
6 changes: 3 additions & 3 deletions crates/bevy_ecs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Added, Bundle, Changed, Component, Entity, Mut, Mutated, Or, QuerySet, Ref, RefMut, With,
Without, World,
system::{Commands, IntoSystem, Query, System},
Added, Bundle, Changed, Component, Entity, In, IntoChainSystem, Mut, Mutated, Or, QuerySet,
Ref, RefMut, With, Without, World,
};
}
4 changes: 2 additions & 2 deletions crates/bevy_ecs/src/resource/resource_query.rs
Original file line number Diff line number Diff line change
@@ -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

Expand Down
Loading

0 comments on commit 3a6f6de

Please sign in to comment.