Base Sets (#7466)
# Objective NOTE: This depends on #7267 and should not be merged until #7267 is merged. If you are reviewing this before that is merged, I highly recommend viewing the Base Sets commit instead of trying to find my changes amongst those from #7267. "Default sets" as described by the [Stageless RFC](https://github.com/bevyengine/rfcs/pull/45) have some [unfortunate consequences](https://github.com/bevyengine/bevy/discussions/7365). ## Solution This adds "base sets" as a variant of `SystemSet`: A set is a "base set" if `SystemSet::is_base` returns `true`. Typically this will be opted-in to using the `SystemSet` derive: ```rust #[derive(SystemSet, Clone, Hash, Debug, PartialEq, Eq)] #[system_set(base)] enum MyBaseSet { A, B, } ``` **Base sets are exclusive**: a system can belong to at most one "base set". Adding a system to more than one will result in an error. When possible we fail immediately during system-config-time with a nice file + line number. For the more nested graph-ey cases, this will fail at the final schedule build. **Base sets cannot belong to other sets**: this is where the word "base" comes from Systems and Sets can only be added to base sets using `in_base_set`. Calling `in_set` with a base set will fail. As will calling `in_base_set` with a normal set. ```rust app.add_system(foo.in_base_set(MyBaseSet::A)) // X must be a normal set ... base sets cannot be added to base sets .configure_set(X.in_base_set(MyBaseSet::A)) ``` Base sets can still be configured like normal sets: ```rust app.add_system(MyBaseSet::B.after(MyBaseSet::Ap)) ``` The primary use case for base sets is enabling a "default base set": ```rust schedule.set_default_base_set(CoreSet::Update) // this will belong to CoreSet::Update by default .add_system(foo) // this will override the default base set with PostUpdate .add_system(bar.in_base_set(CoreSet::PostUpdate)) ``` This allows us to build apis that work by default in the standard Bevy style. This is a rough analog to the "default stage" model, but it use the new "stageless sets" model instead, with all of the ordering flexibility (including exclusive systems) that it provides. --- ## Changelog - Added "base sets" and ported CoreSet to use them. ## Migration Guide TODO
This commit is contained in:
parent
206c7ce219
commit
dcc03724a5
@ -552,7 +552,7 @@ impl Plugin for AnimationPlugin {
|
|||||||
.register_type::<AnimationPlayer>()
|
.register_type::<AnimationPlayer>()
|
||||||
.add_system(
|
.add_system(
|
||||||
animation_player
|
animation_player
|
||||||
.in_set(CoreSet::PostUpdate)
|
.in_base_set(CoreSet::PostUpdate)
|
||||||
.before(TransformSystem::TransformPropagate),
|
.before(TransformSystem::TransformPropagate),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -328,14 +328,14 @@ impl App {
|
|||||||
apply_state_transition::<S>,
|
apply_state_transition::<S>,
|
||||||
)
|
)
|
||||||
.chain()
|
.chain()
|
||||||
.in_set(CoreSet::StateTransitions),
|
.in_base_set(CoreSet::StateTransitions),
|
||||||
);
|
);
|
||||||
|
|
||||||
let main_schedule = self.get_schedule_mut(CoreSchedule::Main).unwrap();
|
let main_schedule = self.get_schedule_mut(CoreSchedule::Main).unwrap();
|
||||||
for variant in S::variants() {
|
for variant in S::variants() {
|
||||||
main_schedule.configure_set(
|
main_schedule.configure_set(
|
||||||
OnUpdate(variant.clone())
|
OnUpdate(variant.clone())
|
||||||
.in_set(CoreSet::StateTransitions)
|
.in_base_set(CoreSet::StateTransitions)
|
||||||
.run_if(state_equals(variant))
|
.run_if(state_equals(variant))
|
||||||
.after(apply_state_transition::<S>),
|
.after(apply_state_transition::<S>),
|
||||||
);
|
);
|
||||||
@ -580,7 +580,7 @@ impl App {
|
|||||||
{
|
{
|
||||||
if !self.world.contains_resource::<Events<T>>() {
|
if !self.world.contains_resource::<Events<T>>() {
|
||||||
self.init_resource::<Events<T>>()
|
self.init_resource::<Events<T>>()
|
||||||
.add_system(Events::<T>::update_system.in_set(CoreSet::First));
|
.add_system(Events::<T>::update_system.in_base_set(CoreSet::First));
|
||||||
}
|
}
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,8 +29,8 @@ pub mod prelude {
|
|||||||
|
|
||||||
use bevy_ecs::{
|
use bevy_ecs::{
|
||||||
schedule_v3::{
|
schedule_v3::{
|
||||||
apply_system_buffers, IntoSystemConfig, IntoSystemSetConfig, Schedule, ScheduleLabel,
|
apply_system_buffers, IntoSystemConfig, IntoSystemSetConfig, IntoSystemSetConfigs,
|
||||||
SystemSet,
|
Schedule, ScheduleLabel, SystemSet,
|
||||||
},
|
},
|
||||||
system::Local,
|
system::Local,
|
||||||
world::World,
|
world::World,
|
||||||
@ -90,6 +90,7 @@ impl CoreSchedule {
|
|||||||
/// that runs immediately after the matching system set.
|
/// that runs immediately after the matching system set.
|
||||||
/// These can be useful for ordering, but you almost never want to add your systems to these sets.
|
/// These can be useful for ordering, but you almost never want to add your systems to these sets.
|
||||||
#[derive(Debug, Hash, PartialEq, Eq, Clone, SystemSet)]
|
#[derive(Debug, Hash, PartialEq, Eq, Clone, SystemSet)]
|
||||||
|
#[system_set(base)]
|
||||||
pub enum CoreSet {
|
pub enum CoreSet {
|
||||||
/// Runs before all other members of this set.
|
/// Runs before all other members of this set.
|
||||||
First,
|
First,
|
||||||
@ -129,20 +130,30 @@ impl CoreSet {
|
|||||||
let mut schedule = Schedule::new();
|
let mut schedule = Schedule::new();
|
||||||
|
|
||||||
// Create "stage-like" structure using buffer flushes + ordering
|
// Create "stage-like" structure using buffer flushes + ordering
|
||||||
schedule.add_system(apply_system_buffers.in_set(FirstFlush));
|
schedule
|
||||||
schedule.add_system(apply_system_buffers.in_set(PreUpdateFlush));
|
.set_default_base_set(Update)
|
||||||
schedule.add_system(apply_system_buffers.in_set(UpdateFlush));
|
.add_system(apply_system_buffers.in_base_set(FirstFlush))
|
||||||
schedule.add_system(apply_system_buffers.in_set(PostUpdateFlush));
|
.add_system(apply_system_buffers.in_base_set(PreUpdateFlush))
|
||||||
schedule.add_system(apply_system_buffers.in_set(LastFlush));
|
.add_system(apply_system_buffers.in_base_set(UpdateFlush))
|
||||||
|
.add_system(apply_system_buffers.in_base_set(PostUpdateFlush))
|
||||||
schedule.configure_set(First.before(FirstFlush));
|
.add_system(apply_system_buffers.in_base_set(LastFlush))
|
||||||
schedule.configure_set(PreUpdate.after(FirstFlush).before(PreUpdateFlush));
|
.configure_sets(
|
||||||
schedule.configure_set(StateTransitions.after(PreUpdateFlush).before(FixedUpdate));
|
(
|
||||||
schedule.configure_set(FixedUpdate.after(StateTransitions).before(Update));
|
First,
|
||||||
schedule.configure_set(Update.after(FixedUpdate).before(UpdateFlush));
|
FirstFlush,
|
||||||
schedule.configure_set(PostUpdate.after(UpdateFlush).before(PostUpdateFlush));
|
PreUpdate,
|
||||||
schedule.configure_set(Last.after(PostUpdateFlush).before(LastFlush));
|
PreUpdateFlush,
|
||||||
|
StateTransitions,
|
||||||
|
FixedUpdate,
|
||||||
|
Update,
|
||||||
|
UpdateFlush,
|
||||||
|
PostUpdate,
|
||||||
|
PostUpdateFlush,
|
||||||
|
Last,
|
||||||
|
LastFlush,
|
||||||
|
)
|
||||||
|
.chain(),
|
||||||
|
);
|
||||||
schedule
|
schedule
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -644,7 +644,7 @@ pub fn free_unused_assets_system(asset_server: Res<AssetServer>) {
|
|||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::{loader::LoadedAsset, update_asset_storage_system};
|
use crate::{loader::LoadedAsset, update_asset_storage_system};
|
||||||
use bevy_app::{App, CoreSet};
|
use bevy_app::App;
|
||||||
use bevy_ecs::prelude::*;
|
use bevy_ecs::prelude::*;
|
||||||
use bevy_reflect::TypeUuid;
|
use bevy_reflect::TypeUuid;
|
||||||
use bevy_utils::BoxedFuture;
|
use bevy_utils::BoxedFuture;
|
||||||
@ -852,16 +852,8 @@ mod test {
|
|||||||
let mut app = App::new();
|
let mut app = App::new();
|
||||||
app.insert_resource(assets);
|
app.insert_resource(assets);
|
||||||
app.insert_resource(asset_server);
|
app.insert_resource(asset_server);
|
||||||
app.add_system(
|
app.add_system(free_unused_assets_system.in_set(FreeUnusedAssets));
|
||||||
free_unused_assets_system
|
app.add_system(update_asset_storage_system::<PngAsset>.after(FreeUnusedAssets));
|
||||||
.in_set(FreeUnusedAssets)
|
|
||||||
.in_set(CoreSet::Update),
|
|
||||||
);
|
|
||||||
app.add_system(
|
|
||||||
update_asset_storage_system::<PngAsset>
|
|
||||||
.after(FreeUnusedAssets)
|
|
||||||
.in_set(CoreSet::Update),
|
|
||||||
);
|
|
||||||
|
|
||||||
fn load_asset(path: AssetPath, world: &World) -> HandleUntyped {
|
fn load_asset(path: AssetPath, world: &World) -> HandleUntyped {
|
||||||
let asset_server = world.resource::<AssetServer>();
|
let asset_server = world.resource::<AssetServer>();
|
||||||
|
|||||||
@ -331,8 +331,8 @@ impl AddAsset for App {
|
|||||||
};
|
};
|
||||||
|
|
||||||
self.insert_resource(assets)
|
self.insert_resource(assets)
|
||||||
.add_system(Assets::<T>::asset_event_system.in_set(AssetSet::AssetEvents))
|
.add_system(Assets::<T>::asset_event_system.in_base_set(AssetSet::AssetEvents))
|
||||||
.add_system(update_asset_storage_system::<T>.in_set(AssetSet::LoadAssets))
|
.add_system(update_asset_storage_system::<T>.in_base_set(AssetSet::LoadAssets))
|
||||||
.register_type::<Handle<T>>()
|
.register_type::<Handle<T>>()
|
||||||
.add_event::<AssetEvent<T>>()
|
.add_event::<AssetEvent<T>>()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
//!
|
//!
|
||||||
//! Internal assets (e.g. shaders) are bundled directly into an application and can't be hot
|
//! Internal assets (e.g. shaders) are bundled directly into an application and can't be hot
|
||||||
//! reloaded using the conventional API.
|
//! reloaded using the conventional API.
|
||||||
use bevy_app::{App, CoreSet, Plugin};
|
use bevy_app::{App, Plugin};
|
||||||
use bevy_ecs::{prelude::*, system::SystemState};
|
use bevy_ecs::{prelude::*, system::SystemState};
|
||||||
use bevy_tasks::{IoTaskPool, TaskPoolBuilder};
|
use bevy_tasks::{IoTaskPool, TaskPoolBuilder};
|
||||||
use bevy_utils::HashMap;
|
use bevy_utils::HashMap;
|
||||||
@ -75,7 +75,7 @@ impl Plugin for DebugAssetServerPlugin {
|
|||||||
watch_for_changes: true,
|
watch_for_changes: true,
|
||||||
});
|
});
|
||||||
app.insert_non_send_resource(DebugAssetApp(debug_asset_app));
|
app.insert_non_send_resource(DebugAssetApp(debug_asset_app));
|
||||||
app.add_system(run_debug_asset_app.in_set(CoreSet::Update));
|
app.add_system(run_debug_asset_app);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -19,7 +19,7 @@ impl<T: Asset> Default for AssetCountDiagnosticsPlugin<T> {
|
|||||||
impl<T: Asset> Plugin for AssetCountDiagnosticsPlugin<T> {
|
impl<T: Asset> Plugin for AssetCountDiagnosticsPlugin<T> {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
app.add_startup_system(Self::setup_system.in_set(StartupSet::Startup))
|
app.add_startup_system(Self::setup_system.in_set(StartupSet::Startup))
|
||||||
.add_system(Self::diagnostic_system.in_set(CoreSet::Update));
|
.add_system(Self::diagnostic_system);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -51,6 +51,7 @@ use bevy_ecs::prelude::*;
|
|||||||
|
|
||||||
/// [`SystemSet`]s for asset loading in an [`App`] schedule.
|
/// [`SystemSet`]s for asset loading in an [`App`] schedule.
|
||||||
#[derive(Debug, Hash, PartialEq, Eq, Clone, SystemSet)]
|
#[derive(Debug, Hash, PartialEq, Eq, Clone, SystemSet)]
|
||||||
|
#[system_set(base)]
|
||||||
pub enum AssetSet {
|
pub enum AssetSet {
|
||||||
/// Asset storages are updated.
|
/// Asset storages are updated.
|
||||||
LoadAssets,
|
LoadAssets,
|
||||||
@ -109,22 +110,20 @@ impl Plugin for AssetPlugin {
|
|||||||
|
|
||||||
app.configure_set(
|
app.configure_set(
|
||||||
AssetSet::LoadAssets
|
AssetSet::LoadAssets
|
||||||
.no_default_set()
|
|
||||||
.before(CoreSet::PreUpdate)
|
.before(CoreSet::PreUpdate)
|
||||||
.after(CoreSet::First),
|
.after(CoreSet::First),
|
||||||
)
|
)
|
||||||
.configure_set(
|
.configure_set(
|
||||||
AssetSet::AssetEvents
|
AssetSet::AssetEvents
|
||||||
.no_default_set()
|
|
||||||
.after(CoreSet::PostUpdate)
|
.after(CoreSet::PostUpdate)
|
||||||
.before(CoreSet::Last),
|
.before(CoreSet::Last),
|
||||||
)
|
)
|
||||||
.add_system(asset_server::free_unused_assets_system.in_set(CoreSet::PreUpdate));
|
.add_system(asset_server::free_unused_assets_system.in_base_set(CoreSet::PreUpdate));
|
||||||
|
|
||||||
#[cfg(all(
|
#[cfg(all(
|
||||||
feature = "filesystem_watcher",
|
feature = "filesystem_watcher",
|
||||||
all(not(target_arch = "wasm32"), not(target_os = "android"))
|
all(not(target_arch = "wasm32"), not(target_os = "android"))
|
||||||
))]
|
))]
|
||||||
app.add_system(io::filesystem_watcher_system.in_set(AssetSet::LoadAssets));
|
app.add_system(io::filesystem_watcher_system.in_base_set(AssetSet::LoadAssets));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -56,7 +56,7 @@ impl Plugin for AudioPlugin {
|
|||||||
.add_asset::<AudioSource>()
|
.add_asset::<AudioSource>()
|
||||||
.add_asset::<AudioSink>()
|
.add_asset::<AudioSink>()
|
||||||
.init_resource::<Audio<AudioSource>>()
|
.init_resource::<Audio<AudioSource>>()
|
||||||
.add_system(play_queued_audio_system::<AudioSource>.in_set(CoreSet::PostUpdate));
|
.add_system(play_queued_audio_system::<AudioSource>.in_base_set(CoreSet::PostUpdate));
|
||||||
|
|
||||||
#[cfg(any(feature = "mp3", feature = "flac", feature = "wav", feature = "vorbis"))]
|
#[cfg(any(feature = "mp3", feature = "flac", feature = "wav", feature = "vorbis"))]
|
||||||
app.init_asset_loader::<AudioLoader>();
|
app.init_asset_loader::<AudioLoader>();
|
||||||
@ -71,6 +71,6 @@ impl AddAudioSource for App {
|
|||||||
self.add_asset::<T>()
|
self.add_asset::<T>()
|
||||||
.init_resource::<Audio<T>>()
|
.init_resource::<Audio<T>>()
|
||||||
.init_resource::<AudioOutput<T>>()
|
.init_resource::<AudioOutput<T>>()
|
||||||
.add_system(play_queued_audio_system::<T>.in_set(CoreSet::PostUpdate))
|
.add_system(play_queued_audio_system::<T>.in_base_set(CoreSet::PostUpdate))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -107,7 +107,7 @@ impl Plugin for TaskPoolPlugin {
|
|||||||
self.task_pool_options.create_default_pools();
|
self.task_pool_options.create_default_pools();
|
||||||
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
app.add_system(tick_global_task_pools.in_set(bevy_app::CoreSet::Last));
|
app.add_system(tick_global_task_pools.in_base_set(bevy_app::CoreSet::Last));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// A dummy type that is [`!Send`](Send), to force systems to run on the main thread.
|
/// A dummy type that is [`!Send`](Send), to force systems to run on the main thread.
|
||||||
@ -142,7 +142,7 @@ pub struct FrameCountPlugin;
|
|||||||
impl Plugin for FrameCountPlugin {
|
impl Plugin for FrameCountPlugin {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
app.init_resource::<FrameCount>();
|
app.init_resource::<FrameCount>();
|
||||||
app.add_system(update_frame_count.in_set(CoreSet::Last));
|
app.add_system(update_frame_count.in_base_set(CoreSet::Last));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,7 @@ pub struct EntityCountDiagnosticsPlugin;
|
|||||||
impl Plugin for EntityCountDiagnosticsPlugin {
|
impl Plugin for EntityCountDiagnosticsPlugin {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
app.add_startup_system(Self::setup_system.in_set(StartupSet::Startup))
|
app.add_startup_system(Self::setup_system.in_set(StartupSet::Startup))
|
||||||
.add_system(Self::diagnostic_system.in_set(CoreSet::Update));
|
.add_system(Self::diagnostic_system);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -11,7 +11,7 @@ pub struct FrameTimeDiagnosticsPlugin;
|
|||||||
impl Plugin for FrameTimeDiagnosticsPlugin {
|
impl Plugin for FrameTimeDiagnosticsPlugin {
|
||||||
fn build(&self, app: &mut bevy_app::App) {
|
fn build(&self, app: &mut bevy_app::App) {
|
||||||
app.add_startup_system(Self::setup_system.in_set(StartupSet::Startup))
|
app.add_startup_system(Self::setup_system.in_set(StartupSet::Startup))
|
||||||
.add_system(Self::diagnostic_system.in_set(CoreSet::Update));
|
.add_system(Self::diagnostic_system);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -37,9 +37,9 @@ impl Plugin for LogDiagnosticsPlugin {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if self.debug {
|
if self.debug {
|
||||||
app.add_system(Self::log_diagnostics_debug_system.in_set(CoreSet::PostUpdate));
|
app.add_system(Self::log_diagnostics_debug_system.in_base_set(CoreSet::PostUpdate));
|
||||||
} else {
|
} else {
|
||||||
app.add_system(Self::log_diagnostics_system.in_set(CoreSet::PostUpdate));
|
app.add_system(Self::log_diagnostics_system.in_base_set(CoreSet::PostUpdate));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,7 +16,7 @@ pub struct SystemInformationDiagnosticsPlugin;
|
|||||||
impl Plugin for SystemInformationDiagnosticsPlugin {
|
impl Plugin for SystemInformationDiagnosticsPlugin {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
app.add_startup_system(internal::setup_system.in_set(StartupSet::Startup))
|
app.add_startup_system(internal::setup_system.in_set(StartupSet::Startup))
|
||||||
.add_system(internal::diagnostic_system.in_set(CoreSet::Update));
|
.add_system(internal::diagnostic_system);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,9 +2,10 @@ extern crate proc_macro;
|
|||||||
|
|
||||||
mod component;
|
mod component;
|
||||||
mod fetch;
|
mod fetch;
|
||||||
|
mod set;
|
||||||
|
|
||||||
use crate::fetch::derive_world_query_impl;
|
use crate::{fetch::derive_world_query_impl, set::derive_set};
|
||||||
use bevy_macro_utils::{derive_boxed_label, derive_set, get_named_struct_fields, BevyManifest};
|
use bevy_macro_utils::{derive_boxed_label, get_named_struct_fields, BevyManifest};
|
||||||
use proc_macro::TokenStream;
|
use proc_macro::TokenStream;
|
||||||
use proc_macro2::Span;
|
use proc_macro2::Span;
|
||||||
use quote::{format_ident, quote};
|
use quote::{format_ident, quote};
|
||||||
@ -537,7 +538,7 @@ pub fn derive_schedule_label(input: TokenStream) -> TokenStream {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Derive macro generating an impl of the trait `SystemSet`.
|
/// Derive macro generating an impl of the trait `SystemSet`.
|
||||||
#[proc_macro_derive(SystemSet)]
|
#[proc_macro_derive(SystemSet, attributes(system_set))]
|
||||||
pub fn derive_system_set(input: TokenStream) -> TokenStream {
|
pub fn derive_system_set(input: TokenStream) -> TokenStream {
|
||||||
let input = parse_macro_input!(input as DeriveInput);
|
let input = parse_macro_input!(input as DeriveInput);
|
||||||
let mut trait_path = bevy_ecs_path();
|
let mut trait_path = bevy_ecs_path();
|
||||||
|
|||||||
84
crates/bevy_ecs/macros/src/set.rs
Normal file
84
crates/bevy_ecs/macros/src/set.rs
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
use proc_macro::TokenStream;
|
||||||
|
use quote::{quote, ToTokens};
|
||||||
|
use syn::parse::{Parse, ParseStream};
|
||||||
|
|
||||||
|
pub static SYSTEM_SET_ATTRIBUTE_NAME: &str = "system_set";
|
||||||
|
pub static BASE_ATTRIBUTE_NAME: &str = "base";
|
||||||
|
|
||||||
|
/// Derive a label trait
|
||||||
|
///
|
||||||
|
/// # Args
|
||||||
|
///
|
||||||
|
/// - `input`: The [`syn::DeriveInput`] for struct that is deriving the label trait
|
||||||
|
/// - `trait_path`: The path [`syn::Path`] to the label trait
|
||||||
|
pub fn derive_set(input: syn::DeriveInput, trait_path: &syn::Path) -> TokenStream {
|
||||||
|
let ident = input.ident;
|
||||||
|
|
||||||
|
let mut is_base = false;
|
||||||
|
for attr in &input.attrs {
|
||||||
|
if !attr
|
||||||
|
.path
|
||||||
|
.get_ident()
|
||||||
|
.map_or(false, |ident| ident == SYSTEM_SET_ATTRIBUTE_NAME)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
attr.parse_args_with(|input: ParseStream| {
|
||||||
|
let meta = input.parse_terminated::<syn::Meta, syn::token::Comma>(syn::Meta::parse)?;
|
||||||
|
for meta in meta {
|
||||||
|
let ident = meta.path().get_ident().unwrap_or_else(|| {
|
||||||
|
panic!(
|
||||||
|
"Unrecognized attribute: `{}`",
|
||||||
|
meta.path().to_token_stream()
|
||||||
|
)
|
||||||
|
});
|
||||||
|
if ident == BASE_ATTRIBUTE_NAME {
|
||||||
|
if let syn::Meta::Path(_) = meta {
|
||||||
|
is_base = true;
|
||||||
|
} else {
|
||||||
|
panic!(
|
||||||
|
"The `{BASE_ATTRIBUTE_NAME}` attribute is expected to have no value or arguments",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
panic!(
|
||||||
|
"Unrecognized attribute: `{}`",
|
||||||
|
meta.path().to_token_stream()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
})
|
||||||
|
.unwrap_or_else(|_| panic!("Invalid `{SYSTEM_SET_ATTRIBUTE_NAME}` attribute format"));
|
||||||
|
}
|
||||||
|
|
||||||
|
let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
|
||||||
|
let mut where_clause = where_clause.cloned().unwrap_or_else(|| syn::WhereClause {
|
||||||
|
where_token: Default::default(),
|
||||||
|
predicates: Default::default(),
|
||||||
|
});
|
||||||
|
where_clause.predicates.push(
|
||||||
|
syn::parse2(quote! {
|
||||||
|
Self: 'static + Send + Sync + Clone + Eq + ::std::fmt::Debug + ::std::hash::Hash
|
||||||
|
})
|
||||||
|
.unwrap(),
|
||||||
|
);
|
||||||
|
|
||||||
|
(quote! {
|
||||||
|
impl #impl_generics #trait_path for #ident #ty_generics #where_clause {
|
||||||
|
fn is_system_type(&self) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_base(&self) -> bool {
|
||||||
|
#is_base
|
||||||
|
}
|
||||||
|
|
||||||
|
fn dyn_clone(&self) -> std::boxed::Box<dyn #trait_path> {
|
||||||
|
std::boxed::Box::new(std::clone::Clone::clone(self))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.into()
|
||||||
|
}
|
||||||
@ -28,7 +28,7 @@ impl SystemSetConfig {
|
|||||||
|
|
||||||
Self {
|
Self {
|
||||||
set,
|
set,
|
||||||
graph_info: GraphInfo::default(),
|
graph_info: GraphInfo::system_set(),
|
||||||
conditions: Vec::new(),
|
conditions: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -45,12 +45,11 @@ impl SystemConfig {
|
|||||||
fn new(system: BoxedSystem) -> Self {
|
fn new(system: BoxedSystem) -> Self {
|
||||||
// include system in its default sets
|
// include system in its default sets
|
||||||
let sets = system.default_system_sets().into_iter().collect();
|
let sets = system.default_system_sets().into_iter().collect();
|
||||||
|
let mut graph_info = GraphInfo::system();
|
||||||
|
graph_info.sets = sets;
|
||||||
Self {
|
Self {
|
||||||
system,
|
system,
|
||||||
graph_info: GraphInfo {
|
graph_info,
|
||||||
sets,
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
conditions: Vec::new(),
|
conditions: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -87,9 +86,13 @@ pub trait IntoSystemSetConfig: sealed::IntoSystemSetConfig {
|
|||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
fn into_config(self) -> SystemSetConfig;
|
fn into_config(self) -> SystemSetConfig;
|
||||||
/// Add to the provided `set`.
|
/// Add to the provided `set`.
|
||||||
|
#[track_caller]
|
||||||
fn in_set(self, set: impl SystemSet) -> SystemSetConfig;
|
fn in_set(self, set: impl SystemSet) -> SystemSetConfig;
|
||||||
/// Don't add this set to the schedules's default set.
|
/// Add to the provided "base" `set`. For more information on base sets, see [`SystemSet::is_base`].
|
||||||
fn no_default_set(self) -> SystemSetConfig;
|
#[track_caller]
|
||||||
|
fn in_base_set(self, set: impl SystemSet) -> SystemSetConfig;
|
||||||
|
/// Add this set to the schedules's default base set.
|
||||||
|
fn in_default_base_set(self) -> SystemSetConfig;
|
||||||
/// Run before all systems in `set`.
|
/// Run before all systems in `set`.
|
||||||
fn before<M>(self, set: impl IntoSystemSet<M>) -> SystemSetConfig;
|
fn before<M>(self, set: impl IntoSystemSet<M>) -> SystemSetConfig;
|
||||||
/// Run after all systems in `set`.
|
/// Run after all systems in `set`.
|
||||||
@ -117,12 +120,18 @@ where
|
|||||||
SystemSetConfig::new(Box::new(self))
|
SystemSetConfig::new(Box::new(self))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
fn in_set(self, set: impl SystemSet) -> SystemSetConfig {
|
fn in_set(self, set: impl SystemSet) -> SystemSetConfig {
|
||||||
self.into_config().in_set(set)
|
self.into_config().in_set(set)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn no_default_set(self) -> SystemSetConfig {
|
#[track_caller]
|
||||||
self.into_config().no_default_set()
|
fn in_base_set(self, set: impl SystemSet) -> SystemSetConfig {
|
||||||
|
self.into_config().in_base_set(set)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn in_default_base_set(self) -> SystemSetConfig {
|
||||||
|
self.into_config().in_default_base_set()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn before<M>(self, set: impl IntoSystemSet<M>) -> SystemSetConfig {
|
fn before<M>(self, set: impl IntoSystemSet<M>) -> SystemSetConfig {
|
||||||
@ -155,12 +164,18 @@ impl IntoSystemSetConfig for BoxedSystemSet {
|
|||||||
SystemSetConfig::new(self)
|
SystemSetConfig::new(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
fn in_set(self, set: impl SystemSet) -> SystemSetConfig {
|
fn in_set(self, set: impl SystemSet) -> SystemSetConfig {
|
||||||
self.into_config().in_set(set)
|
self.into_config().in_set(set)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn no_default_set(self) -> SystemSetConfig {
|
#[track_caller]
|
||||||
self.into_config().no_default_set()
|
fn in_base_set(self, set: impl SystemSet) -> SystemSetConfig {
|
||||||
|
self.into_config().in_base_set(set)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn in_default_base_set(self) -> SystemSetConfig {
|
||||||
|
self.into_config().in_default_base_set()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn before<M>(self, set: impl IntoSystemSet<M>) -> SystemSetConfig {
|
fn before<M>(self, set: impl IntoSystemSet<M>) -> SystemSetConfig {
|
||||||
@ -193,17 +208,44 @@ impl IntoSystemSetConfig for SystemSetConfig {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
fn in_set(mut self, set: impl SystemSet) -> Self {
|
fn in_set(mut self, set: impl SystemSet) -> Self {
|
||||||
assert!(
|
assert!(
|
||||||
!set.is_system_type(),
|
!set.is_system_type(),
|
||||||
"adding arbitrary systems to a system type set is not allowed"
|
"adding arbitrary systems to a system type set is not allowed"
|
||||||
);
|
);
|
||||||
|
assert!(
|
||||||
|
!set.is_base(),
|
||||||
|
"Sets cannot be added to 'base' system sets using 'in_set'. Use 'in_base_set' instead."
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
!self.set.is_base(),
|
||||||
|
"Base system sets cannot be added to other sets."
|
||||||
|
);
|
||||||
self.graph_info.sets.push(Box::new(set));
|
self.graph_info.sets.push(Box::new(set));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn no_default_set(mut self) -> SystemSetConfig {
|
#[track_caller]
|
||||||
self.graph_info.add_default_set = false;
|
fn in_base_set(mut self, set: impl SystemSet) -> Self {
|
||||||
|
assert!(
|
||||||
|
!set.is_system_type(),
|
||||||
|
"System type sets cannot be base sets."
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
set.is_base(),
|
||||||
|
"Sets cannot be added to normal sets using 'in_base_set'. Use 'in_set' instead."
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
!self.set.is_base(),
|
||||||
|
"Base system sets cannot be added to other sets."
|
||||||
|
);
|
||||||
|
self.graph_info.set_base_set(Box::new(set));
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn in_default_base_set(mut self) -> SystemSetConfig {
|
||||||
|
self.graph_info.add_default_base_set = true;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -252,9 +294,13 @@ pub trait IntoSystemConfig<Params>: sealed::IntoSystemConfig<Params> {
|
|||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
fn into_config(self) -> SystemConfig;
|
fn into_config(self) -> SystemConfig;
|
||||||
/// Add to `set` membership.
|
/// Add to `set` membership.
|
||||||
|
#[track_caller]
|
||||||
fn in_set(self, set: impl SystemSet) -> SystemConfig;
|
fn in_set(self, set: impl SystemSet) -> SystemConfig;
|
||||||
|
/// Add to the provided "base" `set`. For more information on base sets, see [`SystemSet::is_base`].
|
||||||
|
#[track_caller]
|
||||||
|
fn in_base_set(self, set: impl SystemSet) -> SystemConfig;
|
||||||
/// Don't add this system to the schedules's default set.
|
/// Don't add this system to the schedules's default set.
|
||||||
fn no_default_set(self) -> SystemConfig;
|
fn no_default_base_set(self) -> SystemConfig;
|
||||||
/// Run before all systems in `set`.
|
/// Run before all systems in `set`.
|
||||||
fn before<M>(self, set: impl IntoSystemSet<M>) -> SystemConfig;
|
fn before<M>(self, set: impl IntoSystemSet<M>) -> SystemConfig;
|
||||||
/// Run after all systems in `set`.
|
/// Run after all systems in `set`.
|
||||||
@ -282,12 +328,18 @@ where
|
|||||||
SystemConfig::new(Box::new(IntoSystem::into_system(self)))
|
SystemConfig::new(Box::new(IntoSystem::into_system(self)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
fn in_set(self, set: impl SystemSet) -> SystemConfig {
|
fn in_set(self, set: impl SystemSet) -> SystemConfig {
|
||||||
self.into_config().in_set(set)
|
self.into_config().in_set(set)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn no_default_set(self) -> SystemConfig {
|
#[track_caller]
|
||||||
self.into_config().no_default_set()
|
fn in_base_set(self, set: impl SystemSet) -> SystemConfig {
|
||||||
|
self.into_config().in_base_set(set)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn no_default_base_set(self) -> SystemConfig {
|
||||||
|
self.into_config().no_default_base_set()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn before<M>(self, set: impl IntoSystemSet<M>) -> SystemConfig {
|
fn before<M>(self, set: impl IntoSystemSet<M>) -> SystemConfig {
|
||||||
@ -320,12 +372,18 @@ impl IntoSystemConfig<()> for BoxedSystem<(), ()> {
|
|||||||
SystemConfig::new(self)
|
SystemConfig::new(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
fn in_set(self, set: impl SystemSet) -> SystemConfig {
|
fn in_set(self, set: impl SystemSet) -> SystemConfig {
|
||||||
self.into_config().in_set(set)
|
self.into_config().in_set(set)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn no_default_set(self) -> SystemConfig {
|
#[track_caller]
|
||||||
self.into_config().no_default_set()
|
fn in_base_set(self, set: impl SystemSet) -> SystemConfig {
|
||||||
|
self.into_config().in_base_set(set)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn no_default_base_set(self) -> SystemConfig {
|
||||||
|
self.into_config().no_default_base_set()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn before<M>(self, set: impl IntoSystemSet<M>) -> SystemConfig {
|
fn before<M>(self, set: impl IntoSystemSet<M>) -> SystemConfig {
|
||||||
@ -358,17 +416,36 @@ impl IntoSystemConfig<()> for SystemConfig {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
fn in_set(mut self, set: impl SystemSet) -> Self {
|
fn in_set(mut self, set: impl SystemSet) -> Self {
|
||||||
assert!(
|
assert!(
|
||||||
!set.is_system_type(),
|
!set.is_system_type(),
|
||||||
"adding arbitrary systems to a system type set is not allowed"
|
"adding arbitrary systems to a system type set is not allowed"
|
||||||
);
|
);
|
||||||
|
assert!(
|
||||||
|
!set.is_base(),
|
||||||
|
"Systems cannot be added to 'base' system sets using 'in_set'. Use 'in_base_set' instead."
|
||||||
|
);
|
||||||
self.graph_info.sets.push(Box::new(set));
|
self.graph_info.sets.push(Box::new(set));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
fn no_default_set(mut self) -> SystemConfig {
|
#[track_caller]
|
||||||
self.graph_info.add_default_set = false;
|
fn in_base_set(mut self, set: impl SystemSet) -> Self {
|
||||||
|
assert!(
|
||||||
|
!set.is_system_type(),
|
||||||
|
"System type sets cannot be base sets."
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
set.is_base(),
|
||||||
|
"Systems cannot be added to normal sets using 'in_base_set'. Use 'in_set' instead."
|
||||||
|
);
|
||||||
|
self.graph_info.set_base_set(Box::new(set));
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn no_default_base_set(mut self) -> SystemConfig {
|
||||||
|
self.graph_info.add_default_base_set = false;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -451,10 +528,17 @@ where
|
|||||||
fn into_configs(self) -> SystemConfigs;
|
fn into_configs(self) -> SystemConfigs;
|
||||||
|
|
||||||
/// Add these systems to the provided `set`.
|
/// Add these systems to the provided `set`.
|
||||||
|
#[track_caller]
|
||||||
fn in_set(self, set: impl SystemSet) -> SystemConfigs {
|
fn in_set(self, set: impl SystemSet) -> SystemConfigs {
|
||||||
self.into_configs().in_set(set)
|
self.into_configs().in_set(set)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Add these systems to the provided "base" `set`. For more information on base sets, see [`SystemSet::is_base`].
|
||||||
|
#[track_caller]
|
||||||
|
fn in_base_set(self, set: impl SystemSet) -> SystemConfigs {
|
||||||
|
self.into_configs().in_base_set(set)
|
||||||
|
}
|
||||||
|
|
||||||
/// Run before all systems in `set`.
|
/// Run before all systems in `set`.
|
||||||
fn before<M>(self, set: impl IntoSystemSet<M>) -> SystemConfigs {
|
fn before<M>(self, set: impl IntoSystemSet<M>) -> SystemConfigs {
|
||||||
self.into_configs().before(set)
|
self.into_configs().before(set)
|
||||||
@ -495,11 +579,16 @@ impl IntoSystemConfigs<()> for SystemConfigs {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
fn in_set(mut self, set: impl SystemSet) -> Self {
|
fn in_set(mut self, set: impl SystemSet) -> Self {
|
||||||
assert!(
|
assert!(
|
||||||
!set.is_system_type(),
|
!set.is_system_type(),
|
||||||
"adding arbitrary systems to a system type set is not allowed"
|
"adding arbitrary systems to a system type set is not allowed"
|
||||||
);
|
);
|
||||||
|
assert!(
|
||||||
|
!set.is_base(),
|
||||||
|
"Systems cannot be added to 'base' system sets using 'in_set'. Use 'in_base_set' instead."
|
||||||
|
);
|
||||||
for config in &mut self.systems {
|
for config in &mut self.systems {
|
||||||
config.graph_info.sets.push(set.dyn_clone());
|
config.graph_info.sets.push(set.dyn_clone());
|
||||||
}
|
}
|
||||||
@ -507,6 +596,23 @@ impl IntoSystemConfigs<()> for SystemConfigs {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
|
fn in_base_set(mut self, set: impl SystemSet) -> Self {
|
||||||
|
assert!(
|
||||||
|
!set.is_system_type(),
|
||||||
|
"System type sets cannot be base sets."
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
set.is_base(),
|
||||||
|
"Systems cannot be added to normal sets using 'in_base_set'. Use 'in_set' instead."
|
||||||
|
);
|
||||||
|
for config in &mut self.systems {
|
||||||
|
config.graph_info.set_base_set(set.dyn_clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
fn before<M>(mut self, set: impl IntoSystemSet<M>) -> Self {
|
fn before<M>(mut self, set: impl IntoSystemSet<M>) -> Self {
|
||||||
let set = set.into_system_set();
|
let set = set.into_system_set();
|
||||||
for config in &mut self.systems {
|
for config in &mut self.systems {
|
||||||
@ -575,10 +681,17 @@ where
|
|||||||
fn into_configs(self) -> SystemSetConfigs;
|
fn into_configs(self) -> SystemSetConfigs;
|
||||||
|
|
||||||
/// Add these system sets to the provided `set`.
|
/// Add these system sets to the provided `set`.
|
||||||
|
#[track_caller]
|
||||||
fn in_set(self, set: impl SystemSet) -> SystemSetConfigs {
|
fn in_set(self, set: impl SystemSet) -> SystemSetConfigs {
|
||||||
self.into_configs().in_set(set)
|
self.into_configs().in_set(set)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Add these system sets to the provided "base" `set`. For more information on base sets, see [`SystemSet::is_base`].
|
||||||
|
#[track_caller]
|
||||||
|
fn in_base_set(self, set: impl SystemSet) -> SystemSetConfigs {
|
||||||
|
self.into_configs().in_base_set(set)
|
||||||
|
}
|
||||||
|
|
||||||
/// Run before all systems in `set`.
|
/// Run before all systems in `set`.
|
||||||
fn before<M>(self, set: impl IntoSystemSet<M>) -> SystemSetConfigs {
|
fn before<M>(self, set: impl IntoSystemSet<M>) -> SystemSetConfigs {
|
||||||
self.into_configs().before(set)
|
self.into_configs().before(set)
|
||||||
@ -614,18 +727,48 @@ impl IntoSystemSetConfigs for SystemSetConfigs {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
fn in_set(mut self, set: impl SystemSet) -> Self {
|
fn in_set(mut self, set: impl SystemSet) -> Self {
|
||||||
assert!(
|
assert!(
|
||||||
!set.is_system_type(),
|
!set.is_system_type(),
|
||||||
"adding arbitrary systems to a system type set is not allowed"
|
"adding arbitrary systems to a system type set is not allowed"
|
||||||
);
|
);
|
||||||
|
assert!(
|
||||||
|
!set.is_base(),
|
||||||
|
"Sets cannot be added to 'base' system sets using 'in_set'. Use 'in_base_set' instead."
|
||||||
|
);
|
||||||
for config in &mut self.sets {
|
for config in &mut self.sets {
|
||||||
|
assert!(
|
||||||
|
!config.set.is_base(),
|
||||||
|
"Base system sets cannot be added to other sets."
|
||||||
|
);
|
||||||
config.graph_info.sets.push(set.dyn_clone());
|
config.graph_info.sets.push(set.dyn_clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
|
fn in_base_set(mut self, set: impl SystemSet) -> Self {
|
||||||
|
assert!(
|
||||||
|
!set.is_system_type(),
|
||||||
|
"System type sets cannot be base sets."
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
set.is_base(),
|
||||||
|
"Sets cannot be added to normal sets using 'in_base_set'. Use 'in_set' instead."
|
||||||
|
);
|
||||||
|
for config in &mut self.sets {
|
||||||
|
assert!(
|
||||||
|
!config.set.is_base(),
|
||||||
|
"Base system sets cannot be added to other sets."
|
||||||
|
);
|
||||||
|
config.graph_info.set_base_set(set.dyn_clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
fn before<M>(mut self, set: impl IntoSystemSet<M>) -> Self {
|
fn before<M>(mut self, set: impl IntoSystemSet<M>) -> Self {
|
||||||
let set = set.into_system_set();
|
let set = set.into_system_set();
|
||||||
for config in &mut self.sets {
|
for config in &mut self.sets {
|
||||||
|
|||||||
@ -54,8 +54,8 @@ pub(super) struct SystemSchedule {
|
|||||||
pub(super) set_ids: Vec<NodeId>,
|
pub(super) set_ids: Vec<NodeId>,
|
||||||
pub(super) system_dependencies: Vec<usize>,
|
pub(super) system_dependencies: Vec<usize>,
|
||||||
pub(super) system_dependents: Vec<Vec<usize>>,
|
pub(super) system_dependents: Vec<Vec<usize>>,
|
||||||
pub(super) sets_of_systems: Vec<FixedBitSet>,
|
pub(super) sets_with_conditions_of_systems: Vec<FixedBitSet>,
|
||||||
pub(super) systems_in_sets: Vec<FixedBitSet>,
|
pub(super) systems_in_sets_with_conditions: Vec<FixedBitSet>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SystemSchedule {
|
impl SystemSchedule {
|
||||||
@ -68,8 +68,8 @@ impl SystemSchedule {
|
|||||||
set_ids: Vec::new(),
|
set_ids: Vec::new(),
|
||||||
system_dependencies: Vec::new(),
|
system_dependencies: Vec::new(),
|
||||||
system_dependents: Vec::new(),
|
system_dependents: Vec::new(),
|
||||||
sets_of_systems: Vec::new(),
|
sets_with_conditions_of_systems: Vec::new(),
|
||||||
systems_in_sets: Vec::new(),
|
systems_in_sets_with_conditions: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -32,8 +32,8 @@ struct SyncUnsafeSchedule<'a> {
|
|||||||
struct Conditions<'a> {
|
struct Conditions<'a> {
|
||||||
system_conditions: &'a mut [Vec<BoxedCondition>],
|
system_conditions: &'a mut [Vec<BoxedCondition>],
|
||||||
set_conditions: &'a mut [Vec<BoxedCondition>],
|
set_conditions: &'a mut [Vec<BoxedCondition>],
|
||||||
sets_of_systems: &'a [FixedBitSet],
|
sets_with_conditions_of_systems: &'a [FixedBitSet],
|
||||||
systems_in_sets: &'a [FixedBitSet],
|
systems_in_sets_with_conditions: &'a [FixedBitSet],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SyncUnsafeSchedule<'_> {
|
impl SyncUnsafeSchedule<'_> {
|
||||||
@ -43,8 +43,8 @@ impl SyncUnsafeSchedule<'_> {
|
|||||||
conditions: Conditions {
|
conditions: Conditions {
|
||||||
system_conditions: &mut schedule.system_conditions,
|
system_conditions: &mut schedule.system_conditions,
|
||||||
set_conditions: &mut schedule.set_conditions,
|
set_conditions: &mut schedule.set_conditions,
|
||||||
sets_of_systems: &schedule.sets_of_systems,
|
sets_with_conditions_of_systems: &schedule.sets_with_conditions_of_systems,
|
||||||
systems_in_sets: &schedule.systems_in_sets,
|
systems_in_sets_with_conditions: &schedule.systems_in_sets_with_conditions,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -333,7 +333,9 @@ impl MultiThreadedExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: an earlier out if world's archetypes did not change
|
// TODO: an earlier out if world's archetypes did not change
|
||||||
for set_idx in conditions.sets_of_systems[system_index].difference(&self.evaluated_sets) {
|
for set_idx in conditions.sets_with_conditions_of_systems[system_index]
|
||||||
|
.difference(&self.evaluated_sets)
|
||||||
|
{
|
||||||
for condition in &mut conditions.set_conditions[set_idx] {
|
for condition in &mut conditions.set_conditions[set_idx] {
|
||||||
condition.update_archetype_component_access(world);
|
condition.update_archetype_component_access(world);
|
||||||
if !condition
|
if !condition
|
||||||
@ -382,7 +384,7 @@ impl MultiThreadedExecutor {
|
|||||||
world: &World,
|
world: &World,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let mut should_run = !self.skipped_systems.contains(system_index);
|
let mut should_run = !self.skipped_systems.contains(system_index);
|
||||||
for set_idx in conditions.sets_of_systems[system_index].ones() {
|
for set_idx in conditions.sets_with_conditions_of_systems[system_index].ones() {
|
||||||
if self.evaluated_sets.contains(set_idx) {
|
if self.evaluated_sets.contains(set_idx) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -393,7 +395,7 @@ impl MultiThreadedExecutor {
|
|||||||
|
|
||||||
if !set_conditions_met {
|
if !set_conditions_met {
|
||||||
self.skipped_systems
|
self.skipped_systems
|
||||||
.union_with(&conditions.systems_in_sets[set_idx]);
|
.union_with(&conditions.systems_in_sets_with_conditions[set_idx]);
|
||||||
}
|
}
|
||||||
|
|
||||||
should_run &= set_conditions_met;
|
should_run &= set_conditions_met;
|
||||||
|
|||||||
@ -41,7 +41,7 @@ impl SystemExecutor for SimpleExecutor {
|
|||||||
let should_run_span = info_span!("check_conditions", name = &*name).entered();
|
let should_run_span = info_span!("check_conditions", name = &*name).entered();
|
||||||
|
|
||||||
let mut should_run = !self.completed_systems.contains(system_index);
|
let mut should_run = !self.completed_systems.contains(system_index);
|
||||||
for set_idx in schedule.sets_of_systems[system_index].ones() {
|
for set_idx in schedule.sets_with_conditions_of_systems[system_index].ones() {
|
||||||
if self.evaluated_sets.contains(set_idx) {
|
if self.evaluated_sets.contains(set_idx) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -52,7 +52,7 @@ impl SystemExecutor for SimpleExecutor {
|
|||||||
|
|
||||||
if !set_conditions_met {
|
if !set_conditions_met {
|
||||||
self.completed_systems
|
self.completed_systems
|
||||||
.union_with(&schedule.systems_in_sets[set_idx]);
|
.union_with(&schedule.systems_in_sets_with_conditions[set_idx]);
|
||||||
}
|
}
|
||||||
|
|
||||||
should_run &= set_conditions_met;
|
should_run &= set_conditions_met;
|
||||||
|
|||||||
@ -51,7 +51,7 @@ impl SystemExecutor for SingleThreadedExecutor {
|
|||||||
let should_run_span = info_span!("check_conditions", name = &*name).entered();
|
let should_run_span = info_span!("check_conditions", name = &*name).entered();
|
||||||
|
|
||||||
let mut should_run = !self.completed_systems.contains(system_index);
|
let mut should_run = !self.completed_systems.contains(system_index);
|
||||||
for set_idx in schedule.sets_of_systems[system_index].ones() {
|
for set_idx in schedule.sets_with_conditions_of_systems[system_index].ones() {
|
||||||
if self.evaluated_sets.contains(set_idx) {
|
if self.evaluated_sets.contains(set_idx) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -62,7 +62,7 @@ impl SystemExecutor for SingleThreadedExecutor {
|
|||||||
|
|
||||||
if !set_conditions_met {
|
if !set_conditions_met {
|
||||||
self.completed_systems
|
self.completed_systems
|
||||||
.union_with(&schedule.systems_in_sets[set_idx]);
|
.union_with(&schedule.systems_in_sets_with_conditions[set_idx]);
|
||||||
}
|
}
|
||||||
|
|
||||||
should_run &= set_conditions_met;
|
should_run &= set_conditions_met;
|
||||||
|
|||||||
@ -72,16 +72,47 @@ pub(crate) struct GraphInfo {
|
|||||||
pub(crate) sets: Vec<BoxedSystemSet>,
|
pub(crate) sets: Vec<BoxedSystemSet>,
|
||||||
pub(crate) dependencies: Vec<Dependency>,
|
pub(crate) dependencies: Vec<Dependency>,
|
||||||
pub(crate) ambiguous_with: Ambiguity,
|
pub(crate) ambiguous_with: Ambiguity,
|
||||||
pub(crate) add_default_set: bool,
|
pub(crate) add_default_base_set: bool,
|
||||||
|
pub(crate) base_set: Option<BoxedSystemSet>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for GraphInfo {
|
impl Default for GraphInfo {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
GraphInfo {
|
GraphInfo {
|
||||||
sets: Vec::new(),
|
sets: Vec::new(),
|
||||||
|
base_set: None,
|
||||||
dependencies: Vec::new(),
|
dependencies: Vec::new(),
|
||||||
ambiguous_with: Ambiguity::default(),
|
ambiguous_with: Ambiguity::default(),
|
||||||
add_default_set: true,
|
add_default_base_set: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GraphInfo {
|
||||||
|
pub(crate) fn system() -> GraphInfo {
|
||||||
|
GraphInfo {
|
||||||
|
// systems get the default base set automatically
|
||||||
|
add_default_base_set: true,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn system_set() -> GraphInfo {
|
||||||
|
GraphInfo {
|
||||||
|
// sets do not get the default base set automatically
|
||||||
|
add_default_base_set: false,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[track_caller]
|
||||||
|
pub(crate) fn set_base_set(&mut self, set: BoxedSystemSet) {
|
||||||
|
if let Some(current) = &self.base_set {
|
||||||
|
panic!(
|
||||||
|
"Cannot set the base set because base set {current:?} has already been configured."
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
self.base_set = Some(set);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -644,4 +644,173 @@ mod tests {
|
|||||||
assert!(matches!(result, Err(ScheduleBuildError::Ambiguity)));
|
assert!(matches!(result, Err(ScheduleBuildError::Ambiguity)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mod base_sets {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[derive(SystemSet, Hash, Debug, Eq, PartialEq, Clone)]
|
||||||
|
#[system_set(base)]
|
||||||
|
enum Base {
|
||||||
|
A,
|
||||||
|
B,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(SystemSet, Hash, Debug, Eq, PartialEq, Clone)]
|
||||||
|
enum Normal {
|
||||||
|
X,
|
||||||
|
Y,
|
||||||
|
Z,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic]
|
||||||
|
fn disallow_adding_base_sets_to_system_with_in_set() {
|
||||||
|
let mut schedule = Schedule::new();
|
||||||
|
schedule.add_system(named_system.in_set(Base::A));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic]
|
||||||
|
fn disallow_adding_sets_to_system_with_in_base_set() {
|
||||||
|
let mut schedule = Schedule::new();
|
||||||
|
schedule.add_system(named_system.in_base_set(Normal::X));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic]
|
||||||
|
fn disallow_adding_base_sets_to_systems_with_in_set() {
|
||||||
|
let mut schedule = Schedule::new();
|
||||||
|
schedule.add_systems((named_system, named_system).in_set(Base::A));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic]
|
||||||
|
fn disallow_adding_sets_to_systems_with_in_base_set() {
|
||||||
|
let mut schedule = Schedule::new();
|
||||||
|
schedule.add_systems((named_system, named_system).in_base_set(Normal::X));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic]
|
||||||
|
fn disallow_adding_base_sets_to_set_with_in_set() {
|
||||||
|
let mut schedule = Schedule::new();
|
||||||
|
schedule.configure_set(Normal::Y.in_set(Base::A));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic]
|
||||||
|
fn disallow_adding_sets_to_set_with_in_base_set() {
|
||||||
|
let mut schedule = Schedule::new();
|
||||||
|
schedule.configure_set(Normal::Y.in_base_set(Normal::X));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic]
|
||||||
|
fn disallow_adding_base_sets_to_sets_with_in_set() {
|
||||||
|
let mut schedule = Schedule::new();
|
||||||
|
schedule.configure_sets((Normal::X, Normal::Y).in_set(Base::A));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic]
|
||||||
|
fn disallow_adding_sets_to_sets_with_in_base_set() {
|
||||||
|
let mut schedule = Schedule::new();
|
||||||
|
schedule.configure_sets((Normal::X, Normal::Y).in_base_set(Normal::Z));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic]
|
||||||
|
fn disallow_adding_base_sets_to_sets() {
|
||||||
|
let mut schedule = Schedule::new();
|
||||||
|
schedule.configure_set(Base::A.in_set(Normal::X));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic]
|
||||||
|
fn disallow_adding_base_sets_to_base_sets() {
|
||||||
|
let mut schedule = Schedule::new();
|
||||||
|
schedule.configure_set(Base::A.in_base_set(Base::B));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic]
|
||||||
|
fn disallow_adding_set_to_multiple_base_sets() {
|
||||||
|
let mut schedule = Schedule::new();
|
||||||
|
schedule.configure_set(Normal::X.in_base_set(Base::A).in_base_set(Base::B));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic]
|
||||||
|
fn disallow_adding_sets_to_multiple_base_sets() {
|
||||||
|
let mut schedule = Schedule::new();
|
||||||
|
schedule.configure_sets(
|
||||||
|
(Normal::X, Normal::Y)
|
||||||
|
.in_base_set(Base::A)
|
||||||
|
.in_base_set(Base::B),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic]
|
||||||
|
fn disallow_adding_system_to_multiple_base_sets() {
|
||||||
|
let mut schedule = Schedule::new();
|
||||||
|
schedule.add_system(named_system.in_base_set(Base::A).in_base_set(Base::B));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[should_panic]
|
||||||
|
fn disallow_adding_systems_to_multiple_base_sets() {
|
||||||
|
let mut schedule = Schedule::new();
|
||||||
|
schedule.add_systems(
|
||||||
|
(make_function_system(0), make_function_system(1))
|
||||||
|
.in_base_set(Base::A)
|
||||||
|
.in_base_set(Base::B),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn disallow_multiple_base_sets() {
|
||||||
|
let mut world = World::new();
|
||||||
|
|
||||||
|
let mut schedule = Schedule::new();
|
||||||
|
schedule
|
||||||
|
.configure_set(Normal::X.in_base_set(Base::A))
|
||||||
|
.configure_set(Normal::Y.in_base_set(Base::B))
|
||||||
|
.add_system(named_system.in_set(Normal::X).in_set(Normal::Y));
|
||||||
|
|
||||||
|
let result = schedule.initialize(&mut world);
|
||||||
|
assert!(matches!(
|
||||||
|
result,
|
||||||
|
Err(ScheduleBuildError::SystemInMultipleBaseSets { .. })
|
||||||
|
));
|
||||||
|
|
||||||
|
let mut schedule = Schedule::new();
|
||||||
|
schedule
|
||||||
|
.configure_set(Normal::X.in_base_set(Base::A))
|
||||||
|
.configure_set(Normal::Y.in_base_set(Base::B).in_set(Normal::X));
|
||||||
|
|
||||||
|
let result = schedule.initialize(&mut world);
|
||||||
|
assert!(matches!(
|
||||||
|
result,
|
||||||
|
Err(ScheduleBuildError::SetInMultipleBaseSets { .. })
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn default_base_set_ordering() {
|
||||||
|
let mut world = World::default();
|
||||||
|
let mut schedule = Schedule::default();
|
||||||
|
|
||||||
|
world.init_resource::<SystemOrder>();
|
||||||
|
|
||||||
|
schedule
|
||||||
|
.set_default_base_set(Base::A)
|
||||||
|
.configure_set(Base::A.before(Base::B))
|
||||||
|
.add_system(make_function_system(0).in_base_set(Base::B))
|
||||||
|
.add_system(make_function_system(1));
|
||||||
|
schedule.run(&mut world);
|
||||||
|
|
||||||
|
assert_eq!(world.resource::<SystemOrder>().0, vec![1, 0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -127,6 +127,12 @@ impl Schedule {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_default_base_set(&mut self, default_base_set: impl SystemSet) -> &mut Self {
|
||||||
|
self.graph
|
||||||
|
.set_default_base_set(Some(Box::new(default_base_set)));
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Add a system to the schedule.
|
/// Add a system to the schedule.
|
||||||
pub fn add_system<P>(&mut self, system: impl IntoSystemConfig<P>) -> &mut Self {
|
pub fn add_system<P>(&mut self, system: impl IntoSystemConfig<P>) -> &mut Self {
|
||||||
self.graph.add_system(system);
|
self.graph.add_system(system);
|
||||||
@ -264,14 +270,25 @@ impl Dag {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
|
||||||
|
enum BaseSetMembership {
|
||||||
|
Uncalculated,
|
||||||
|
None,
|
||||||
|
Some(NodeId),
|
||||||
|
}
|
||||||
|
|
||||||
/// A [`SystemSet`] with metadata, stored in a [`ScheduleGraph`].
|
/// A [`SystemSet`] with metadata, stored in a [`ScheduleGraph`].
|
||||||
struct SystemSetNode {
|
struct SystemSetNode {
|
||||||
inner: BoxedSystemSet,
|
inner: BoxedSystemSet,
|
||||||
|
base_set_membership: BaseSetMembership,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SystemSetNode {
|
impl SystemSetNode {
|
||||||
pub fn new(set: BoxedSystemSet) -> Self {
|
pub fn new(set: BoxedSystemSet) -> Self {
|
||||||
Self { inner: set }
|
Self {
|
||||||
|
inner: set,
|
||||||
|
base_set_membership: BaseSetMembership::Uncalculated,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name(&self) -> String {
|
pub fn name(&self) -> String {
|
||||||
@ -283,15 +300,43 @@ impl SystemSetNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A [`BoxedSystem`] with metadata, stored in a [`ScheduleGraph`].
|
||||||
|
struct SystemNode {
|
||||||
|
inner: Option<BoxedSystem>,
|
||||||
|
base_set_membership: BaseSetMembership,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SystemNode {
|
||||||
|
pub fn new(system: BoxedSystem) -> Self {
|
||||||
|
Self {
|
||||||
|
inner: Some(system),
|
||||||
|
base_set_membership: BaseSetMembership::Uncalculated,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get(&self) -> Option<&BoxedSystem> {
|
||||||
|
self.inner.as_ref()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_mut(&mut self) -> Option<&mut BoxedSystem> {
|
||||||
|
self.inner.as_mut()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn name(&self) -> String {
|
||||||
|
format!("{:?}", &self.inner)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Metadata for a [`Schedule`].
|
/// Metadata for a [`Schedule`].
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct ScheduleGraph {
|
struct ScheduleGraph {
|
||||||
systems: Vec<Option<BoxedSystem>>,
|
systems: Vec<SystemNode>,
|
||||||
system_conditions: Vec<Option<Vec<BoxedCondition>>>,
|
system_conditions: Vec<Option<Vec<BoxedCondition>>>,
|
||||||
system_sets: Vec<SystemSetNode>,
|
system_sets: Vec<SystemSetNode>,
|
||||||
system_set_conditions: Vec<Option<Vec<BoxedCondition>>>,
|
system_set_conditions: Vec<Option<Vec<BoxedCondition>>>,
|
||||||
system_set_ids: HashMap<BoxedSystemSet, NodeId>,
|
system_set_ids: HashMap<BoxedSystemSet, NodeId>,
|
||||||
uninit: Vec<(NodeId, usize)>,
|
uninit: Vec<(NodeId, usize)>,
|
||||||
|
maybe_default_base_set: Vec<NodeId>,
|
||||||
hierarchy: Dag,
|
hierarchy: Dag,
|
||||||
dependency: Dag,
|
dependency: Dag,
|
||||||
dependency_flattened: Dag,
|
dependency_flattened: Dag,
|
||||||
@ -300,6 +345,7 @@ struct ScheduleGraph {
|
|||||||
ambiguous_with_all: HashSet<NodeId>,
|
ambiguous_with_all: HashSet<NodeId>,
|
||||||
changed: bool,
|
changed: bool,
|
||||||
settings: ScheduleBuildSettings,
|
settings: ScheduleBuildSettings,
|
||||||
|
default_base_set: Option<BoxedSystemSet>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ScheduleGraph {
|
impl ScheduleGraph {
|
||||||
@ -310,6 +356,7 @@ impl ScheduleGraph {
|
|||||||
system_sets: Vec::new(),
|
system_sets: Vec::new(),
|
||||||
system_set_conditions: Vec::new(),
|
system_set_conditions: Vec::new(),
|
||||||
system_set_ids: HashMap::new(),
|
system_set_ids: HashMap::new(),
|
||||||
|
maybe_default_base_set: Vec::new(),
|
||||||
uninit: Vec::new(),
|
uninit: Vec::new(),
|
||||||
hierarchy: Dag::new(),
|
hierarchy: Dag::new(),
|
||||||
dependency: Dag::new(),
|
dependency: Dag::new(),
|
||||||
@ -319,6 +366,7 @@ impl ScheduleGraph {
|
|||||||
ambiguous_with_all: HashSet::new(),
|
ambiguous_with_all: HashSet::new(),
|
||||||
changed: false,
|
changed: false,
|
||||||
settings: default(),
|
settings: default(),
|
||||||
|
default_base_set: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -357,11 +405,11 @@ impl ScheduleGraph {
|
|||||||
let id = NodeId::System(self.systems.len());
|
let id = NodeId::System(self.systems.len());
|
||||||
|
|
||||||
// graph updates are immediate
|
// graph updates are immediate
|
||||||
self.update_graphs(id, graph_info)?;
|
self.update_graphs(id, graph_info, false)?;
|
||||||
|
|
||||||
// system init has to be deferred (need `&mut World`)
|
// system init has to be deferred (need `&mut World`)
|
||||||
self.uninit.push((id, 0));
|
self.uninit.push((id, 0));
|
||||||
self.systems.push(Some(system));
|
self.systems.push(SystemNode::new(system));
|
||||||
self.system_conditions.push(Some(conditions));
|
self.system_conditions.push(Some(conditions));
|
||||||
|
|
||||||
Ok(id)
|
Ok(id)
|
||||||
@ -405,7 +453,7 @@ impl ScheduleGraph {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// graph updates are immediate
|
// graph updates are immediate
|
||||||
self.update_graphs(id, graph_info)?;
|
self.update_graphs(id, graph_info, set.is_base())?;
|
||||||
|
|
||||||
// system init has to be deferred (need `&mut World`)
|
// system init has to be deferred (need `&mut World`)
|
||||||
let system_set_conditions =
|
let system_set_conditions =
|
||||||
@ -424,23 +472,33 @@ impl ScheduleGraph {
|
|||||||
id
|
id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn check_set(&mut self, id: &NodeId, set: &dyn SystemSet) -> Result<(), ScheduleBuildError> {
|
||||||
|
match self.system_set_ids.get(set) {
|
||||||
|
Some(set_id) => {
|
||||||
|
if id == set_id {
|
||||||
|
let string = format!("{:?}", &set);
|
||||||
|
return Err(ScheduleBuildError::HierarchyLoop(string));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
self.add_set(set.dyn_clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn check_sets(
|
fn check_sets(
|
||||||
&mut self,
|
&mut self,
|
||||||
id: &NodeId,
|
id: &NodeId,
|
||||||
graph_info: &GraphInfo,
|
graph_info: &GraphInfo,
|
||||||
) -> Result<(), ScheduleBuildError> {
|
) -> Result<(), ScheduleBuildError> {
|
||||||
for set in &graph_info.sets {
|
for set in &graph_info.sets {
|
||||||
match self.system_set_ids.get(set) {
|
self.check_set(id, &**set)?;
|
||||||
Some(set_id) => {
|
}
|
||||||
if id == set_id {
|
|
||||||
let string = format!("{:?}", &set);
|
if let Some(base_set) = &graph_info.base_set {
|
||||||
return Err(ScheduleBuildError::HierarchyLoop(string));
|
self.check_set(id, &**base_set)?;
|
||||||
}
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
self.add_set(set.dyn_clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -480,6 +538,7 @@ impl ScheduleGraph {
|
|||||||
&mut self,
|
&mut self,
|
||||||
id: NodeId,
|
id: NodeId,
|
||||||
graph_info: GraphInfo,
|
graph_info: GraphInfo,
|
||||||
|
is_base_set: bool,
|
||||||
) -> Result<(), ScheduleBuildError> {
|
) -> Result<(), ScheduleBuildError> {
|
||||||
self.check_sets(&id, &graph_info)?;
|
self.check_sets(&id, &graph_info)?;
|
||||||
self.check_edges(&id, &graph_info)?;
|
self.check_edges(&id, &graph_info)?;
|
||||||
@ -489,6 +548,8 @@ impl ScheduleGraph {
|
|||||||
sets,
|
sets,
|
||||||
dependencies,
|
dependencies,
|
||||||
ambiguous_with,
|
ambiguous_with,
|
||||||
|
base_set,
|
||||||
|
add_default_base_set,
|
||||||
..
|
..
|
||||||
} = graph_info;
|
} = graph_info;
|
||||||
|
|
||||||
@ -502,6 +563,34 @@ impl ScheduleGraph {
|
|||||||
self.dependency.graph.add_node(set);
|
self.dependency.graph.add_node(set);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the current node is not a base set, set the base set if it was configured
|
||||||
|
if !is_base_set {
|
||||||
|
if let Some(base_set) = base_set {
|
||||||
|
let set_id = self.system_set_ids[&base_set];
|
||||||
|
self.hierarchy.graph.add_edge(set_id, id, ());
|
||||||
|
} else if let Some(default_base_set) = &self.default_base_set {
|
||||||
|
if add_default_base_set {
|
||||||
|
match id {
|
||||||
|
NodeId::System(_) => {
|
||||||
|
// Queue the default base set. We queue systems instead of adding directly to allow
|
||||||
|
// sets to define base sets, which will override the default inheritance behavior
|
||||||
|
self.maybe_default_base_set.push(id);
|
||||||
|
}
|
||||||
|
NodeId::Set(_) => {
|
||||||
|
// Sets should be added automatically because developers explicitly called
|
||||||
|
// in_default_base_set()
|
||||||
|
let set_id = self.system_set_ids[default_base_set];
|
||||||
|
self.hierarchy.graph.add_edge(set_id, id, ());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !self.dependency.graph.contains_node(id) {
|
||||||
|
self.dependency.graph.add_node(id);
|
||||||
|
}
|
||||||
|
|
||||||
for (kind, set) in dependencies
|
for (kind, set) in dependencies
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|Dependency { kind, set }| (kind, self.system_set_ids[&set]))
|
.map(|Dependency { kind, set }| (kind, self.system_set_ids[&set]))
|
||||||
@ -538,7 +627,7 @@ impl ScheduleGraph {
|
|||||||
for (id, i) in self.uninit.drain(..) {
|
for (id, i) in self.uninit.drain(..) {
|
||||||
match id {
|
match id {
|
||||||
NodeId::System(index) => {
|
NodeId::System(index) => {
|
||||||
self.systems[index].as_mut().unwrap().initialize(world);
|
self.systems[index].get_mut().unwrap().initialize(world);
|
||||||
if let Some(v) = self.system_conditions[index].as_mut() {
|
if let Some(v) = self.system_conditions[index].as_mut() {
|
||||||
for condition in v.iter_mut() {
|
for condition in v.iter_mut() {
|
||||||
condition.initialize(world);
|
condition.initialize(world);
|
||||||
@ -556,12 +645,141 @@ impl ScheduleGraph {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Calculates the base set for each node and caches the results on the node
|
||||||
|
fn calculate_base_sets_and_detect_cycles(&mut self) -> Result<(), ScheduleBuildError> {
|
||||||
|
let set_ids = (0..self.system_sets.len()).map(NodeId::Set);
|
||||||
|
let system_ids = (0..self.systems.len()).map(NodeId::System);
|
||||||
|
let mut visited_sets = vec![false; self.system_sets.len()];
|
||||||
|
// reset base set membership, as this can change when the schedule updates
|
||||||
|
for system in &mut self.systems {
|
||||||
|
system.base_set_membership = BaseSetMembership::Uncalculated;
|
||||||
|
}
|
||||||
|
for system_set in &mut self.system_sets {
|
||||||
|
system_set.base_set_membership = BaseSetMembership::Uncalculated;
|
||||||
|
}
|
||||||
|
for node_id in set_ids.chain(system_ids) {
|
||||||
|
Self::calculate_base_set(
|
||||||
|
&self.hierarchy,
|
||||||
|
&mut self.system_sets,
|
||||||
|
&mut self.systems,
|
||||||
|
&mut visited_sets,
|
||||||
|
node_id,
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn calculate_base_set(
|
||||||
|
hierarchy: &Dag,
|
||||||
|
system_sets: &mut [SystemSetNode],
|
||||||
|
systems: &mut [SystemNode],
|
||||||
|
visited_sets: &mut [bool],
|
||||||
|
node_id: NodeId,
|
||||||
|
) -> Result<Option<NodeId>, ScheduleBuildError> {
|
||||||
|
let base_set_membership = match node_id {
|
||||||
|
// systems only have
|
||||||
|
NodeId::System(_) => BaseSetMembership::Uncalculated,
|
||||||
|
NodeId::Set(index) => {
|
||||||
|
let set_node = &mut system_sets[index];
|
||||||
|
if set_node.inner.is_base() {
|
||||||
|
set_node.base_set_membership = BaseSetMembership::Some(node_id);
|
||||||
|
}
|
||||||
|
set_node.base_set_membership
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let base_set = match base_set_membership {
|
||||||
|
BaseSetMembership::None => None,
|
||||||
|
BaseSetMembership::Some(node_id) => Some(node_id),
|
||||||
|
BaseSetMembership::Uncalculated => {
|
||||||
|
let mut base_set: Option<NodeId> = None;
|
||||||
|
if let NodeId::Set(index) = node_id {
|
||||||
|
if visited_sets[index] {
|
||||||
|
return Err(ScheduleBuildError::HierarchyCycle);
|
||||||
|
}
|
||||||
|
visited_sets[index] = true;
|
||||||
|
}
|
||||||
|
for neighbor in hierarchy
|
||||||
|
.graph
|
||||||
|
.neighbors_directed(node_id, Direction::Incoming)
|
||||||
|
{
|
||||||
|
if let Some(calculated_base_set) = Self::calculate_base_set(
|
||||||
|
hierarchy,
|
||||||
|
system_sets,
|
||||||
|
systems,
|
||||||
|
visited_sets,
|
||||||
|
neighbor,
|
||||||
|
)? {
|
||||||
|
if let Some(first_set) = base_set {
|
||||||
|
return Err(match node_id {
|
||||||
|
NodeId::System(index) => {
|
||||||
|
ScheduleBuildError::SystemInMultipleBaseSets {
|
||||||
|
system: systems[index].name(),
|
||||||
|
first_set: system_sets[first_set.index()].name(),
|
||||||
|
second_set: system_sets[calculated_base_set.index()].name(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NodeId::Set(index) => ScheduleBuildError::SetInMultipleBaseSets {
|
||||||
|
set: system_sets[index].name(),
|
||||||
|
first_set: system_sets[first_set.index()].name(),
|
||||||
|
second_set: system_sets[calculated_base_set.index()].name(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
base_set = Some(calculated_base_set);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
match node_id {
|
||||||
|
NodeId::System(index) => {
|
||||||
|
systems[index].base_set_membership = if let Some(base_set) = base_set {
|
||||||
|
BaseSetMembership::Some(base_set)
|
||||||
|
} else {
|
||||||
|
BaseSetMembership::None
|
||||||
|
};
|
||||||
|
}
|
||||||
|
NodeId::Set(index) => {
|
||||||
|
system_sets[index].base_set_membership = if let Some(base_set) = base_set {
|
||||||
|
BaseSetMembership::Some(base_set)
|
||||||
|
} else {
|
||||||
|
BaseSetMembership::None
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
base_set
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Ok(base_set)
|
||||||
|
}
|
||||||
|
|
||||||
fn build_schedule(
|
fn build_schedule(
|
||||||
&mut self,
|
&mut self,
|
||||||
components: &Components,
|
components: &Components,
|
||||||
) -> Result<SystemSchedule, ScheduleBuildError> {
|
) -> Result<SystemSchedule, ScheduleBuildError> {
|
||||||
|
self.calculate_base_sets_and_detect_cycles()?;
|
||||||
|
|
||||||
|
// Add missing base set membership to systems that defaulted to using the
|
||||||
|
// default base set and weren't added to a set that belongs to a base set.
|
||||||
|
if let Some(default_base_set) = &self.default_base_set {
|
||||||
|
let default_set_id = self.system_set_ids[default_base_set];
|
||||||
|
for system_id in std::mem::take(&mut self.maybe_default_base_set) {
|
||||||
|
let system_node = &mut self.systems[system_id.index()];
|
||||||
|
if system_node.base_set_membership == BaseSetMembership::None {
|
||||||
|
self.hierarchy.graph.add_edge(default_set_id, system_id, ());
|
||||||
|
system_node.base_set_membership = BaseSetMembership::Some(default_set_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
debug_assert_ne!(
|
||||||
|
system_node.base_set_membership,
|
||||||
|
BaseSetMembership::Uncalculated,
|
||||||
|
"base set membership should have been calculated"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// check hierarchy for cycles
|
// check hierarchy for cycles
|
||||||
let hier_scc = tarjan_scc(&self.hierarchy.graph);
|
let hier_scc = tarjan_scc(&self.hierarchy.graph);
|
||||||
|
// PERF: in theory we can skip this contains_cycles because we've already detected cycles
|
||||||
|
// using calculate_base_sets_and_detect_cycles
|
||||||
if self.contains_cycles(&hier_scc) {
|
if self.contains_cycles(&hier_scc) {
|
||||||
self.report_cycles(&hier_scc);
|
self.report_cycles(&hier_scc);
|
||||||
return Err(ScheduleBuildError::HierarchyCycle);
|
return Err(ScheduleBuildError::HierarchyCycle);
|
||||||
@ -767,8 +985,8 @@ impl ScheduleGraph {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let system_a = self.systems[a.index()].as_ref().unwrap();
|
let system_a = self.systems[a.index()].get().unwrap();
|
||||||
let system_b = self.systems[b.index()].as_ref().unwrap();
|
let system_b = self.systems[b.index()].get().unwrap();
|
||||||
if system_a.is_exclusive() || system_b.is_exclusive() {
|
if system_a.is_exclusive() || system_b.is_exclusive() {
|
||||||
conflicting_systems.push((a, b, Vec::new()));
|
conflicting_systems.push((a, b, Vec::new()));
|
||||||
} else {
|
} else {
|
||||||
@ -808,7 +1026,7 @@ impl ScheduleGraph {
|
|||||||
.filter(|&(_i, id)| id.is_system())
|
.filter(|&(_i, id)| id.is_system())
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let (hg_set_idxs, hg_set_ids): (Vec<_>, Vec<_>) = self
|
let (hg_set_with_conditions_idxs, hg_set_ids): (Vec<_>, Vec<_>) = self
|
||||||
.hierarchy
|
.hierarchy
|
||||||
.topsort
|
.topsort
|
||||||
.iter()
|
.iter()
|
||||||
@ -826,7 +1044,7 @@ impl ScheduleGraph {
|
|||||||
.unzip();
|
.unzip();
|
||||||
|
|
||||||
let sys_count = self.systems.len();
|
let sys_count = self.systems.len();
|
||||||
let set_count = hg_set_ids.len();
|
let set_with_conditions_count = hg_set_ids.len();
|
||||||
let node_count = self.systems.len() + self.system_sets.len();
|
let node_count = self.systems.len() + self.system_sets.len();
|
||||||
|
|
||||||
// get the number of dependencies and the immediate dependents of each system
|
// get the number of dependencies and the immediate dependents of each system
|
||||||
@ -853,9 +1071,10 @@ impl ScheduleGraph {
|
|||||||
|
|
||||||
// get the rows and columns of the hierarchy graph's reachability matrix
|
// get the rows and columns of the hierarchy graph's reachability matrix
|
||||||
// (needed to we can evaluate conditions in the correct order)
|
// (needed to we can evaluate conditions in the correct order)
|
||||||
let mut systems_in_sets = vec![FixedBitSet::with_capacity(sys_count); set_count];
|
let mut systems_in_sets_with_conditions =
|
||||||
for (i, &row) in hg_set_idxs.iter().enumerate() {
|
vec![FixedBitSet::with_capacity(sys_count); set_with_conditions_count];
|
||||||
let bitset = &mut systems_in_sets[i];
|
for (i, &row) in hg_set_with_conditions_idxs.iter().enumerate() {
|
||||||
|
let bitset = &mut systems_in_sets_with_conditions[i];
|
||||||
for &(col, sys_id) in &hg_systems {
|
for &(col, sys_id) in &hg_systems {
|
||||||
let idx = dg_system_idx_map[&sys_id];
|
let idx = dg_system_idx_map[&sys_id];
|
||||||
let is_descendant = hier_results.reachable[index(row, col, node_count)];
|
let is_descendant = hier_results.reachable[index(row, col, node_count)];
|
||||||
@ -863,11 +1082,12 @@ impl ScheduleGraph {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut sets_of_systems = vec![FixedBitSet::with_capacity(set_count); sys_count];
|
let mut sets_with_conditions_of_systems =
|
||||||
|
vec![FixedBitSet::with_capacity(set_with_conditions_count); sys_count];
|
||||||
for &(col, sys_id) in &hg_systems {
|
for &(col, sys_id) in &hg_systems {
|
||||||
let i = dg_system_idx_map[&sys_id];
|
let i = dg_system_idx_map[&sys_id];
|
||||||
let bitset = &mut sets_of_systems[i];
|
let bitset = &mut sets_with_conditions_of_systems[i];
|
||||||
for (idx, &row) in hg_set_idxs
|
for (idx, &row) in hg_set_with_conditions_idxs
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.take_while(|&(_idx, &row)| row < col)
|
.take_while(|&(_idx, &row)| row < col)
|
||||||
@ -880,13 +1100,13 @@ impl ScheduleGraph {
|
|||||||
Ok(SystemSchedule {
|
Ok(SystemSchedule {
|
||||||
systems: Vec::with_capacity(sys_count),
|
systems: Vec::with_capacity(sys_count),
|
||||||
system_conditions: Vec::with_capacity(sys_count),
|
system_conditions: Vec::with_capacity(sys_count),
|
||||||
set_conditions: Vec::with_capacity(set_count),
|
set_conditions: Vec::with_capacity(set_with_conditions_count),
|
||||||
system_ids: dg_system_ids,
|
system_ids: dg_system_ids,
|
||||||
set_ids: hg_set_ids,
|
set_ids: hg_set_ids,
|
||||||
system_dependencies,
|
system_dependencies,
|
||||||
system_dependents,
|
system_dependents,
|
||||||
sets_of_systems,
|
sets_with_conditions_of_systems,
|
||||||
systems_in_sets,
|
systems_in_sets_with_conditions,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -906,7 +1126,7 @@ impl ScheduleGraph {
|
|||||||
.zip(schedule.systems.drain(..))
|
.zip(schedule.systems.drain(..))
|
||||||
.zip(schedule.system_conditions.drain(..))
|
.zip(schedule.system_conditions.drain(..))
|
||||||
{
|
{
|
||||||
self.systems[id.index()] = Some(system);
|
self.systems[id.index()].inner = Some(system);
|
||||||
self.system_conditions[id.index()] = Some(conditions);
|
self.system_conditions[id.index()] = Some(conditions);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -922,7 +1142,7 @@ impl ScheduleGraph {
|
|||||||
|
|
||||||
// move systems into new schedule
|
// move systems into new schedule
|
||||||
for &id in &schedule.system_ids {
|
for &id in &schedule.system_ids {
|
||||||
let system = self.systems[id.index()].take().unwrap();
|
let system = self.systems[id.index()].inner.take().unwrap();
|
||||||
let conditions = self.system_conditions[id.index()].take().unwrap();
|
let conditions = self.system_conditions[id.index()].take().unwrap();
|
||||||
schedule.systems.push(system);
|
schedule.systems.push(system);
|
||||||
schedule.system_conditions.push(conditions);
|
schedule.system_conditions.push(conditions);
|
||||||
@ -935,17 +1155,24 @@ impl ScheduleGraph {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_default_base_set(&mut self, set: Option<BoxedSystemSet>) {
|
||||||
|
if let Some(set) = set {
|
||||||
|
self.default_base_set = Some(set.dyn_clone());
|
||||||
|
if self.system_set_ids.get(&set).is_none() {
|
||||||
|
self.add_set(set);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.default_base_set = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// methods for reporting errors
|
// methods for reporting errors
|
||||||
impl ScheduleGraph {
|
impl ScheduleGraph {
|
||||||
fn get_node_name(&self, id: &NodeId) -> String {
|
fn get_node_name(&self, id: &NodeId) -> String {
|
||||||
match id {
|
match id {
|
||||||
NodeId::System(_) => self.systems[id.index()]
|
NodeId::System(_) => self.systems[id.index()].get().unwrap().name().to_string(),
|
||||||
.as_ref()
|
|
||||||
.unwrap()
|
|
||||||
.name()
|
|
||||||
.to_string(),
|
|
||||||
NodeId::Set(_) => self.system_sets[id.index()].name(),
|
NodeId::Set(_) => self.system_sets[id.index()].name(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1100,6 +1327,20 @@ pub enum ScheduleBuildError {
|
|||||||
/// Tried to run a schedule before all of its systems have been initialized.
|
/// Tried to run a schedule before all of its systems have been initialized.
|
||||||
#[error("Systems in schedule have not been initialized.")]
|
#[error("Systems in schedule have not been initialized.")]
|
||||||
Uninitialized,
|
Uninitialized,
|
||||||
|
/// Tried to add a system to multiple base sets.
|
||||||
|
#[error("System `{system:?}` is in the base sets {first_set:?} and {second_set:?}, but systems can only belong to one base set.")]
|
||||||
|
SystemInMultipleBaseSets {
|
||||||
|
system: String,
|
||||||
|
first_set: String,
|
||||||
|
second_set: String,
|
||||||
|
},
|
||||||
|
/// Tried to add a set to multiple base sets.
|
||||||
|
#[error("Set `{set:?}` is in the base sets {first_set:?} and {second_set:?}, but sets can only belong to one base set.")]
|
||||||
|
SetInMultipleBaseSets {
|
||||||
|
set: String,
|
||||||
|
first_set: String,
|
||||||
|
second_set: String,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Specifies how schedule construction should respond to detecting a certain kind of issue.
|
/// Specifies how schedule construction should respond to detecting a certain kind of issue.
|
||||||
|
|||||||
@ -23,6 +23,16 @@ pub trait SystemSet: DynHash + Debug + Send + Sync + 'static {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns `true` if this set is a "base system set". Systems
|
||||||
|
/// can only belong to one base set at a time. Systems and Sets
|
||||||
|
/// can only be added to base sets using specialized `in_base_set`
|
||||||
|
/// APIs. This enables "mutually exclusive" behaviors. It also
|
||||||
|
/// enables schedules to have a "default base set", which can be used
|
||||||
|
/// to apply default configuration to systems.
|
||||||
|
fn is_base(&self) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates a boxed clone of the label corresponding to this system set.
|
/// Creates a boxed clone of the label corresponding to this system set.
|
||||||
fn dyn_clone(&self) -> Box<dyn SystemSet>;
|
fn dyn_clone(&self) -> Box<dyn SystemSet>;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,7 +24,7 @@ impl Plugin for GilrsPlugin {
|
|||||||
.add_system(
|
.add_system(
|
||||||
gilrs_event_system
|
gilrs_event_system
|
||||||
.before(InputSystem)
|
.before(InputSystem)
|
||||||
.in_set(CoreSet::PreUpdate),
|
.in_base_set(CoreSet::PreUpdate),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Err(err) => error!("Failed to start Gilrs. {}", err),
|
Err(err) => error!("Failed to start Gilrs. {}", err),
|
||||||
|
|||||||
@ -99,7 +99,7 @@ impl<T: Component> Plugin for ValidParentCheckPlugin<T> {
|
|||||||
app.init_resource::<ReportHierarchyIssue<T>>().add_system(
|
app.init_resource::<ReportHierarchyIssue<T>>().add_system(
|
||||||
check_hierarchy_component_has_valid_parent::<T>
|
check_hierarchy_component_has_valid_parent::<T>
|
||||||
.run_if(resource_equals(ReportHierarchyIssue::<T>::new(true)))
|
.run_if(resource_equals(ReportHierarchyIssue::<T>::new(true)))
|
||||||
.in_set(CoreSet::Last),
|
.in_base_set(CoreSet::Last),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -51,7 +51,7 @@ pub struct InputSystem;
|
|||||||
|
|
||||||
impl Plugin for InputPlugin {
|
impl Plugin for InputPlugin {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
app.configure_set(InputSystem.in_set(CoreSet::PreUpdate))
|
app.configure_set(InputSystem.in_base_set(CoreSet::PreUpdate))
|
||||||
// keyboard
|
// keyboard
|
||||||
.add_event::<KeyboardInput>()
|
.add_event::<KeyboardInput>()
|
||||||
.init_resource::<Input<KeyCode>>()
|
.init_resource::<Input<KeyCode>>()
|
||||||
|
|||||||
@ -138,40 +138,6 @@ pub fn derive_boxed_label(input: syn::DeriveInput, trait_path: &syn::Path) -> To
|
|||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Derive a label trait
|
|
||||||
///
|
|
||||||
/// # Args
|
|
||||||
///
|
|
||||||
/// - `input`: The [`syn::DeriveInput`] for struct that is deriving the label trait
|
|
||||||
/// - `trait_path`: The path [`syn::Path`] to the label trait
|
|
||||||
pub fn derive_set(input: syn::DeriveInput, trait_path: &syn::Path) -> TokenStream {
|
|
||||||
let ident = input.ident;
|
|
||||||
let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
|
|
||||||
let mut where_clause = where_clause.cloned().unwrap_or_else(|| syn::WhereClause {
|
|
||||||
where_token: Default::default(),
|
|
||||||
predicates: Default::default(),
|
|
||||||
});
|
|
||||||
where_clause.predicates.push(
|
|
||||||
syn::parse2(quote! {
|
|
||||||
Self: 'static + Send + Sync + Clone + Eq + ::std::fmt::Debug + ::std::hash::Hash
|
|
||||||
})
|
|
||||||
.unwrap(),
|
|
||||||
);
|
|
||||||
|
|
||||||
(quote! {
|
|
||||||
impl #impl_generics #trait_path for #ident #ty_generics #where_clause {
|
|
||||||
fn is_system_type(&self) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn dyn_clone(&self) -> std::boxed::Box<dyn #trait_path> {
|
|
||||||
std::boxed::Box::new(std::clone::Clone::clone(self))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.into()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Derive a label trait
|
/// Derive a label trait
|
||||||
///
|
///
|
||||||
/// # Args
|
/// # Args
|
||||||
|
|||||||
@ -181,14 +181,10 @@ impl Plugin for PbrPlugin {
|
|||||||
SimulationLightSystems::UpdateDirectionalLightCascades,
|
SimulationLightSystems::UpdateDirectionalLightCascades,
|
||||||
SimulationLightSystems::UpdateLightFrusta,
|
SimulationLightSystems::UpdateLightFrusta,
|
||||||
)
|
)
|
||||||
.in_set(CoreSet::PostUpdate),
|
.in_base_set(CoreSet::PostUpdate),
|
||||||
)
|
)
|
||||||
.add_plugin(FogPlugin)
|
.add_plugin(FogPlugin)
|
||||||
.add_system(
|
.add_system(add_clusters.in_set(SimulationLightSystems::AddClusters))
|
||||||
// NOTE: Clusters need to have been added before update_clusters is run so
|
|
||||||
// add as an exclusive system
|
|
||||||
add_clusters.in_set(SimulationLightSystems::AddClusters),
|
|
||||||
)
|
|
||||||
.add_system(apply_system_buffers.in_set(SimulationLightSystems::AddClustersFlush))
|
.add_system(apply_system_buffers.in_set(SimulationLightSystems::AddClustersFlush))
|
||||||
.add_system(
|
.add_system(
|
||||||
assign_lights_to_clusters
|
assign_lights_to_clusters
|
||||||
|
|||||||
@ -31,7 +31,7 @@ impl<T: CameraProjection + Component + GetTypeRegistration> Plugin for CameraPro
|
|||||||
.edit_schedule(CoreSchedule::Startup, |schedule| {
|
.edit_schedule(CoreSchedule::Startup, |schedule| {
|
||||||
schedule.configure_set(CameraUpdateSystem.in_set(StartupSet::PostStartup));
|
schedule.configure_set(CameraUpdateSystem.in_set(StartupSet::PostStartup));
|
||||||
})
|
})
|
||||||
.configure_set(CameraUpdateSystem.in_set(CoreSet::PostUpdate))
|
.configure_set(CameraUpdateSystem.in_base_set(CoreSet::PostUpdate))
|
||||||
.add_startup_system(
|
.add_startup_system(
|
||||||
crate::camera::camera_system::<T>
|
crate::camera::camera_system::<T>
|
||||||
.in_set(CameraUpdateSystem)
|
.in_set(CameraUpdateSystem)
|
||||||
|
|||||||
@ -210,19 +210,19 @@ impl Plugin for VisibilityPlugin {
|
|||||||
fn build(&self, app: &mut bevy_app::App) {
|
fn build(&self, app: &mut bevy_app::App) {
|
||||||
use VisibilitySystems::*;
|
use VisibilitySystems::*;
|
||||||
|
|
||||||
app.configure_set(CalculateBounds.in_set(CoreSet::PostUpdate))
|
app.configure_set(CalculateBounds.in_base_set(CoreSet::PostUpdate))
|
||||||
// We add an AABB component in CaclulateBounds, which must be ready on the same frame.
|
// We add an AABB component in CaclulateBounds, which must be ready on the same frame.
|
||||||
.add_system(apply_system_buffers.in_set(CalculateBoundsFlush))
|
.add_system(apply_system_buffers.in_set(CalculateBoundsFlush))
|
||||||
.configure_set(
|
.configure_set(
|
||||||
CalculateBoundsFlush
|
CalculateBoundsFlush
|
||||||
.after(CalculateBounds)
|
.after(CalculateBounds)
|
||||||
.in_set(CoreSet::PostUpdate),
|
.in_base_set(CoreSet::PostUpdate),
|
||||||
)
|
)
|
||||||
.configure_set(UpdateOrthographicFrusta.in_set(CoreSet::PostUpdate))
|
.configure_set(UpdateOrthographicFrusta.in_base_set(CoreSet::PostUpdate))
|
||||||
.configure_set(UpdatePerspectiveFrusta.in_set(CoreSet::PostUpdate))
|
.configure_set(UpdatePerspectiveFrusta.in_base_set(CoreSet::PostUpdate))
|
||||||
.configure_set(UpdateProjectionFrusta.in_set(CoreSet::PostUpdate))
|
.configure_set(UpdateProjectionFrusta.in_base_set(CoreSet::PostUpdate))
|
||||||
.configure_set(CheckVisibility.in_set(CoreSet::PostUpdate))
|
.configure_set(CheckVisibility.in_base_set(CoreSet::PostUpdate))
|
||||||
.configure_set(VisibilityPropagate.in_set(CoreSet::PostUpdate))
|
.configure_set(VisibilityPropagate.in_base_set(CoreSet::PostUpdate))
|
||||||
.add_system(calculate_bounds.in_set(CalculateBounds))
|
.add_system(calculate_bounds.in_set(CalculateBounds))
|
||||||
.add_system(
|
.add_system(
|
||||||
update_frusta::<OrthographicProjection>
|
update_frusta::<OrthographicProjection>
|
||||||
@ -247,7 +247,7 @@ impl Plugin for VisibilityPlugin {
|
|||||||
)
|
)
|
||||||
.add_system(
|
.add_system(
|
||||||
update_frusta::<Projection>
|
update_frusta::<Projection>
|
||||||
.in_set(CoreSet::PostUpdate)
|
.in_base_set(CoreSet::PostUpdate)
|
||||||
.after(camera_system::<Projection>)
|
.after(camera_system::<Projection>)
|
||||||
.after(TransformSystem::TransformPropagate),
|
.after(TransformSystem::TransformPropagate),
|
||||||
)
|
)
|
||||||
|
|||||||
@ -36,9 +36,9 @@ impl Plugin for ScenePlugin {
|
|||||||
.add_asset::<Scene>()
|
.add_asset::<Scene>()
|
||||||
.init_asset_loader::<SceneLoader>()
|
.init_asset_loader::<SceneLoader>()
|
||||||
.init_resource::<SceneSpawner>()
|
.init_resource::<SceneSpawner>()
|
||||||
.add_system(scene_spawner_system.in_set(CoreSet::Update))
|
.add_system(scene_spawner_system)
|
||||||
// Systems `*_bundle_spawner` must run before `scene_spawner_system`
|
// Systems `*_bundle_spawner` must run before `scene_spawner_system`
|
||||||
.add_system(scene_spawner.in_set(CoreSet::PreUpdate));
|
.add_system(scene_spawner.in_base_set(CoreSet::PreUpdate));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -82,7 +82,7 @@ impl Plugin for TextPlugin {
|
|||||||
.insert_resource(TextPipeline::default())
|
.insert_resource(TextPipeline::default())
|
||||||
.add_system(
|
.add_system(
|
||||||
update_text2d_layout
|
update_text2d_layout
|
||||||
.in_set(CoreSet::PostUpdate)
|
.in_base_set(CoreSet::PostUpdate)
|
||||||
.after(ModifiesWindows)
|
.after(ModifiesWindows)
|
||||||
// Potential conflict: `Assets<Image>`
|
// Potential conflict: `Assets<Image>`
|
||||||
// In practice, they run independently since `bevy_render::camera_update_system`
|
// In practice, they run independently since `bevy_render::camera_update_system`
|
||||||
|
|||||||
@ -39,9 +39,9 @@ impl Plugin for TimePlugin {
|
|||||||
.register_type::<Time>()
|
.register_type::<Time>()
|
||||||
.register_type::<Stopwatch>()
|
.register_type::<Stopwatch>()
|
||||||
.init_resource::<FixedTime>()
|
.init_resource::<FixedTime>()
|
||||||
.configure_set(TimeSystem.in_set(CoreSet::First))
|
.configure_set(TimeSystem.in_base_set(CoreSet::First))
|
||||||
.add_system(time_system.in_set(TimeSystem))
|
.add_system(time_system.in_set(TimeSystem))
|
||||||
.add_system(run_fixed_update_schedule.in_set(CoreSet::FixedUpdate));
|
.add_system(run_fixed_update_schedule.in_base_set(CoreSet::FixedUpdate));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -94,7 +94,7 @@ impl Plugin for TransformPlugin {
|
|||||||
.register_type::<GlobalTransform>()
|
.register_type::<GlobalTransform>()
|
||||||
.add_plugin(ValidParentCheckPlugin::<GlobalTransform>::default())
|
.add_plugin(ValidParentCheckPlugin::<GlobalTransform>::default())
|
||||||
// add transform systems to startup so the first update is "correct"
|
// add transform systems to startup so the first update is "correct"
|
||||||
.configure_set(TransformSystem::TransformPropagate.in_set(CoreSet::PostUpdate))
|
.configure_set(TransformSystem::TransformPropagate.in_base_set(CoreSet::PostUpdate))
|
||||||
.edit_schedule(CoreSchedule::Startup, |schedule| {
|
.edit_schedule(CoreSchedule::Startup, |schedule| {
|
||||||
schedule.configure_set(
|
schedule.configure_set(
|
||||||
TransformSystem::TransformPropagate.in_set(StartupSet::PostStartup),
|
TransformSystem::TransformPropagate.in_set(StartupSet::PostStartup),
|
||||||
|
|||||||
@ -101,14 +101,14 @@ impl Plugin for UiPlugin {
|
|||||||
.register_type::<UiImage>()
|
.register_type::<UiImage>()
|
||||||
.register_type::<Val>()
|
.register_type::<Val>()
|
||||||
.register_type::<widget::Button>()
|
.register_type::<widget::Button>()
|
||||||
.configure_set(UiSystem::Focus.in_set(CoreSet::PreUpdate))
|
.configure_set(UiSystem::Focus.in_base_set(CoreSet::PreUpdate))
|
||||||
.configure_set(UiSystem::Flex.in_set(CoreSet::PostUpdate))
|
.configure_set(UiSystem::Flex.in_base_set(CoreSet::PostUpdate))
|
||||||
.configure_set(UiSystem::Stack.in_set(CoreSet::PostUpdate))
|
.configure_set(UiSystem::Stack.in_base_set(CoreSet::PostUpdate))
|
||||||
.add_system(ui_focus_system.in_set(UiSystem::Focus).after(InputSystem))
|
.add_system(ui_focus_system.in_set(UiSystem::Focus).after(InputSystem))
|
||||||
// add these systems to front because these must run before transform update systems
|
// add these systems to front because these must run before transform update systems
|
||||||
.add_system(
|
.add_system(
|
||||||
widget::text_system
|
widget::text_system
|
||||||
.in_set(CoreSet::PostUpdate)
|
.in_base_set(CoreSet::PostUpdate)
|
||||||
.before(UiSystem::Flex)
|
.before(UiSystem::Flex)
|
||||||
.after(ModifiesWindows)
|
.after(ModifiesWindows)
|
||||||
// Potential conflict: `Assets<Image>`
|
// Potential conflict: `Assets<Image>`
|
||||||
@ -123,7 +123,7 @@ impl Plugin for UiPlugin {
|
|||||||
)
|
)
|
||||||
.add_system(
|
.add_system(
|
||||||
widget::update_image_calculated_size_system
|
widget::update_image_calculated_size_system
|
||||||
.in_set(CoreSet::PostUpdate)
|
.in_base_set(CoreSet::PostUpdate)
|
||||||
.before(UiSystem::Flex)
|
.before(UiSystem::Flex)
|
||||||
// Potential conflicts: `Assets<Image>`
|
// Potential conflicts: `Assets<Image>`
|
||||||
// They run independently since `widget::image_node_system` will only ever observe
|
// They run independently since `widget::image_node_system` will only ever observe
|
||||||
@ -142,7 +142,7 @@ impl Plugin for UiPlugin {
|
|||||||
.add_system(
|
.add_system(
|
||||||
update_clipping_system
|
update_clipping_system
|
||||||
.after(TransformSystem::TransformPropagate)
|
.after(TransformSystem::TransformPropagate)
|
||||||
.in_set(CoreSet::PostUpdate),
|
.in_base_set(CoreSet::PostUpdate),
|
||||||
);
|
);
|
||||||
|
|
||||||
crate::render::build_ui_render(app);
|
crate::render::build_ui_render(app);
|
||||||
|
|||||||
@ -93,16 +93,16 @@ impl Plugin for WindowPlugin {
|
|||||||
|
|
||||||
match self.exit_condition {
|
match self.exit_condition {
|
||||||
ExitCondition::OnPrimaryClosed => {
|
ExitCondition::OnPrimaryClosed => {
|
||||||
app.add_system(exit_on_primary_closed.in_set(CoreSet::PostUpdate));
|
app.add_system(exit_on_primary_closed.in_base_set(CoreSet::PostUpdate));
|
||||||
}
|
}
|
||||||
ExitCondition::OnAllClosed => {
|
ExitCondition::OnAllClosed => {
|
||||||
app.add_system(exit_on_all_closed.in_set(CoreSet::PostUpdate));
|
app.add_system(exit_on_all_closed.in_base_set(CoreSet::PostUpdate));
|
||||||
}
|
}
|
||||||
ExitCondition::DontExit => {}
|
ExitCondition::DontExit => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.close_when_requested {
|
if self.close_when_requested {
|
||||||
app.add_system(close_when_requested.in_set(CoreSet::PostUpdate));
|
app.add_system(close_when_requested.in_base_set(CoreSet::PostUpdate));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register event types
|
// Register event types
|
||||||
|
|||||||
@ -70,7 +70,7 @@ impl Plugin for WinitPlugin {
|
|||||||
app.init_non_send_resource::<WinitWindows>()
|
app.init_non_send_resource::<WinitWindows>()
|
||||||
.init_resource::<WinitSettings>()
|
.init_resource::<WinitSettings>()
|
||||||
.set_runner(winit_runner)
|
.set_runner(winit_runner)
|
||||||
.configure_set(ModifiesWindows.in_set(CoreSet::PostUpdate))
|
.configure_set(ModifiesWindows.in_base_set(CoreSet::PostUpdate))
|
||||||
// exit_on_all_closed only uses the query to determine if the query is empty,
|
// exit_on_all_closed only uses the query to determine if the query is empty,
|
||||||
// and so doesn't care about ordering relative to changed_window
|
// and so doesn't care about ordering relative to changed_window
|
||||||
.add_systems(
|
.add_systems(
|
||||||
|
|||||||
@ -6,7 +6,7 @@ fn main() {
|
|||||||
App::new()
|
App::new()
|
||||||
.add_plugins(DefaultPlugins)
|
.add_plugins(DefaultPlugins)
|
||||||
.add_startup_system(setup)
|
.add_startup_system(setup)
|
||||||
.add_system(sprite_movement.in_set(CoreSet::Update))
|
.add_system(sprite_movement)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@ fn main() {
|
|||||||
App::new()
|
App::new()
|
||||||
.add_plugins(DefaultPlugins.set(ImagePlugin::default_nearest()))
|
.add_plugins(DefaultPlugins.set(ImagePlugin::default_nearest()))
|
||||||
.add_startup_system(setup)
|
.add_startup_system(setup)
|
||||||
.add_system(sprite_movement.in_set(CoreSet::Update))
|
.add_system(sprite_movement)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -7,7 +7,7 @@ fn main() {
|
|||||||
App::new()
|
App::new()
|
||||||
.add_plugins(DefaultPlugins.set(ImagePlugin::default_nearest())) // prevents blurry sprites
|
.add_plugins(DefaultPlugins.set(ImagePlugin::default_nearest())) // prevents blurry sprites
|
||||||
.add_startup_system(setup)
|
.add_startup_system(setup)
|
||||||
.add_system(animate_sprite.in_set(CoreSet::Update))
|
.add_system(animate_sprite)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -14,9 +14,9 @@ fn main() {
|
|||||||
App::new()
|
App::new()
|
||||||
.add_plugins(DefaultPlugins)
|
.add_plugins(DefaultPlugins)
|
||||||
.add_startup_system(setup)
|
.add_startup_system(setup)
|
||||||
.add_system(animate_translation.in_set(CoreSet::Update))
|
.add_system(animate_translation)
|
||||||
.add_system(animate_rotation.in_set(CoreSet::Update))
|
.add_system(animate_rotation)
|
||||||
.add_system(animate_scale.in_set(CoreSet::Update))
|
.add_system(animate_scale)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -12,7 +12,7 @@ fn main() {
|
|||||||
App::new()
|
App::new()
|
||||||
.add_plugins(DefaultPlugins.set(ImagePlugin::default_nearest()))
|
.add_plugins(DefaultPlugins.set(ImagePlugin::default_nearest()))
|
||||||
.add_startup_system(setup)
|
.add_startup_system(setup)
|
||||||
.add_system(rotate.in_set(CoreSet::Update))
|
.add_system(rotate)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -18,7 +18,7 @@ fn main() {
|
|||||||
|
|
||||||
app.add_plugins(DefaultPlugins)
|
app.add_plugins(DefaultPlugins)
|
||||||
.add_startup_system(setup)
|
.add_startup_system(setup)
|
||||||
.add_system(example_control_system.in_set(CoreSet::Update));
|
.add_system(example_control_system);
|
||||||
|
|
||||||
// Unfortunately, MSAA and HDR are not supported simultaneously under WebGL.
|
// Unfortunately, MSAA and HDR are not supported simultaneously under WebGL.
|
||||||
// Since this example uses HDR, we must disable MSAA for WASM builds, at least
|
// Since this example uses HDR, we must disable MSAA for WASM builds, at least
|
||||||
|
|||||||
@ -11,7 +11,7 @@ fn main() {
|
|||||||
.add_plugins(DefaultPlugins)
|
.add_plugins(DefaultPlugins)
|
||||||
.add_startup_system(setup_scene)
|
.add_startup_system(setup_scene)
|
||||||
.add_system(update_bloom_settings)
|
.add_system(update_bloom_settings)
|
||||||
.add_system(bounce_spheres.in_set(CoreSet::Update))
|
.add_system(bounce_spheres)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -9,8 +9,8 @@ fn main() {
|
|||||||
App::new()
|
App::new()
|
||||||
.add_plugins(DefaultPlugins)
|
.add_plugins(DefaultPlugins)
|
||||||
.add_startup_system(setup)
|
.add_startup_system(setup)
|
||||||
.add_system(movement.in_set(CoreSet::Update))
|
.add_system(movement)
|
||||||
.add_system(animate_light_direction.in_set(CoreSet::Update))
|
.add_system(animate_light_direction)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -16,7 +16,7 @@ fn main() {
|
|||||||
.insert_resource(DirectionalLightShadowMap { size: 4096 })
|
.insert_resource(DirectionalLightShadowMap { size: 4096 })
|
||||||
.add_plugins(DefaultPlugins)
|
.add_plugins(DefaultPlugins)
|
||||||
.add_startup_system(setup)
|
.add_startup_system(setup)
|
||||||
.add_system(animate_light_direction.in_set(CoreSet::Update))
|
.add_system(animate_light_direction)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -13,7 +13,7 @@ fn main() {
|
|||||||
.insert_resource(Msaa::default())
|
.insert_resource(Msaa::default())
|
||||||
.add_plugins(DefaultPlugins)
|
.add_plugins(DefaultPlugins)
|
||||||
.add_startup_system(setup)
|
.add_startup_system(setup)
|
||||||
.add_system(cycle_msaa.in_set(CoreSet::Update))
|
.add_system(cycle_msaa)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -7,7 +7,7 @@ fn main() {
|
|||||||
App::new()
|
App::new()
|
||||||
.add_plugins(DefaultPlugins)
|
.add_plugins(DefaultPlugins)
|
||||||
.add_startup_system(setup)
|
.add_startup_system(setup)
|
||||||
.add_system(rotator_system.in_set(CoreSet::Update))
|
.add_system(rotator_system)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -18,8 +18,8 @@ fn main() {
|
|||||||
App::new()
|
App::new()
|
||||||
.add_plugins(DefaultPlugins)
|
.add_plugins(DefaultPlugins)
|
||||||
.add_startup_system(setup)
|
.add_startup_system(setup)
|
||||||
.add_system(cube_rotator_system.in_set(CoreSet::Update))
|
.add_system(cube_rotator_system)
|
||||||
.add_system(rotator_system.in_set(CoreSet::Update))
|
.add_system(rotator_system)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -23,7 +23,7 @@ fn main() {
|
|||||||
.add_system(adjust_point_light_biases)
|
.add_system(adjust_point_light_biases)
|
||||||
.add_system(toggle_light)
|
.add_system(toggle_light)
|
||||||
.add_system(adjust_directional_light_biases)
|
.add_system(adjust_directional_light_biases)
|
||||||
.add_system(camera_controller.in_set(CoreSet::Update))
|
.add_system(camera_controller)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -11,7 +11,7 @@ fn main() {
|
|||||||
App::new()
|
App::new()
|
||||||
.add_plugins(DefaultPlugins)
|
.add_plugins(DefaultPlugins)
|
||||||
.add_startup_system(setup)
|
.add_startup_system(setup)
|
||||||
.add_system(set_camera_viewports.in_set(CoreSet::Update))
|
.add_system(set_camera_viewports)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -7,7 +7,7 @@ fn main() {
|
|||||||
App::new()
|
App::new()
|
||||||
.add_plugins(DefaultPlugins)
|
.add_plugins(DefaultPlugins)
|
||||||
.add_startup_system(setup)
|
.add_startup_system(setup)
|
||||||
.add_system(move_scene_entities.in_set(CoreSet::Update))
|
.add_system(move_scene_entities)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -15,7 +15,7 @@ fn main() {
|
|||||||
})
|
})
|
||||||
.add_startup_system(setup)
|
.add_startup_system(setup)
|
||||||
.add_system(setup_scene_once_loaded)
|
.add_system(setup_scene_once_loaded)
|
||||||
.add_system(keyboard_animation_control.in_set(CoreSet::Update))
|
.add_system(keyboard_animation_control)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -21,7 +21,7 @@ fn main() {
|
|||||||
..default()
|
..default()
|
||||||
})
|
})
|
||||||
.add_startup_system(setup)
|
.add_startup_system(setup)
|
||||||
.add_system(joint_animation.in_set(CoreSet::Update))
|
.add_system(joint_animation)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -13,7 +13,7 @@ fn main() {
|
|||||||
..default()
|
..default()
|
||||||
})
|
})
|
||||||
.add_startup_system(setup)
|
.add_startup_system(setup)
|
||||||
.add_system(joint_animation.in_set(CoreSet::Update))
|
.add_system(joint_animation)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -240,6 +240,7 @@ fn print_at_end_round(mut counter: Local<u32>) {
|
|||||||
|
|
||||||
/// A group of related system sets, used for controlling the order of systems
|
/// A group of related system sets, used for controlling the order of systems
|
||||||
#[derive(Debug, Hash, PartialEq, Eq, Clone, SystemSet)]
|
#[derive(Debug, Hash, PartialEq, Eq, Clone, SystemSet)]
|
||||||
|
#[system_set(base)]
|
||||||
enum MySet {
|
enum MySet {
|
||||||
BeforeRound,
|
BeforeRound,
|
||||||
AfterRound,
|
AfterRound,
|
||||||
@ -281,21 +282,21 @@ fn main() {
|
|||||||
// add_system(system) adds systems to the Update system set by default
|
// add_system(system) adds systems to the Update system set by default
|
||||||
// However we can manually specify the set if we want to. The following is equivalent to
|
// However we can manually specify the set if we want to. The following is equivalent to
|
||||||
// add_system(score_system)
|
// add_system(score_system)
|
||||||
.add_system(score_system.in_set(CoreSet::Update))
|
.add_system(score_system)
|
||||||
// There are other `CoreSets`, such as `Last` which runs at the very end of each run.
|
// There are other `CoreSets`, such as `Last` which runs at the very end of each run.
|
||||||
.add_system(print_at_end_round.in_set(CoreSet::Last))
|
.add_system(print_at_end_round.in_base_set(CoreSet::Last))
|
||||||
// We can also create new system sets, and order them relative to other system sets.
|
// We can also create new system sets, and order them relative to other system sets.
|
||||||
// Here is what our games stage order will look like:
|
// Here is what our games stage order will look like:
|
||||||
// "before_round": new_player_system, new_round_system
|
// "before_round": new_player_system, new_round_system
|
||||||
// "update": print_message_system, score_system
|
// "update": print_message_system, score_system
|
||||||
// "after_round": score_check_system, game_over_system
|
// "after_round": score_check_system, game_over_system
|
||||||
.configure_set(MySet::BeforeRound.no_default_set().before(CoreSet::Update))
|
.configure_set(MySet::BeforeRound.before(CoreSet::Update))
|
||||||
.configure_set(MySet::AfterRound.no_default_set().after(CoreSet::Update))
|
.configure_set(MySet::AfterRound.after(CoreSet::Update))
|
||||||
.add_system(new_round_system.in_set(MySet::BeforeRound))
|
.add_system(new_round_system.in_base_set(MySet::BeforeRound))
|
||||||
.add_system(
|
.add_system(
|
||||||
new_player_system
|
new_player_system
|
||||||
.after(new_round_system)
|
.after(new_round_system)
|
||||||
.in_set(MySet::BeforeRound),
|
.in_base_set(MySet::BeforeRound),
|
||||||
)
|
)
|
||||||
.add_system(exclusive_player_system.in_set(MySet::BeforeRound))
|
.add_system(exclusive_player_system.in_set(MySet::BeforeRound))
|
||||||
.add_system(score_check_system.in_set(MySet::AfterRound))
|
.add_system(score_check_system.in_set(MySet::AfterRound))
|
||||||
|
|||||||
@ -8,7 +8,7 @@ fn main() {
|
|||||||
App::new()
|
App::new()
|
||||||
.add_plugins(DefaultPlugins)
|
.add_plugins(DefaultPlugins)
|
||||||
.add_startup_system(setup)
|
.add_startup_system(setup)
|
||||||
.add_system(rotate.in_set(CoreSet::Update))
|
.add_system(rotate)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -15,7 +15,7 @@ fn main() {
|
|||||||
.add_startup_system(generate_bodies)
|
.add_startup_system(generate_bodies)
|
||||||
.insert_resource(FixedTime::new_from_secs(DELTA_TIME))
|
.insert_resource(FixedTime::new_from_secs(DELTA_TIME))
|
||||||
.add_systems_to_schedule(CoreSchedule::FixedUpdate, (interact_bodies, integrate))
|
.add_systems_to_schedule(CoreSchedule::FixedUpdate, (interact_bodies, integrate))
|
||||||
.add_system(look_at_star.in_set(CoreSet::Update))
|
.add_system(look_at_star)
|
||||||
.insert_resource(ClearColor(Color::BLACK))
|
.insert_resource(ClearColor(Color::BLACK))
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -70,7 +70,7 @@ fn main() {
|
|||||||
App::new()
|
App::new()
|
||||||
.add_plugins(DefaultPlugins)
|
.add_plugins(DefaultPlugins)
|
||||||
.add_startup_system(spawn_system)
|
.add_startup_system(spawn_system)
|
||||||
.add_system(move_system.in_set(CoreSet::Update))
|
.add_system(move_system)
|
||||||
.add_system(bounce_system.in_set(CoreSet::Update))
|
.add_system(bounce_system)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,8 +15,8 @@ fn main() {
|
|||||||
App::new()
|
App::new()
|
||||||
.add_plugins(DefaultPlugins)
|
.add_plugins(DefaultPlugins)
|
||||||
.add_startup_system(setup)
|
.add_startup_system(setup)
|
||||||
.add_system(remove_component.in_set(CoreSet::Update))
|
.add_system(remove_component)
|
||||||
.add_system(react_on_removal.in_set(CoreSet::PostUpdate))
|
.add_system(react_on_removal.in_base_set(CoreSet::PostUpdate))
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -13,9 +13,9 @@ fn main() {
|
|||||||
.add_plugins(DefaultPlugins)
|
.add_plugins(DefaultPlugins)
|
||||||
.add_startup_system(setup_contributor_selection)
|
.add_startup_system(setup_contributor_selection)
|
||||||
.add_startup_system(setup)
|
.add_startup_system(setup)
|
||||||
.add_system(velocity_system.in_set(CoreSet::Update))
|
.add_system(velocity_system)
|
||||||
.add_system(move_system.in_set(CoreSet::Update))
|
.add_system(move_system)
|
||||||
.add_system(collision_system.in_set(CoreSet::Update))
|
.add_system(collision_system)
|
||||||
.add_system(select_system)
|
.add_system(select_system)
|
||||||
.init_resource::<SelectionState>()
|
.init_resource::<SelectionState>()
|
||||||
.run();
|
.run();
|
||||||
|
|||||||
@ -14,7 +14,7 @@ fn main() {
|
|||||||
}))
|
}))
|
||||||
.add_startup_system(setup_scene)
|
.add_startup_system(setup_scene)
|
||||||
.add_startup_system(setup_music)
|
.add_startup_system(setup_music)
|
||||||
.add_system(touch_camera.in_set(CoreSet::Update))
|
.add_system(touch_camera)
|
||||||
.add_system(button_handler)
|
.add_system(button_handler)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,7 +11,7 @@ fn main() {
|
|||||||
.add_plugins(DefaultPlugins)
|
.add_plugins(DefaultPlugins)
|
||||||
.add_plugin(MaterialPlugin::<CustomMaterial>::default())
|
.add_plugin(MaterialPlugin::<CustomMaterial>::default())
|
||||||
.add_startup_system(setup)
|
.add_startup_system(setup)
|
||||||
.add_system(rotate_camera.in_set(CoreSet::Update))
|
.add_system(rotate_camera)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -29,7 +29,7 @@ fn main() {
|
|||||||
..default()
|
..default()
|
||||||
})
|
})
|
||||||
.add_startup_system(setup)
|
.add_startup_system(setup)
|
||||||
.add_system(rotate.in_set(CoreSet::Update))
|
.add_system(rotate)
|
||||||
.add_system(update)
|
.add_system(update)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -44,9 +44,9 @@ fn main() {
|
|||||||
color: Color::WHITE,
|
color: Color::WHITE,
|
||||||
})
|
})
|
||||||
.add_startup_system(setup)
|
.add_startup_system(setup)
|
||||||
.add_system(mouse_handler.in_set(CoreSet::Update))
|
.add_system(mouse_handler)
|
||||||
.add_system(movement_system.in_set(CoreSet::Update))
|
.add_system(movement_system)
|
||||||
.add_system(collision_system.in_set(CoreSet::Update))
|
.add_system(collision_system)
|
||||||
.add_system(counter_system)
|
.add_system(counter_system)
|
||||||
.add_system_to_schedule(CoreSchedule::FixedUpdate, scheduled_spawner)
|
.add_system_to_schedule(CoreSchedule::FixedUpdate, scheduled_spawner)
|
||||||
.insert_resource(FixedTime::new_from_secs(0.2))
|
.insert_resource(FixedTime::new_from_secs(0.2))
|
||||||
|
|||||||
@ -33,13 +33,9 @@ fn main() {
|
|||||||
..default()
|
..default()
|
||||||
}))
|
}))
|
||||||
.add_startup_system(setup)
|
.add_startup_system(setup)
|
||||||
.add_system(animate_sprite.in_set(CoreSet::Update))
|
.add_system(animate_sprite)
|
||||||
.add_system(print_sprite_count)
|
.add_system(print_sprite_count)
|
||||||
.add_system(
|
.add_system(move_camera.after(print_sprite_count))
|
||||||
move_camera
|
|
||||||
.in_set(CoreSet::Update)
|
|
||||||
.after(print_sprite_count),
|
|
||||||
)
|
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -31,8 +31,8 @@ fn main() {
|
|||||||
.add_plugin(FrameTimeDiagnosticsPlugin::default())
|
.add_plugin(FrameTimeDiagnosticsPlugin::default())
|
||||||
.add_plugin(LogDiagnosticsPlugin::default())
|
.add_plugin(LogDiagnosticsPlugin::default())
|
||||||
.add_startup_system(setup)
|
.add_startup_system(setup)
|
||||||
.add_system(move_camera.in_set(CoreSet::Update))
|
.add_system(move_camera)
|
||||||
.add_system(print_mesh_count.in_set(CoreSet::Update))
|
.add_system(print_mesh_count)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -27,7 +27,7 @@ fn main() {
|
|||||||
.add_plugin(FrameTimeDiagnosticsPlugin::default())
|
.add_plugin(FrameTimeDiagnosticsPlugin::default())
|
||||||
.add_plugin(LogDiagnosticsPlugin::default())
|
.add_plugin(LogDiagnosticsPlugin::default())
|
||||||
.add_startup_system(setup)
|
.add_startup_system(setup)
|
||||||
.add_system(move_camera.in_set(CoreSet::Update))
|
.add_system(move_camera)
|
||||||
.add_system(print_light_count)
|
.add_system(print_light_count)
|
||||||
.add_plugin(LogVisibleLights)
|
.add_plugin(LogVisibleLights)
|
||||||
.run();
|
.run();
|
||||||
|
|||||||
@ -188,7 +188,7 @@ fn main() {
|
|||||||
.add_startup_system(setup)
|
.add_startup_system(setup)
|
||||||
// Updating transforms *must* be done before `CoreSet::PostUpdate`
|
// Updating transforms *must* be done before `CoreSet::PostUpdate`
|
||||||
// or the hierarchy will momentarily be in an invalid state.
|
// or the hierarchy will momentarily be in an invalid state.
|
||||||
.add_system(update.in_set(CoreSet::Update))
|
.add_system(update)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -131,10 +131,10 @@ fn main() {
|
|||||||
.add_startup_system(setup_sticks)
|
.add_startup_system(setup_sticks)
|
||||||
.add_startup_system(setup_triggers)
|
.add_startup_system(setup_triggers)
|
||||||
.add_startup_system(setup_connected)
|
.add_startup_system(setup_connected)
|
||||||
.add_system(update_buttons.in_set(CoreSet::Update))
|
.add_system(update_buttons)
|
||||||
.add_system(update_button_values.in_set(CoreSet::Update))
|
.add_system(update_button_values)
|
||||||
.add_system(update_axes.in_set(CoreSet::Update))
|
.add_system(update_axes)
|
||||||
.add_system(update_connected.in_set(CoreSet::Update))
|
.add_system(update_connected)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -42,7 +42,7 @@ fn main() {
|
|||||||
.add_plugin(CameraControllerPlugin)
|
.add_plugin(CameraControllerPlugin)
|
||||||
.add_plugin(SceneViewerPlugin)
|
.add_plugin(SceneViewerPlugin)
|
||||||
.add_startup_system(setup)
|
.add_startup_system(setup)
|
||||||
.add_system(setup_scene_after_load.in_set(CoreSet::PreUpdate));
|
.add_system(setup_scene_after_load.in_base_set(CoreSet::PreUpdate));
|
||||||
|
|
||||||
app.run();
|
app.run();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -57,13 +57,13 @@ pub struct SceneViewerPlugin;
|
|||||||
impl Plugin for SceneViewerPlugin {
|
impl Plugin for SceneViewerPlugin {
|
||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
app.init_resource::<CameraTracker>()
|
app.init_resource::<CameraTracker>()
|
||||||
.add_system(scene_load_check.in_set(CoreSet::PreUpdate))
|
.add_system(scene_load_check.in_base_set(CoreSet::PreUpdate))
|
||||||
.add_system(update_lights.in_set(CoreSet::Update))
|
.add_system(update_lights)
|
||||||
.add_system(camera_tracker.in_set(CoreSet::Update));
|
.add_system(camera_tracker);
|
||||||
|
|
||||||
#[cfg(feature = "animation")]
|
#[cfg(feature = "animation")]
|
||||||
app.add_system(start_animation.in_set(CoreSet::Update))
|
app.add_system(start_animation)
|
||||||
.add_system(keyboard_animation_control.in_set(CoreSet::Update));
|
.add_system(keyboard_animation_control);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -14,7 +14,7 @@ fn main() {
|
|||||||
App::new()
|
App::new()
|
||||||
.add_plugins(DefaultPlugins)
|
.add_plugins(DefaultPlugins)
|
||||||
.add_startup_system(setup)
|
.add_startup_system(setup)
|
||||||
.add_system(rotate_cube.in_set(CoreSet::Update))
|
.add_system(rotate_cube)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -30,8 +30,8 @@ fn main() {
|
|||||||
App::new()
|
App::new()
|
||||||
.add_plugins(DefaultPlugins)
|
.add_plugins(DefaultPlugins)
|
||||||
.add_startup_system(setup)
|
.add_startup_system(setup)
|
||||||
.add_system(change_scale_direction.in_set(CoreSet::Update))
|
.add_system(change_scale_direction)
|
||||||
.add_system(scale_cube.in_set(CoreSet::Update))
|
.add_system(scale_cube)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -25,9 +25,9 @@ fn main() {
|
|||||||
App::new()
|
App::new()
|
||||||
.add_plugins(DefaultPlugins)
|
.add_plugins(DefaultPlugins)
|
||||||
.add_startup_system(setup)
|
.add_startup_system(setup)
|
||||||
.add_system(move_cube.in_set(CoreSet::Update))
|
.add_system(move_cube)
|
||||||
.add_system(rotate_cube.in_set(CoreSet::Update))
|
.add_system(rotate_cube)
|
||||||
.add_system(scale_down_sphere_proportional_to_cube_travel_distance.in_set(CoreSet::Update))
|
.add_system(scale_down_sphere_proportional_to_cube_travel_distance)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -26,7 +26,7 @@ fn main() {
|
|||||||
App::new()
|
App::new()
|
||||||
.add_plugins(DefaultPlugins)
|
.add_plugins(DefaultPlugins)
|
||||||
.add_startup_system(setup)
|
.add_startup_system(setup)
|
||||||
.add_system(move_cube.in_set(CoreSet::Update))
|
.add_system(move_cube)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -8,7 +8,7 @@ fn main() {
|
|||||||
// Only run the app when there is user input. This will significantly reduce CPU/GPU use.
|
// Only run the app when there is user input. This will significantly reduce CPU/GPU use.
|
||||||
.insert_resource(WinitSettings::desktop_app())
|
.insert_resource(WinitSettings::desktop_app())
|
||||||
.add_startup_system(setup)
|
.add_startup_system(setup)
|
||||||
.add_system(relative_cursor_position_system.in_set(CoreSet::Update))
|
.add_system(relative_cursor_position_system)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -13,8 +13,8 @@ fn main() {
|
|||||||
.add_plugins(DefaultPlugins)
|
.add_plugins(DefaultPlugins)
|
||||||
.add_plugin(FrameTimeDiagnosticsPlugin::default())
|
.add_plugin(FrameTimeDiagnosticsPlugin::default())
|
||||||
.add_startup_system(setup)
|
.add_startup_system(setup)
|
||||||
.add_system(text_update_system.in_set(CoreSet::Update))
|
.add_system(text_update_system)
|
||||||
.add_system(text_color_system.in_set(CoreSet::Update))
|
.add_system(text_color_system)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -17,7 +17,7 @@ fn main() {
|
|||||||
}))
|
}))
|
||||||
.add_plugin(FrameTimeDiagnosticsPlugin)
|
.add_plugin(FrameTimeDiagnosticsPlugin)
|
||||||
.add_startup_system(infotext_system)
|
.add_startup_system(infotext_system)
|
||||||
.add_system(change_text_system.in_set(CoreSet::Update))
|
.add_system(change_text_system)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -12,7 +12,7 @@ fn main() {
|
|||||||
// Only run the app when there is user input. This will significantly reduce CPU/GPU use.
|
// Only run the app when there is user input. This will significantly reduce CPU/GPU use.
|
||||||
.insert_resource(WinitSettings::desktop_app())
|
.insert_resource(WinitSettings::desktop_app())
|
||||||
.add_startup_system(setup)
|
.add_startup_system(setup)
|
||||||
.add_system(mouse_scroll.in_set(CoreSet::Update))
|
.add_system(mouse_scroll)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -17,8 +17,8 @@ fn main() {
|
|||||||
target_time: Timer::new(Duration::from_millis(SCALE_TIME), TimerMode::Once),
|
target_time: Timer::new(Duration::from_millis(SCALE_TIME), TimerMode::Once),
|
||||||
})
|
})
|
||||||
.add_startup_system(setup)
|
.add_startup_system(setup)
|
||||||
.add_system(change_scaling.in_set(CoreSet::Update))
|
.add_system(change_scaling)
|
||||||
.add_system(apply_scaling.after(change_scaling).in_set(CoreSet::Update))
|
.add_system(apply_scaling.after(change_scaling))
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -34,9 +34,9 @@ fn main() {
|
|||||||
..default()
|
..default()
|
||||||
}))
|
}))
|
||||||
.add_startup_system(test_setup::setup)
|
.add_startup_system(test_setup::setup)
|
||||||
.add_system(test_setup::cycle_modes.in_set(CoreSet::Update))
|
.add_system(test_setup::cycle_modes)
|
||||||
.add_system(test_setup::rotate_cube.in_set(CoreSet::Update))
|
.add_system(test_setup::rotate_cube)
|
||||||
.add_system(test_setup::update_text.in_set(CoreSet::Update))
|
.add_system(test_setup::update_text)
|
||||||
.add_system(update_winit)
|
.add_system(update_winit)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user