mirror of
https://github.com/bevyengine/bevy
synced 2024-11-22 04:33:37 +00:00
System Inputs, Outputs, Chaining, and Registration Ergo (#876)
System Inputs, Outputs, Chaining, and Registration Ergo
This commit is contained in:
parent
50c7e229b2
commit
3a6f6de277
95 changed files with 595 additions and 461 deletions
|
@ -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"
|
||||
|
|
|
@ -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)
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
|
|
@ -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::<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>>()
|
||||
}
|
||||
|
||||
|
|
|
@ -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::<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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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::<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>);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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::<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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(),)*
|
||||
})
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -147,7 +147,7 @@ impl ExecutorStage {
|
|||
pub fn prepare_to_next_thread_local(
|
||||
&mut self,
|
||||
world: &World,
|
||||
systems: &mut [Box<dyn System>],
|
||||
systems: &mut [Box<dyn System<Input = (), Output = ()>>],
|
||||
schedule_changed: bool,
|
||||
next_thread_local_index: usize,
|
||||
) -> Range<usize> {
|
||||
|
@ -329,7 +329,7 @@ impl ExecutorStage {
|
|||
&self,
|
||||
world: &World,
|
||||
resources: &Resources,
|
||||
systems: &mut [Box<dyn System>],
|
||||
systems: &mut [Box<dyn System<Input = (), Output = ()>>],
|
||||
prepared_system_range: Range<usize>,
|
||||
compute_pool: &TaskPool,
|
||||
) {
|
||||
|
@ -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
|
||||
|
@ -419,7 +422,7 @@ impl ExecutorStage {
|
|||
&mut self,
|
||||
world: &mut World,
|
||||
resources: &mut Resources,
|
||||
systems: &mut [Box<dyn System>],
|
||||
systems: &mut [Box<dyn System<Input = (), Output = ()>>],
|
||||
schedule_changed: bool,
|
||||
) {
|
||||
let start_archetypes_generation = world.archetypes_generation();
|
||||
|
@ -499,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);
|
||||
}
|
||||
|
||||
|
@ -552,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};
|
||||
|
@ -589,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);
|
||||
|
@ -620,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();
|
||||
|
@ -691,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
|
||||
|
||||
|
@ -722,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
|
||||
|
||||
|
@ -759,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(
|
||||
|
|
|
@ -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<Cow<'static, str>, Vec<Box<dyn System>>>,
|
||||
pub(crate) stages: HashMap<Cow<'static, str>, Vec<Box<dyn System<Input = (), Output = ()>>>>,
|
||||
pub(crate) stage_order: Vec<Cow<'static, str>>,
|
||||
pub(crate) system_ids: HashSet<SystemId>,
|
||||
generation: usize,
|
||||
|
@ -96,12 +96,32 @@ impl Schedule {
|
|||
self.stage_order.insert(target_index, stage);
|
||||
}
|
||||
|
||||
pub fn add_system_to_stage(
|
||||
pub fn add_system_to_stage<S, Params, IntoS>(
|
||||
&mut self,
|
||||
stage_name: impl Into<Cow<'static, str>>,
|
||||
system: Box<dyn System>,
|
||||
) -> &mut Self {
|
||||
let stage_name = stage_name.into();
|
||||
system: IntoS,
|
||||
) -> &mut Self
|
||||
where
|
||||
S: System<Input = (), Output = ()>,
|
||||
IntoS: IntoSystem<Params, S>,
|
||||
{
|
||||
self.add_system_to_stage_internal(stage_name.into(), Box::new(system.system()));
|
||||
self
|
||||
}
|
||||
|
||||
pub fn add_boxed_system_to_stage(
|
||||
&mut self,
|
||||
stage_name: impl Into<Cow<'static, str>>,
|
||||
system: Box<dyn System<Input = (), Output = ()>>,
|
||||
) {
|
||||
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<dyn System<Input = (), Output = ()>>,
|
||||
) {
|
||||
let systems = self
|
||||
.stages
|
||||
.get_mut(&stage_name)
|
||||
|
@ -117,15 +137,26 @@ impl Schedule {
|
|||
systems.push(system);
|
||||
|
||||
self.generation += 1;
|
||||
}
|
||||
|
||||
pub fn add_system_to_stage_front<S, Params, IntoS>(
|
||||
&mut self,
|
||||
stage_name: impl Into<Cow<'static, str>>,
|
||||
system: IntoS,
|
||||
) -> &mut Self
|
||||
where
|
||||
S: System<Input = (), Output = ()>,
|
||||
IntoS: IntoSystem<Params, S>,
|
||||
{
|
||||
self.add_system_to_stage_front_internal(stage_name.into(), Box::new(system.system()));
|
||||
self
|
||||
}
|
||||
|
||||
pub fn add_system_to_stage_front(
|
||||
fn add_system_to_stage_front_internal(
|
||||
&mut self,
|
||||
stage_name: impl Into<Cow<'static, str>>,
|
||||
system: Box<dyn System>,
|
||||
) -> &mut Self {
|
||||
let stage_name = stage_name.into();
|
||||
stage_name: Cow<'static, str>,
|
||||
system: Box<dyn System<Input = (), Output = ()>>,
|
||||
) {
|
||||
let systems = self
|
||||
.stages
|
||||
.get_mut(&stage_name)
|
||||
|
@ -141,7 +172,6 @@ impl Schedule {
|
|||
systems.insert(0, system);
|
||||
|
||||
self.generation += 1;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn run(&mut self, world: &mut World, resources: &mut Resources) {
|
||||
|
@ -150,9 +180,11 @@ 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);
|
||||
system.run((), world, resources);
|
||||
// NOTE: when this is made parallel a full sync is required here
|
||||
system.run_thread_local(world, resources);
|
||||
}
|
||||
|
@ -195,7 +227,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<Input = (), Output = ()>),
|
||||
) {
|
||||
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() {
|
||||
|
|
|
@ -73,24 +73,23 @@ impl SystemState {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct FuncSystem<F, Init, ThreadLocalFunc>
|
||||
where
|
||||
F: FnMut(&mut SystemState, &World, &Resources) + 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<Input, Return> {
|
||||
func: Box<
|
||||
dyn FnMut(Input, &mut SystemState, &World, &Resources) -> Option<Return>
|
||||
+ Send
|
||||
+ Sync
|
||||
+ 'static,
|
||||
>,
|
||||
thread_local_func:
|
||||
Box<dyn FnMut(&mut SystemState, &mut World, &mut Resources) + Send + Sync + 'static>,
|
||||
init_func: Box<dyn FnMut(&mut SystemState, &World, &mut Resources) + Send + Sync + 'static>,
|
||||
state: SystemState,
|
||||
}
|
||||
|
||||
impl<F, Init, ThreadLocalFunc> System for FuncSystem<F, Init, ThreadLocalFunc>
|
||||
where
|
||||
F: FnMut(&mut SystemState, &World, &Resources) + 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<Input: 'static, Output: 'static> System for FuncSystem<Input, Output> {
|
||||
type Input = Input;
|
||||
type Output = Output;
|
||||
|
||||
fn name(&self) -> std::borrow::Cow<'static, str> {
|
||||
self.state.name.clone()
|
||||
}
|
||||
|
@ -115,8 +114,13 @@ where
|
|||
ThreadLocalExecution::NextFlush
|
||||
}
|
||||
|
||||
fn run(&mut self, world: &World, resources: &Resources) {
|
||||
(self.func)(&mut self.state, world, resources)
|
||||
unsafe fn run_unsafe(
|
||||
&mut self,
|
||||
input: Input,
|
||||
world: &World,
|
||||
resources: &Resources,
|
||||
) -> Option<Output> {
|
||||
(self.func)(input, &mut self.state, world, resources)
|
||||
}
|
||||
|
||||
fn run_thread_local(&mut self, world: &mut World, resources: &mut Resources) {
|
||||
|
@ -133,20 +137,27 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
pub trait IntoSystem<Params> {
|
||||
fn system(self) -> Box<dyn System>;
|
||||
pub trait IntoSystem<Params, SystemType: System> {
|
||||
fn system(self) -> SystemType;
|
||||
}
|
||||
|
||||
// Systems implicitly implement IntoSystem
|
||||
impl<Sys: System> IntoSystem<(), Sys> for Sys {
|
||||
fn system(self) -> Sys {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_into_system {
|
||||
($($param: ident),*) => {
|
||||
impl<Func, $($param: SystemParam),*> IntoSystem<($($param,)*)> for Func
|
||||
where Func: FnMut($($param),*) + Send + Sync + 'static,
|
||||
impl<Func, Input, Return, $($param: SystemParam<Input>),*> IntoSystem<($($param,)*), FuncSystem<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<dyn System> {
|
||||
Box::new(FuncSystem {
|
||||
fn system(mut self) -> FuncSystem<Input, Return> {
|
||||
FuncSystem {
|
||||
state: SystemState {
|
||||
name: std::any::type_name::<Self>().into(),
|
||||
archetype_component_access: TypeAccess::default(),
|
||||
|
@ -161,28 +172,30 @@ macro_rules! impl_into_system {
|
|||
query_type_names: Vec::new(),
|
||||
current_query_index: 0,
|
||||
},
|
||||
func: move |state, world, resources| {
|
||||
func: Box::new(move |input, state, world, resources| {
|
||||
state.reset_indices();
|
||||
let mut input = Some(input);
|
||||
unsafe {
|
||||
if let Some(($($param,)*)) = <($($param,)*)>::get_param(state, world, resources) {
|
||||
self($($param),*);
|
||||
if let Some(($($param,)*)) = <($($param,)*)>::get_param(&mut input, state, world, resources) {
|
||||
Some(self($($param),*))
|
||||
} else {
|
||||
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);)*
|
||||
},
|
||||
})
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -273,7 +286,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::<bool>().unwrap(), "system ran");
|
||||
}
|
||||
|
@ -304,7 +317,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::<bool>().unwrap(), "system ran");
|
||||
}
|
||||
|
@ -324,7 +337,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);
|
||||
|
@ -357,7 +370,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);
|
||||
|
@ -387,7 +400,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]
|
||||
|
@ -399,7 +412,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]
|
||||
|
@ -410,7 +423,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]
|
||||
|
@ -422,7 +435,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]
|
||||
|
@ -433,10 +446,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<dyn System>) {
|
||||
fn run_system<
|
||||
Params,
|
||||
SystemType: System<Input = (), Output = ()>,
|
||||
Sys: IntoSystem<Params, SystemType>,
|
||||
>(
|
||||
world: &mut World,
|
||||
resources: &mut Resources,
|
||||
system: Sys,
|
||||
) {
|
||||
let mut schedule = Schedule::default();
|
||||
schedule.add_stage("update");
|
||||
schedule.add_system_to_stage("update", system);
|
||||
|
@ -450,7 +471,13 @@ mod tests {
|
|||
_buffer: Vec<u8>,
|
||||
}
|
||||
|
||||
fn test_for_conflicting_resources(sys: Box<dyn System>) {
|
||||
fn test_for_conflicting_resources<
|
||||
Params,
|
||||
SystemType: System<Input = (), Output = ()>,
|
||||
Sys: IntoSystem<Params, SystemType>,
|
||||
>(
|
||||
sys: Sys,
|
||||
) {
|
||||
let mut world = World::default();
|
||||
let mut resources = Resources::default();
|
||||
resources.insert(BufferRes::default());
|
||||
|
@ -463,21 +490,21 @@ mod tests {
|
|||
#[should_panic]
|
||||
fn conflicting_system_resources() {
|
||||
fn sys(_: ResMut<BufferRes>, _: Res<BufferRes>) {}
|
||||
test_for_conflicting_resources(sys.system())
|
||||
test_for_conflicting_resources(sys)
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn conflicting_system_resources_reverse_order() {
|
||||
fn sys(_: Res<BufferRes>, _: ResMut<BufferRes>) {}
|
||||
test_for_conflicting_resources(sys.system())
|
||||
test_for_conflicting_resources(sys)
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn conflicting_system_resources_multiple_mutable() {
|
||||
fn sys(_: ResMut<BufferRes>, _: ResMut<BufferRes>) {}
|
||||
test_for_conflicting_resources(sys.system())
|
||||
test_for_conflicting_resources(sys)
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -485,19 +512,19 @@ mod tests {
|
|||
fn conflicting_changed_and_mutable_resource() {
|
||||
// A tempting pattern, but unsound if allowed.
|
||||
fn sys(_: ResMut<BufferRes>, _: ChangedRes<BufferRes>) {}
|
||||
test_for_conflicting_resources(sys.system())
|
||||
test_for_conflicting_resources(sys)
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn conflicting_system_local_resources() {
|
||||
fn sys(_: Local<BufferRes>, _: Local<BufferRes>) {}
|
||||
test_for_conflicting_resources(sys.system())
|
||||
test_for_conflicting_resources(sys)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn nonconflicting_system_resources() {
|
||||
fn sys(_: Local<BufferRes>, _: ResMut<BufferRes>, _: Local<A>, _: ResMut<A>) {}
|
||||
test_for_conflicting_resources(sys.system())
|
||||
test_for_conflicting_resources(sys)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,26 +2,22 @@ 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<Func>
|
||||
where
|
||||
Func: FnMut(&mut World, &mut Resources) + Send + Sync,
|
||||
{
|
||||
pub func: Func,
|
||||
pub struct ThreadLocalSystemFn {
|
||||
pub func: Box<dyn FnMut(&mut World, &mut Resources) + Send + Sync + 'static>,
|
||||
pub resource_access: TypeAccess<TypeId>,
|
||||
pub archetype_component_access: TypeAccess<ArchetypeComponent>,
|
||||
pub name: Cow<'static, str>,
|
||||
pub id: SystemId,
|
||||
}
|
||||
|
||||
impl<Func> System for ThreadLocalSystemFn<Func>
|
||||
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 +36,14 @@ where
|
|||
ThreadLocalExecution::Immediate
|
||||
}
|
||||
|
||||
fn run(&mut self, _world: &World, _resources: &Resources) {}
|
||||
unsafe fn run_unsafe(
|
||||
&mut self,
|
||||
_input: (),
|
||||
_world: &World,
|
||||
_resources: &Resources,
|
||||
) -> Option<()> {
|
||||
Some(())
|
||||
}
|
||||
|
||||
fn run_thread_local(&mut self, world: &mut World, resources: &mut Resources) {
|
||||
(self.func)(world, resources);
|
||||
|
@ -57,22 +60,17 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
/// Converts `Self` into a thread local system
|
||||
pub trait IntoThreadLocalSystem {
|
||||
fn thread_local_system(self) -> Box<dyn System>;
|
||||
}
|
||||
|
||||
impl<F> IntoThreadLocalSystem for F
|
||||
impl<F> 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<dyn System> {
|
||||
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::<F>().into(),
|
||||
id: SystemId::new(),
|
||||
resource_access: TypeAccess::default(),
|
||||
archetype_component_access: TypeAccess::default(),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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::*;
|
||||
|
|
|
@ -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,7 +29,25 @@ pub trait System: Send + Sync {
|
|||
fn archetype_component_access(&self) -> &TypeAccess<ArchetypeComponent>;
|
||||
fn resource_access(&self) -> &TypeAccess<TypeId>;
|
||||
fn thread_local_execution(&self) -> ThreadLocalExecution;
|
||||
fn run(&mut self, world: &World, resources: &Resources);
|
||||
/// # 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,
|
||||
world: &World,
|
||||
resources: &Resources,
|
||||
) -> Option<Self::Output>;
|
||||
fn run(
|
||||
&mut self,
|
||||
input: Self::Input,
|
||||
world: &mut World,
|
||||
resources: &mut Resources,
|
||||
) -> Option<Self::Output> {
|
||||
// SAFE: world and resources are exclusively borrowed
|
||||
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) {}
|
||||
}
|
||||
|
|
103
crates/bevy_ecs/src/system/system_chaining.rs
Normal file
103
crates/bevy_ecs/src/system/system_chaining.rs
Normal file
|
@ -0,0 +1,103 @@
|
|||
use crate::{
|
||||
ArchetypeComponent, IntoSystem, Resources, System, SystemId, ThreadLocalExecution, TypeAccess,
|
||||
World,
|
||||
};
|
||||
use std::{any::TypeId, borrow::Cow};
|
||||
|
||||
pub struct ChainSystem<SystemA, SystemB> {
|
||||
system_a: SystemA,
|
||||
system_b: SystemB,
|
||||
name: Cow<'static, str>,
|
||||
id: SystemId,
|
||||
pub(crate) archetype_component_access: TypeAccess<ArchetypeComponent>,
|
||||
pub(crate) resource_access: TypeAccess<TypeId>,
|
||||
}
|
||||
|
||||
impl<SystemA: System, SystemB: System<Input = SystemA::Output>> System
|
||||
for ChainSystem<SystemA, SystemB>
|
||||
{
|
||||
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<ArchetypeComponent> {
|
||||
&self.archetype_component_access
|
||||
}
|
||||
|
||||
fn resource_access(&self) -> &TypeAccess<TypeId> {
|
||||
&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<Self::Output> {
|
||||
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<AParams, BParams, IntoB, SystemA, SystemB>:
|
||||
IntoSystem<AParams, SystemA> + Sized
|
||||
where
|
||||
IntoB: IntoSystem<BParams, SystemB>,
|
||||
SystemA: System,
|
||||
SystemB: System<Input = SystemA::Output>,
|
||||
{
|
||||
fn chain(self, system: IntoB) -> ChainSystem<SystemA, SystemB>;
|
||||
}
|
||||
|
||||
impl<AParams, BParams, IntoA, IntoB, SystemA, SystemB>
|
||||
IntoChainSystem<AParams, BParams, IntoB, SystemA, SystemB> for IntoA
|
||||
where
|
||||
SystemA: System,
|
||||
SystemB: System<Input = SystemA::Output>,
|
||||
IntoA: IntoSystem<AParams, SystemA>,
|
||||
IntoB: IntoSystem<BParams, SystemB>,
|
||||
{
|
||||
fn chain(self, system: IntoB) -> ChainSystem<SystemA, SystemB> {
|
||||
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(),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,21 +6,39 @@ use crate::{
|
|||
use parking_lot::Mutex;
|
||||
use std::{any::TypeId, sync::Arc};
|
||||
|
||||
pub trait SystemParam: Sized {
|
||||
pub struct In<Input>(pub Input);
|
||||
|
||||
impl<Input> SystemParam<Input> for In<Input> {
|
||||
#[inline]
|
||||
unsafe fn get_param(
|
||||
input: &mut Option<Input>,
|
||||
_system_state: &mut SystemState,
|
||||
_world: &World,
|
||||
_resources: &Resources,
|
||||
) -> Option<Self> {
|
||||
Some(In(input.take().unwrap()))
|
||||
}
|
||||
|
||||
fn init(_system_state: &mut SystemState, _world: &World, _resources: &mut Resources) {}
|
||||
}
|
||||
|
||||
pub trait SystemParam<Input>: 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<Input>,
|
||||
system_state: &mut SystemState,
|
||||
world: &World,
|
||||
resources: &Resources,
|
||||
) -> Option<Self>;
|
||||
}
|
||||
|
||||
impl<'a, Q: WorldQuery, F: QueryFilter> SystemParam for Query<'a, Q, F> {
|
||||
impl<'a, Q: WorldQuery, F: QueryFilter, Input> SystemParam<Input> for Query<'a, Q, F> {
|
||||
#[inline]
|
||||
unsafe fn get_param(
|
||||
_input: &mut Option<Input>,
|
||||
system_state: &mut SystemState,
|
||||
world: &World,
|
||||
_resources: &Resources,
|
||||
|
@ -45,9 +63,10 @@ impl<'a, Q: WorldQuery, F: QueryFilter> SystemParam for Query<'a, Q, F> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T: QueryTuple> SystemParam for QuerySet<T> {
|
||||
impl<T: QueryTuple, Input> SystemParam<Input> for QuerySet<T> {
|
||||
#[inline]
|
||||
unsafe fn get_param(
|
||||
_input: &mut Option<Input>,
|
||||
system_state: &mut SystemState,
|
||||
world: &World,
|
||||
_resources: &Resources,
|
||||
|
@ -71,7 +90,7 @@ impl<T: QueryTuple> SystemParam for QuerySet<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> SystemParam for &'a mut Commands {
|
||||
impl<'a, Input> SystemParam<Input> for &'a mut Commands {
|
||||
fn init(system_state: &mut SystemState, world: &World, _resources: &mut Resources) {
|
||||
system_state
|
||||
.commands
|
||||
|
@ -80,6 +99,7 @@ impl<'a> SystemParam for &'a mut Commands {
|
|||
|
||||
#[inline]
|
||||
unsafe fn get_param(
|
||||
_input: &mut Option<Input>,
|
||||
system_state: &mut SystemState,
|
||||
_world: &World,
|
||||
_resources: &Resources,
|
||||
|
@ -89,7 +109,7 @@ impl<'a> SystemParam for &'a mut Commands {
|
|||
}
|
||||
}
|
||||
|
||||
impl SystemParam for Arc<Mutex<Commands>> {
|
||||
impl<Input> SystemParam<Input> for Arc<Mutex<Commands>> {
|
||||
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 +120,7 @@ impl SystemParam for Arc<Mutex<Commands>> {
|
|||
|
||||
#[inline]
|
||||
unsafe fn get_param(
|
||||
_input: &mut Option<Input>,
|
||||
system_state: &mut SystemState,
|
||||
_world: &World,
|
||||
_resources: &Resources,
|
||||
|
@ -108,7 +129,7 @@ impl SystemParam for Arc<Mutex<Commands>> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, T: Resource> SystemParam for Res<'a, T> {
|
||||
impl<'a, T: Resource, Input> SystemParam<Input> for Res<'a, T> {
|
||||
fn init(system_state: &mut SystemState, _world: &World, _resources: &mut Resources) {
|
||||
if system_state.resource_access.is_write(&TypeId::of::<T>()) {
|
||||
panic!(
|
||||
|
@ -123,6 +144,7 @@ impl<'a, T: Resource> SystemParam for Res<'a, T> {
|
|||
|
||||
#[inline]
|
||||
unsafe fn get_param(
|
||||
_input: &mut Option<Input>,
|
||||
_system_state: &mut SystemState,
|
||||
_world: &World,
|
||||
resources: &Resources,
|
||||
|
@ -133,7 +155,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<Input> 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<Foo>, ResMut<Foo>)` or `fn(ResMut<Foo>, ResMut<Foo>)` must not be allowed.
|
||||
|
@ -153,6 +175,7 @@ impl<'a, T: Resource> SystemParam for ResMut<'a, T> {
|
|||
|
||||
#[inline]
|
||||
unsafe fn get_param(
|
||||
_input: &mut Option<Input>,
|
||||
_system_state: &mut SystemState,
|
||||
_world: &World,
|
||||
resources: &Resources,
|
||||
|
@ -163,7 +186,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<Input> for ChangedRes<'a, T> {
|
||||
fn init(system_state: &mut SystemState, _world: &World, _resources: &mut Resources) {
|
||||
if system_state.resource_access.is_write(&TypeId::of::<T>()) {
|
||||
panic!(
|
||||
|
@ -178,6 +201,7 @@ impl<'a, T: Resource> SystemParam for ChangedRes<'a, T> {
|
|||
|
||||
#[inline]
|
||||
unsafe fn get_param(
|
||||
_input: &mut Option<Input>,
|
||||
_system_state: &mut SystemState,
|
||||
_world: &World,
|
||||
resources: &Resources,
|
||||
|
@ -192,7 +216,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<Input> for Local<'a, T> {
|
||||
fn init(system_state: &mut SystemState, _world: &World, resources: &mut Resources) {
|
||||
if system_state
|
||||
.local_resource_access
|
||||
|
@ -220,6 +244,7 @@ impl<'a, T: Resource + FromResources> SystemParam for Local<'a, T> {
|
|||
|
||||
#[inline]
|
||||
unsafe fn get_param(
|
||||
_input: &mut Option<Input>,
|
||||
system_state: &mut SystemState,
|
||||
_world: &World,
|
||||
resources: &Resources,
|
||||
|
@ -231,38 +256,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<Input, $($param: SystemParam<Input>),*> SystemParam<Input> 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<Input>,
|
||||
system_state: &mut SystemState,
|
||||
world: &World,
|
||||
resources: &Resources,
|
||||
) -> Option<Self> {
|
||||
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<Input, $($param: SystemParam<Input>),*> SystemParam<Input> 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<Input>,
|
||||
system_state: &mut SystemState,
|
||||
world: &World,
|
||||
resources: &Resources,
|
||||
) -> Option<Self> {
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
}
|
||||
|
|
|
@ -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::<MouseMotion>()
|
||||
.add_event::<MouseWheel>()
|
||||
.init_resource::<Input<KeyCode>>()
|
||||
.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::<Input<MouseButton>>()
|
||||
.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::<GamepadEvent>()
|
||||
.add_event::<GamepadEventRaw>()
|
||||
.init_resource::<GamepadSettings>()
|
||||
.init_resource::<Input<GamepadButton>>()
|
||||
.init_resource::<Axis<GamepadAxis>>()
|
||||
.init_resource::<Axis<GamepadButton>>()
|
||||
.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::<TouchInput>()
|
||||
.init_resource::<Touches>()
|
||||
.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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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::<Light>()
|
||||
.add_system_to_stage(
|
||||
stage::POST_UPDATE,
|
||||
shader::asset_shader_defs_system::<StandardMaterial>.system(),
|
||||
shader::asset_shader_defs_system::<StandardMaterial>,
|
||||
)
|
||||
.init_resource::<AmbientLight>();
|
||||
let resources = app.resources();
|
||||
|
|
|
@ -51,7 +51,7 @@ struct LightCount {
|
|||
unsafe impl Byteable for LightCount {}
|
||||
|
||||
impl SystemNode for LightsNode {
|
||||
fn get_system(&self, commands: &mut Commands) -> Box<dyn System> {
|
||||
fn get_system(&self, commands: &mut Commands) -> Box<dyn System<Input = (), Output = ()>> {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
@ -121,45 +120,30 @@ impl Plugin for RenderPlugin {
|
|||
.init_resource::<TextureResourceSystemState>()
|
||||
.init_resource::<AssetRenderResourceBindings>()
|
||||
.init_resource::<ActiveCameras>()
|
||||
.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.system(),
|
||||
bevy_app::stage::POST_UPDATE,
|
||||
camera::camera_system::<OrthographicProjection>,
|
||||
)
|
||||
.add_system_to_stage(
|
||||
bevy_app::stage::POST_UPDATE,
|
||||
camera::active_cameras_system.system(),
|
||||
)
|
||||
.add_system_to_stage(
|
||||
bevy_app::stage::POST_UPDATE,
|
||||
camera::camera_system::<OrthographicProjection>.system(),
|
||||
)
|
||||
.add_system_to_stage(
|
||||
bevy_app::stage::POST_UPDATE,
|
||||
camera::camera_system::<PerspectiveProjection>.system(),
|
||||
camera::camera_system::<PerspectiveProjection>,
|
||||
)
|
||||
// registration order matters here. this must come after all camera_system::<T> 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(),
|
||||
)
|
||||
.add_system_to_stage(
|
||||
stage::RENDER_RESOURCE,
|
||||
Texture::texture_resource_system.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.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::POST_RENDER,
|
||||
shader::clear_shader_defs_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);
|
||||
|
||||
if app.resources().get::<Msaa>().is_none() {
|
||||
app.init_resource::<Msaa>();
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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<dyn System>;
|
||||
fn get_system(&self, commands: &mut Commands) -> Box<dyn System<Input = (), Output = ()>>;
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
|
@ -44,7 +44,7 @@ impl Node for CameraNode {
|
|||
}
|
||||
|
||||
impl SystemNode for CameraNode {
|
||||
fn get_system(&self, commands: &mut Commands) -> Box<dyn System> {
|
||||
fn get_system(&self, commands: &mut Commands) -> Box<dyn System<Input = (), Output = ()>> {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -387,7 +387,7 @@ impl<T> SystemNode for RenderResourcesNode<T>
|
|||
where
|
||||
T: renderer::RenderResources,
|
||||
{
|
||||
fn get_system(&self, commands: &mut Commands) -> Box<dyn System> {
|
||||
fn get_system(&self, commands: &mut Commands) -> Box<dyn System<Input = (), Output = ()>> {
|
||||
let system = render_resources_node_system::<T>.system();
|
||||
commands.insert_local_resource(
|
||||
system.id(),
|
||||
|
@ -398,7 +398,7 @@ where
|
|||
},
|
||||
);
|
||||
|
||||
system
|
||||
Box::new(system)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -527,7 +527,7 @@ impl<T> SystemNode for AssetRenderResourcesNode<T>
|
|||
where
|
||||
T: renderer::RenderResources + Asset,
|
||||
{
|
||||
fn get_system(&self, commands: &mut Commands) -> Box<dyn System> {
|
||||
fn get_system(&self, commands: &mut Commands) -> Box<dyn System<Input = (), Output = ()>> {
|
||||
let system = asset_render_resources_node_system::<T>.system();
|
||||
commands.insert_local_resource(
|
||||
system.id(),
|
||||
|
@ -538,7 +538,7 @@ where
|
|||
},
|
||||
);
|
||||
|
||||
system
|
||||
Box::new(system)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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::<SceneLoader>()
|
||||
.init_resource::<SceneSpawner>()
|
||||
.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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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::<ColorMaterial>()
|
||||
.add_asset::<TextureAtlas>()
|
||||
.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::<ColorMaterial>.system(),
|
||||
asset_shader_defs_system::<ColorMaterial>,
|
||||
);
|
||||
|
||||
let resources = app.resources_mut();
|
||||
|
|
|
@ -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,10 @@ pub fn parent_update_system(
|
|||
commands.insert_one(*k, Children::with(v));
|
||||
});
|
||||
}
|
||||
|
||||
pub fn hierarchy_maintenance_systems() -> Vec<Box<dyn System>> {
|
||||
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 +78,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();
|
||||
|
|
|
@ -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<Box<dyn System>> {
|
||||
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::<Transform>()
|
||||
.register_component::<GlobalTransform>()
|
||||
// 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,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ fn propagate_recursive(
|
|||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use crate::{hierarchy::BuildChildren, transform_systems};
|
||||
use crate::hierarchy::{parent_update_system, BuildChildren};
|
||||
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,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 mut commands = Commands::default();
|
||||
|
|
|
@ -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::<FlexSurface>()
|
||||
.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::<RenderGraph>().unwrap();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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::<winit::event::WindowEvent>()
|
||||
.init_resource::<WinitWindows>()
|
||||
.set_runner(winit_runner)
|
||||
.add_system(change_window.thread_local_system());
|
||||
.add_system(change_window);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ use bevy::prelude::*;
|
|||
fn main() {
|
||||
App::build()
|
||||
.add_plugins(DefaultPlugins)
|
||||
.add_startup_system(setup.system())
|
||||
.add_startup_system(setup)
|
||||
.run();
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -5,8 +5,8 @@ fn main() {
|
|||
App::build()
|
||||
.init_resource::<RpgSpriteHandles>()
|
||||
.add_plugins(DefaultPlugins)
|
||||
.add_startup_system(setup.system())
|
||||
.add_system(load_atlas.system())
|
||||
.add_startup_system(setup)
|
||||
.add_system(load_atlas)
|
||||
.run();
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ use bevy::prelude::*;
|
|||
fn main() {
|
||||
App::build()
|
||||
.add_plugins(DefaultPlugins)
|
||||
.add_startup_system(setup.system())
|
||||
.add_startup_system(setup)
|
||||
.run();
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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.system());
|
||||
app.add_resource(state).add_system(print_message_system);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -39,8 +39,8 @@ fn main() {
|
|||
.init_resource::<State>()
|
||||
.add_asset::<CustomAsset>()
|
||||
.init_asset_loader::<CustomAssetLoader>()
|
||||
.add_startup_system(setup.system())
|
||||
.add_system(print_on_load.system())
|
||||
.add_startup_system(setup)
|
||||
.add_system(print_on_load)
|
||||
.run();
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ use bevy::prelude::*;
|
|||
fn main() {
|
||||
App::build()
|
||||
.add_plugins(DefaultPlugins)
|
||||
.add_startup_system(setup.system())
|
||||
.add_startup_system(setup)
|
||||
.run();
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ use bevy::prelude::*;
|
|||
fn main() {
|
||||
App::build()
|
||||
.add_plugins(DefaultPlugins)
|
||||
.add_startup_system(setup.system())
|
||||
.add_startup_system(setup)
|
||||
.run();
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -256,9 +256,9 @@ fn main() {
|
|||
.init_resource::<GameState>()
|
||||
// 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"
|
||||
|
|
|
@ -7,8 +7,8 @@ fn main() {
|
|||
.add_plugins(DefaultPlugins)
|
||||
.add_event::<MyEvent>()
|
||||
.init_resource::<EventTriggerState>()
|
||||
.add_system(event_trigger_system.system())
|
||||
.add_system(event_listener_system.system())
|
||||
.add_system(event_trigger_system)
|
||||
.add_system(event_listener_system)
|
||||
.run();
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
25
examples/ecs/system_chaining.rs
Normal file
25
examples/ecs/system_chaining.rs
Normal file
|
@ -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<usize> output by trying to parse the Message resource
|
||||
fn parse_message_system(message: Res<Message>) -> Result<usize> {
|
||||
Ok(message.0.parse::<usize>()?)
|
||||
}
|
||||
|
||||
// This system takes a Result<usize> 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<Result<usize>>) {
|
||||
match result {
|
||||
Ok(value) => println!("parsed message: {}", value),
|
||||
Err(err) => println!("encountered an error: {:?}", err),
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -8,8 +8,8 @@ fn main() {
|
|||
App::build()
|
||||
.add_plugins(DefaultPlugins)
|
||||
.init_resource::<GamepadLobby>()
|
||||
.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();
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ use bevy::{
|
|||
fn main() {
|
||||
App::build()
|
||||
.add_plugins(DefaultPlugins)
|
||||
.add_system(gamepad_events.system())
|
||||
.add_system(gamepad_events)
|
||||
.run();
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -16,7 +16,7 @@ fn main() {
|
|||
.register_property::<Test>()
|
||||
.register_property::<Nested>()
|
||||
.register_property::<CustomProperty>()
|
||||
.add_startup_system(setup.system())
|
||||
.add_startup_system(setup)
|
||||
.run();
|
||||
}
|
||||
|
||||
|
|
|
@ -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::<ComponentA>()
|
||||
.register_component::<ComponentB>()
|
||||
.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();
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ fn main() {
|
|||
App::build()
|
||||
.add_plugins(DefaultPlugins)
|
||||
.add_asset::<MyMaterialWithVertexColorSupport>()
|
||||
.add_startup_system(setup.system())
|
||||
.add_startup_system(setup)
|
||||
.run();
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ fn main() {
|
|||
App::build()
|
||||
.add_plugins(DefaultPlugins)
|
||||
.add_asset::<MyMaterial>()
|
||||
.add_startup_system(setup.system())
|
||||
.add_startup_system(setup)
|
||||
.run();
|
||||
}
|
||||
|
||||
|
|
|
@ -16,11 +16,8 @@ fn main() {
|
|||
App::build()
|
||||
.add_plugins(DefaultPlugins)
|
||||
.add_asset::<MyMaterial>()
|
||||
.add_startup_system(setup.system())
|
||||
.add_system_to_stage(
|
||||
stage::POST_UPDATE,
|
||||
asset_shader_defs_system::<MyMaterial>.system(),
|
||||
)
|
||||
.add_startup_system(setup)
|
||||
.add_system_to_stage(stage::POST_UPDATE, asset_shader_defs_system::<MyMaterial>)
|
||||
.run();
|
||||
}
|
||||
|
||||
|
|
|
@ -40,11 +40,11 @@ fn main() {
|
|||
.add_plugin(FrameTimeDiagnosticsPlugin::default())
|
||||
.add_resource(BevyCounter { count: 0 })
|
||||
.init_resource::<BirdMaterial>()
|
||||
.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();
|
||||
}
|
||||
|
||||
|
|
|
@ -5,8 +5,8 @@ fn main() {
|
|||
App::build()
|
||||
.add_plugins(DefaultPlugins)
|
||||
.init_resource::<ButtonMaterials>()
|
||||
.add_startup_system(setup.system())
|
||||
.add_system(button_system.system())
|
||||
.add_startup_system(setup)
|
||||
.add_system(button_system)
|
||||
.run();
|
||||
}
|
||||
|
||||
|
|
|
@ -5,9 +5,9 @@ fn main() {
|
|||
App::build()
|
||||
.init_resource::<State>()
|
||||
.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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ use bevy::prelude::*;
|
|||
fn main() {
|
||||
App::build()
|
||||
.add_plugins(DefaultPlugins)
|
||||
.add_startup_system(setup.system())
|
||||
.add_startup_system(setup)
|
||||
.run();
|
||||
}
|
||||
|
||||
|
|
|
@ -13,8 +13,8 @@ fn main() {
|
|||
.add_plugins(DefaultPlugins)
|
||||
.add_asset::<RustSourceCode>()
|
||||
.init_asset_loader::<RustSourceCodeLoader>()
|
||||
.add_startup_system(load_asset.system())
|
||||
.add_system(print_asset.system())
|
||||
.add_startup_system(load_asset)
|
||||
.add_system(print_asset)
|
||||
.run();
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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::<TrackInputState>()
|
||||
.add_system(track_input_events.system())
|
||||
.add_system(track_input_events)
|
||||
.run();
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue