diff --git a/crates/bevy_app/src/app.rs b/crates/bevy_app/src/app.rs index de317e634a856..f7f90c5e5a7ee 100644 --- a/crates/bevy_app/src/app.rs +++ b/crates/bevy_app/src/app.rs @@ -1,4 +1,7 @@ -use crate::{CoreSchedule, CoreSet, Plugin, PluginGroup, StartupSet}; +use crate::{ + CoreSchedule, CoreSet, IntoSystemAppConfig, IntoSystemAppConfigs, Plugin, PluginGroup, + StartupSet, SystemAppConfig, +}; pub use bevy_derive::AppLabel; use bevy_ecs::{ prelude::*, @@ -378,10 +381,18 @@ impl App { /// # /// app.add_system(my_system); /// ``` - pub fn add_system(&mut self, system: impl IntoSystemConfig) -> &mut Self { + pub fn add_system(&mut self, system: impl IntoSystemAppConfig) -> &mut Self { let mut schedules = self.world.resource_mut::(); - if let Some(default_schedule) = schedules.get_mut(&*self.default_schedule_label) { + let SystemAppConfig { system, schedule } = system.into_app_config(); + + if let Some(schedule_label) = schedule { + if let Some(schedule) = schedules.get_mut(&*schedule_label) { + schedule.add_system(system); + } else { + panic!("Schedule {schedule_label:?} does not exist.") + } + } else if let Some(default_schedule) = schedules.get_mut(&*self.default_schedule_label) { default_schedule.add_system(system); } else { let schedule_label = &self.default_schedule_label; @@ -406,48 +417,28 @@ impl App { /// # /// app.add_systems((system_a, system_b, system_c)); /// ``` - pub fn add_systems(&mut self, systems: impl IntoSystemConfigs) -> &mut Self { - let mut schedules = self.world.resource_mut::(); - - if let Some(default_schedule) = schedules.get_mut(&*self.default_schedule_label) { - default_schedule.add_systems(systems); - } else { - let schedule_label = &self.default_schedule_label; - panic!("Default schedule {schedule_label:?} does not exist.") - } - - self - } - - /// Adds a system to the provided [`Schedule`]. - pub fn add_system_to_schedule( - &mut self, - schedule_label: impl ScheduleLabel, - system: impl IntoSystemConfig, - ) -> &mut Self { - let mut schedules = self.world.resource_mut::(); - - if let Some(schedule) = schedules.get_mut(&schedule_label) { - schedule.add_system(system); - } else { - panic!("Provided schedule {schedule_label:?} does not exist.") - } - - self - } - - /// Adds a collection of system to the provided [`Schedule`]. - pub fn add_systems_to_schedule( - &mut self, - schedule_label: impl ScheduleLabel, - systems: impl IntoSystemConfigs, - ) -> &mut Self { + pub fn add_systems(&mut self, systems: impl IntoSystemAppConfigs) -> &mut Self { let mut schedules = self.world.resource_mut::(); - if let Some(schedule) = schedules.get_mut(&schedule_label) { - schedule.add_systems(systems); - } else { - panic!("Provided schedule {schedule_label:?} does not exist.") + match systems.into_app_configs().0 { + crate::InnerConfigs::Blanket { systems, schedule } => { + let schedule = if let Some(label) = schedule { + schedules + .get_mut(&*label) + .unwrap_or_else(|| panic!("Schedule '{label:?}' does not exist.")) + } else { + let label = &*self.default_schedule_label; + schedules + .get_mut(label) + .unwrap_or_else(|| panic!("Default schedule '{label:?}' does not exist.")) + }; + schedule.add_systems(systems); + } + crate::InnerConfigs::Granular(systems) => { + for system in systems { + self.add_system(system); + } + } } self @@ -472,7 +463,7 @@ impl App { /// .add_startup_system(my_startup_system); /// ``` pub fn add_startup_system(&mut self, system: impl IntoSystemConfig) -> &mut Self { - self.add_system_to_schedule(CoreSchedule::Startup, system) + self.add_system(system.in_schedule(CoreSchedule::Startup)) } /// Adds a collection of systems to [`CoreSchedule::Startup`]. @@ -497,7 +488,7 @@ impl App { /// ); /// ``` pub fn add_startup_systems(&mut self, systems: impl IntoSystemConfigs) -> &mut Self { - self.add_systems_to_schedule(CoreSchedule::Startup, systems) + self.add_systems(systems.into_configs().in_schedule(CoreSchedule::Startup)) } /// Configures a system set in the default schedule, adding the set if it does not exist. diff --git a/crates/bevy_app/src/config.rs b/crates/bevy_app/src/config.rs new file mode 100644 index 0000000000000..81d35f8574445 --- /dev/null +++ b/crates/bevy_app/src/config.rs @@ -0,0 +1,291 @@ +use bevy_ecs::{ + all_tuples, + schedule::{ + BoxedScheduleLabel, Condition, IntoSystemConfig, IntoSystemSet, ScheduleLabel, + SystemConfig, SystemConfigs, SystemSet, + }, +}; + +use crate::CoreSchedule; + +/// A [`System`] with [`App`]-aware scheduling metadata. +/// +/// [`System`]: bevy_ecs::prelude::System +/// [`App`]: crate::App +pub struct SystemAppConfig { + pub(crate) system: SystemConfig, + pub(crate) schedule: Option, +} + +/// Types that can be converted into a [`SystemAppConfig`]. +/// +/// This has been implemented for all `System` trait objects +/// and all functions that convert into such. +pub trait IntoSystemAppConfig: Sized { + /// Converts into a [`SystemAppConfig`]. + fn into_app_config(self) -> SystemAppConfig; + + /// Adds the system to the provided `schedule`. + /// + /// If a schedule is not specified, it will be added to the [`App`]'s default schedule. + /// + /// [`App`]: crate::App + /// + /// # Panics + /// + /// If the system has already been assigned to a schedule. + #[track_caller] + fn in_schedule(self, schedule: impl ScheduleLabel) -> SystemAppConfig { + let mut config = self.into_app_config(); + if let Some(old_schedule) = &config.schedule { + panic!( + "Cannot add system to schedule '{schedule:?}': it is already in '{old_schedule:?}'." + ); + } + config.schedule = Some(Box::new(schedule)); + + config + } + + /// Adds the system to [`CoreSchedule::Startup`]. + /// This is a shorthand for `self.in_schedule(CoreSchedule::Startup)`. + /// + /// Systems in this schedule will run exactly once, at the start of the [`App`]'s lifecycle. + /// + /// [`App`]: crate::App + /// + /// # Examples + /// + /// ``` + /// # use bevy_app::prelude::*; + /// # use bevy_ecs::prelude::*; + /// # + /// fn my_startup_system(_commands: Commands) { + /// println!("My startup system"); + /// } + /// + /// App::new() + /// .add_system(my_startup_system.on_startup()) + /// .run(); + /// ``` + /// + /// # Panics + /// + /// If the system has already been assigned to a schedule. + #[inline] + fn on_startup(self) -> SystemAppConfig { + self.in_schedule(CoreSchedule::Startup) + } +} + +impl IntoSystemConfig<(), Self> for SystemAppConfig { + fn into_config(self) -> Self { + self + } + + #[track_caller] + fn in_set(self, set: impl SystemSet) -> Self { + let Self { system, schedule } = self; + Self { + system: system.in_set(set), + schedule, + } + } + + #[track_caller] + fn in_base_set(self, set: impl SystemSet) -> Self { + let Self { system, schedule } = self; + Self { + system: system.in_base_set(set), + schedule, + } + } + + fn no_default_base_set(self) -> Self { + let Self { system, schedule } = self; + Self { + system: system.no_default_base_set(), + schedule, + } + } + + fn before(self, set: impl IntoSystemSet) -> Self { + let Self { system, schedule } = self; + Self { + system: system.before(set), + schedule, + } + } + + fn after(self, set: impl IntoSystemSet) -> Self { + let Self { system, schedule } = self; + Self { + system: system.after(set), + schedule, + } + } + + fn run_if

(self, condition: impl Condition

) -> Self { + let Self { system, schedule } = self; + Self { + system: system.run_if(condition), + schedule, + } + } + + fn ambiguous_with(self, set: impl IntoSystemSet) -> Self { + let Self { system, schedule } = self; + Self { + system: system.ambiguous_with(set), + schedule, + } + } + + fn ambiguous_with_all(self) -> Self { + let Self { system, schedule } = self; + Self { + system: system.ambiguous_with_all(), + schedule, + } + } +} + +impl IntoSystemAppConfig<()> for SystemAppConfig { + fn into_app_config(self) -> SystemAppConfig { + self + } +} + +impl IntoSystemAppConfig for T +where + T: IntoSystemConfig, +{ + fn into_app_config(self) -> SystemAppConfig { + SystemAppConfig { + system: self.into_config(), + schedule: None, + } + } +} + +/// A collection of [`SystemAppConfig`]s. +pub struct SystemAppConfigs(pub(crate) InnerConfigs); + +pub(crate) enum InnerConfigs { + /// This came from an instance of `SystemConfigs`. + /// All systems are in the same schedule. + Blanket { + systems: SystemConfigs, + schedule: Option, + }, + /// This came from several separate instances of `SystemAppConfig`. + /// Each system gets its own schedule. + Granular(Vec), +} + +/// Types that can convert into [`SystemAppConfigs`]. +pub trait IntoSystemAppConfigs: Sized { + /// Converts to [`SystemAppConfigs`]. + fn into_app_configs(self) -> SystemAppConfigs; + + /// Adds the systems to the provided `schedule`. + /// + /// If a schedule is not specified, they will be added to the [`App`]'s default schedule. + /// + /// [`App`]: crate::App + /// + /// # Panics + /// + /// If any of the systems have already been assigned to a schedule. + #[track_caller] + fn in_schedule(self, label: impl ScheduleLabel) -> SystemAppConfigs { + let mut configs = self.into_app_configs(); + + match &mut configs.0 { + InnerConfigs::Blanket { schedule, .. } => { + if schedule.is_some() { + panic!( + "Cannot add systems to the schedule '{label:?}: they are already in '{schedule:?}'" + ); + } + *schedule = Some(Box::new(label)); + } + InnerConfigs::Granular(configs) => { + for SystemAppConfig { schedule, .. } in configs { + if schedule.is_some() { + panic!( + "Cannot add system to the schedule '{label:?}': it is already in '{schedule:?}'." + ); + } + *schedule = Some(label.dyn_clone()); + } + } + } + + configs + } + + /// Adds the systems to [`CoreSchedule::Startup`]. + /// This is a shorthand for `self.in_schedule(CoreSchedule::Startup)`. + /// + /// # Examples + /// + /// ``` + /// # use bevy_app::prelude::*; + /// # use bevy_ecs::prelude::*; + /// # + /// # let mut app = App::new(); + /// # fn startup_system_a() {} + /// # fn startup_system_b() {} + /// # fn startup_system_c() {} + /// # + /// app.add_systems( + /// ( + /// startup_system_a, + /// startup_system_b, + /// startup_system_c, + /// ) + /// .on_startup() + /// ); + /// ``` + /// + /// # Panics + /// + /// If any of the systems have already been assigned to a schedule. + #[track_caller] + fn on_startup(self) -> SystemAppConfigs { + self.in_schedule(CoreSchedule::Startup) + } +} + +impl IntoSystemAppConfigs<()> for SystemAppConfigs { + fn into_app_configs(self) -> SystemAppConfigs { + self + } +} + +impl IntoSystemAppConfigs<()> for SystemConfigs { + fn into_app_configs(self) -> SystemAppConfigs { + SystemAppConfigs(InnerConfigs::Blanket { + systems: self, + schedule: None, + }) + } +} + +macro_rules! impl_system_collection { + ($(($param: ident, $sys: ident)),*) => { + impl<$($param, $sys),*> IntoSystemAppConfigs<($($param,)*)> for ($($sys,)*) + where + $($sys: IntoSystemAppConfig<$param>),* + { + #[allow(non_snake_case)] + fn into_app_configs(self) -> SystemAppConfigs { + let ($($sys,)*) = self; + SystemAppConfigs(InnerConfigs::Granular(vec![$($sys.into_app_config(),)*])) + } + } + } +} + +all_tuples!(impl_system_collection, 0, 15, P, S); diff --git a/crates/bevy_app/src/lib.rs b/crates/bevy_app/src/lib.rs index f03856aa18e45..8348a7c16e15e 100644 --- a/crates/bevy_app/src/lib.rs +++ b/crates/bevy_app/src/lib.rs @@ -3,6 +3,7 @@ #![warn(missing_docs)] mod app; +mod config; mod plugin; mod plugin_group; mod schedule_runner; @@ -12,6 +13,7 @@ mod ci_testing; pub use app::*; pub use bevy_derive::DynamicPlugin; +pub use config::*; pub use plugin::*; pub use plugin_group::*; pub use schedule_runner::*; @@ -23,7 +25,9 @@ pub mod prelude { pub use crate::AppTypeRegistry; #[doc(hidden)] pub use crate::{ - app::App, CoreSchedule, CoreSet, DynamicPlugin, Plugin, PluginGroup, StartupSet, + app::App, + config::{IntoSystemAppConfig, IntoSystemAppConfigs}, + CoreSchedule, CoreSet, DynamicPlugin, Plugin, PluginGroup, StartupSet, }; } diff --git a/crates/bevy_core_pipeline/src/core_2d/mod.rs b/crates/bevy_core_pipeline/src/core_2d/mod.rs index f02c78cf6d0f6..233671a159ab0 100644 --- a/crates/bevy_core_pipeline/src/core_2d/mod.rs +++ b/crates/bevy_core_pipeline/src/core_2d/mod.rs @@ -19,7 +19,7 @@ pub mod graph { pub use camera_2d::*; pub use main_pass_2d_node::*; -use bevy_app::{App, Plugin}; +use bevy_app::{App, IntoSystemAppConfig, Plugin}; use bevy_ecs::prelude::*; use bevy_render::{ camera::Camera, @@ -51,7 +51,7 @@ impl Plugin for Core2dPlugin { render_app .init_resource::>() - .add_system_to_schedule(ExtractSchedule, extract_core_2d_camera_phases) + .add_system(extract_core_2d_camera_phases.in_schedule(ExtractSchedule)) .add_system(sort_phase_system::.in_set(RenderSet::PhaseSort)) .add_system( batch_phase_system:: diff --git a/crates/bevy_core_pipeline/src/core_3d/mod.rs b/crates/bevy_core_pipeline/src/core_3d/mod.rs index 98042adcee5ee..ab3f68df20904 100644 --- a/crates/bevy_core_pipeline/src/core_3d/mod.rs +++ b/crates/bevy_core_pipeline/src/core_3d/mod.rs @@ -22,7 +22,7 @@ use std::cmp::Reverse; pub use camera_3d::*; pub use main_pass_3d_node::*; -use bevy_app::{App, Plugin}; +use bevy_app::{App, IntoSystemAppConfig, Plugin}; use bevy_ecs::prelude::*; use bevy_render::{ camera::{Camera, ExtractedCamera}, @@ -67,7 +67,7 @@ impl Plugin for Core3dPlugin { .init_resource::>() .init_resource::>() .init_resource::>() - .add_system_to_schedule(ExtractSchedule, extract_core_3d_camera_phases) + .add_system(extract_core_3d_camera_phases.in_schedule(ExtractSchedule)) .add_system( prepare_core_3d_depth_textures .in_set(RenderSet::Prepare) diff --git a/crates/bevy_ecs/src/schedule/config.rs b/crates/bevy_ecs/src/schedule/config.rs index 54f68a8167e05..7c0524a094432 100644 --- a/crates/bevy_ecs/src/schedule/config.rs +++ b/crates/bevy_ecs/src/schedule/config.rs @@ -80,7 +80,7 @@ fn ambiguous_with(graph_info: &mut GraphInfo, set: BoxedSystemSet) { /// Types that can be converted into a [`SystemSetConfig`]. /// /// This has been implemented for all types that implement [`SystemSet`] and boxed trait objects. -pub trait IntoSystemSetConfig: sealed::IntoSystemSetConfig { +pub trait IntoSystemSetConfig { /// Convert into a [`SystemSetConfig`]. #[doc(hidden)] fn into_config(self) -> SystemSetConfig; @@ -109,10 +109,7 @@ pub trait IntoSystemSetConfig: sealed::IntoSystemSetConfig { fn ambiguous_with_all(self) -> SystemSetConfig; } -impl IntoSystemSetConfig for S -where - S: SystemSet + sealed::IntoSystemSetConfig, -{ +impl IntoSystemSetConfig for S { fn into_config(self) -> SystemSetConfig { SystemSetConfig::new(Box::new(self)) } @@ -274,38 +271,38 @@ impl IntoSystemSetConfig for SystemSetConfig { /// /// This has been implemented for boxed [`System`](crate::system::System) /// trait objects and all functions that turn into such. -pub trait IntoSystemConfig: sealed::IntoSystemConfig { +pub trait IntoSystemConfig { /// Convert into a [`SystemConfig`]. #[doc(hidden)] - fn into_config(self) -> SystemConfig; + fn into_config(self) -> Config; /// Add to `set` membership. #[track_caller] - fn in_set(self, set: impl SystemSet) -> SystemConfig; + fn in_set(self, set: impl SystemSet) -> Config; /// 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; + fn in_base_set(self, set: impl SystemSet) -> Config; /// Don't add this system to the schedules's default set. - fn no_default_base_set(self) -> SystemConfig; + fn no_default_base_set(self) -> Config; /// Run before all systems in `set`. - fn before(self, set: impl IntoSystemSet) -> SystemConfig; + fn before(self, set: impl IntoSystemSet) -> Config; /// Run after all systems in `set`. - fn after(self, set: impl IntoSystemSet) -> SystemConfig; + fn after(self, set: impl IntoSystemSet) -> Config; /// Run only if the [`Condition`] is `true`. /// /// The `Condition` will be evaluated at most once (per schedule run), /// when the system prepares to run. - fn run_if(self, condition: impl Condition) -> SystemConfig; + fn run_if(self, condition: impl Condition) -> Config; /// Suppress warnings and errors that would result from this system having ambiguities /// (conflicting access but indeterminate order) with systems in `set`. - fn ambiguous_with(self, set: impl IntoSystemSet) -> SystemConfig; + fn ambiguous_with(self, set: impl IntoSystemSet) -> Config; /// Suppress warnings and errors that would result from this system having ambiguities /// (conflicting access but indeterminate order) with any other system. - fn ambiguous_with_all(self) -> SystemConfig; + fn ambiguous_with_all(self) -> Config; } impl IntoSystemConfig for F where - F: IntoSystem<(), (), Marker> + sealed::IntoSystemConfig, + F: IntoSystem<(), (), Marker>, { fn into_config(self) -> SystemConfig { SystemConfig::new(Box::new(IntoSystem::into_system(self))) @@ -456,32 +453,6 @@ impl IntoSystemConfig<()> for SystemConfig { } } -// only `System` system objects can be scheduled -mod sealed { - use crate::{ - schedule::{BoxedSystemSet, SystemSet}, - system::{BoxedSystem, IntoSystem}, - }; - - use super::{SystemConfig, SystemSetConfig}; - - pub trait IntoSystemConfig {} - - impl> IntoSystemConfig for F {} - - impl IntoSystemConfig<()> for BoxedSystem<(), ()> {} - - impl IntoSystemConfig<()> for SystemConfig {} - - pub trait IntoSystemSetConfig {} - - impl IntoSystemSetConfig for S {} - - impl IntoSystemSetConfig for BoxedSystemSet {} - - impl IntoSystemSetConfig for SystemSetConfig {} -} - /// A collection of [`SystemConfig`]. pub struct SystemConfigs { pub(super) systems: Vec, diff --git a/crates/bevy_pbr/src/lib.rs b/crates/bevy_pbr/src/lib.rs index 7635dc1b8ff73..884b08a423ac7 100644 --- a/crates/bevy_pbr/src/lib.rs +++ b/crates/bevy_pbr/src/lib.rs @@ -268,12 +268,12 @@ impl Plugin for PbrPlugin { .configure_set(RenderLightSystems::PrepareLights.in_set(RenderSet::Prepare)) .configure_set(RenderLightSystems::PrepareClusters.in_set(RenderSet::Prepare)) .configure_set(RenderLightSystems::QueueShadows.in_set(RenderSet::Queue)) - .add_systems_to_schedule( - ExtractSchedule, + .add_systems( ( render::extract_clusters.in_set(RenderLightSystems::ExtractClusters), render::extract_lights.in_set(RenderLightSystems::ExtractLights), - ), + ) + .in_schedule(ExtractSchedule), ) .add_system( render::prepare_lights diff --git a/crates/bevy_pbr/src/material.rs b/crates/bevy_pbr/src/material.rs index 410b702c4933e..7ab25bdd9d553 100644 --- a/crates/bevy_pbr/src/material.rs +++ b/crates/bevy_pbr/src/material.rs @@ -2,7 +2,7 @@ use crate::{ AlphaMode, DrawMesh, EnvironmentMapLight, MeshPipeline, MeshPipelineKey, MeshUniform, PrepassPlugin, SetMeshBindGroup, SetMeshViewBindGroup, }; -use bevy_app::{App, Plugin}; +use bevy_app::{App, IntoSystemAppConfig, Plugin}; use bevy_asset::{AddAsset, AssetEvent, AssetServer, Assets, Handle}; use bevy_core_pipeline::{ core_3d::{AlphaMask3d, Opaque3d, Transparent3d}, @@ -195,7 +195,7 @@ where .init_resource::>() .init_resource::>() .init_resource::>>() - .add_system_to_schedule(ExtractSchedule, extract_materials::) + .add_system(extract_materials::.in_schedule(ExtractSchedule)) .add_system( prepare_materials:: .in_set(RenderSet::Prepare) diff --git a/crates/bevy_pbr/src/prepass/mod.rs b/crates/bevy_pbr/src/prepass/mod.rs index f4f75f7a04b99..9f63d7b9ff4ea 100644 --- a/crates/bevy_pbr/src/prepass/mod.rs +++ b/crates/bevy_pbr/src/prepass/mod.rs @@ -1,4 +1,4 @@ -use bevy_app::Plugin; +use bevy_app::{IntoSystemAppConfig, Plugin}; use bevy_asset::{load_internal_asset, AssetServer, Handle, HandleUntyped}; use bevy_core_pipeline::{ prelude::Camera3d, @@ -97,7 +97,7 @@ where }; render_app - .add_system_to_schedule(ExtractSchedule, extract_camera_prepass_phase) + .add_system(extract_camera_prepass_phase.in_schedule(ExtractSchedule)) .add_system( prepare_prepass_textures .in_set(RenderSet::Prepare) diff --git a/crates/bevy_pbr/src/render/mesh.rs b/crates/bevy_pbr/src/render/mesh.rs index 0b4f5463eb758..477e29795014a 100644 --- a/crates/bevy_pbr/src/render/mesh.rs +++ b/crates/bevy_pbr/src/render/mesh.rs @@ -5,7 +5,7 @@ use crate::{ ViewShadowBindings, CLUSTERED_FORWARD_STORAGE_BUFFER_COUNT, MAX_CASCADES_PER_LIGHT, MAX_DIRECTIONAL_LIGHTS, }; -use bevy_app::Plugin; +use bevy_app::{IntoSystemAppConfigs, Plugin}; use bevy_asset::{load_internal_asset, Assets, Handle, HandleUntyped}; use bevy_core_pipeline::{ prepass::ViewPrepassTextures, @@ -108,7 +108,7 @@ impl Plugin for MeshRenderPlugin { render_app .init_resource::() .init_resource::() - .add_systems_to_schedule(ExtractSchedule, (extract_meshes, extract_skinned_meshes)) + .add_systems((extract_meshes, extract_skinned_meshes).in_schedule(ExtractSchedule)) .add_system(prepare_skinned_meshes.in_set(RenderSet::Prepare)) .add_system(queue_mesh_bind_group.in_set(RenderSet::Queue)) .add_system( diff --git a/crates/bevy_render/src/camera/mod.rs b/crates/bevy_render/src/camera/mod.rs index cdd26a36c638a..e1639a348f991 100644 --- a/crates/bevy_render/src/camera/mod.rs +++ b/crates/bevy_render/src/camera/mod.rs @@ -8,7 +8,7 @@ pub use camera_driver_node::*; pub use projection::*; use crate::{render_graph::RenderGraph, ExtractSchedule, RenderApp}; -use bevy_app::{App, Plugin}; +use bevy_app::{App, IntoSystemAppConfig, Plugin}; #[derive(Default)] pub struct CameraPlugin; @@ -26,7 +26,7 @@ impl Plugin for CameraPlugin { .add_plugin(CameraProjectionPlugin::::default()); if let Ok(render_app) = app.get_sub_app_mut(RenderApp) { - render_app.add_system_to_schedule(ExtractSchedule, extract_cameras); + render_app.add_system(extract_cameras.in_schedule(ExtractSchedule)); let camera_driver_node = CameraDriverNode::new(&mut render_app.world); let mut render_graph = render_app.world.resource_mut::(); render_graph.add_node(crate::main_graph::node::CAMERA_DRIVER, camera_driver_node); diff --git a/crates/bevy_render/src/extract_component.rs b/crates/bevy_render/src/extract_component.rs index 6f6241a59ebcb..2b70a897a16fc 100644 --- a/crates/bevy_render/src/extract_component.rs +++ b/crates/bevy_render/src/extract_component.rs @@ -4,7 +4,7 @@ use crate::{ view::ComputedVisibility, Extract, ExtractSchedule, RenderApp, RenderSet, }; -use bevy_app::{App, Plugin}; +use bevy_app::{App, IntoSystemAppConfig, Plugin}; use bevy_asset::{Asset, Handle}; use bevy_ecs::{ component::Component, @@ -180,9 +180,9 @@ impl Plugin for ExtractComponentPlugin { fn build(&self, app: &mut App) { if let Ok(render_app) = app.get_sub_app_mut(RenderApp) { if self.only_extract_visible { - render_app.add_system_to_schedule(ExtractSchedule, extract_visible_components::); + render_app.add_system(extract_visible_components::.in_schedule(ExtractSchedule)); } else { - render_app.add_system_to_schedule(ExtractSchedule, extract_components::); + render_app.add_system(extract_components::.in_schedule(ExtractSchedule)); } } } diff --git a/crates/bevy_render/src/extract_resource.rs b/crates/bevy_render/src/extract_resource.rs index 65b3d954fbb15..a1e8b122f0857 100644 --- a/crates/bevy_render/src/extract_resource.rs +++ b/crates/bevy_render/src/extract_resource.rs @@ -1,6 +1,6 @@ use std::marker::PhantomData; -use bevy_app::{App, Plugin}; +use bevy_app::{App, IntoSystemAppConfig, Plugin}; use bevy_ecs::prelude::*; pub use bevy_render_macros::ExtractResource; @@ -32,7 +32,7 @@ impl Default for ExtractResourcePlugin { impl Plugin for ExtractResourcePlugin { fn build(&self, app: &mut App) { if let Ok(render_app) = app.get_sub_app_mut(RenderApp) { - render_app.add_system_to_schedule(ExtractSchedule, extract_resource::); + render_app.add_system(extract_resource::.in_schedule(ExtractSchedule)); } } } diff --git a/crates/bevy_render/src/globals.rs b/crates/bevy_render/src/globals.rs index 474defa802e1b..6b9fbdbc7f3d2 100644 --- a/crates/bevy_render/src/globals.rs +++ b/crates/bevy_render/src/globals.rs @@ -5,7 +5,7 @@ use crate::{ renderer::{RenderDevice, RenderQueue}, Extract, ExtractSchedule, RenderApp, RenderSet, }; -use bevy_app::{App, Plugin}; +use bevy_app::{App, IntoSystemAppConfigs, Plugin}; use bevy_asset::{load_internal_asset, HandleUntyped}; use bevy_core::FrameCount; use bevy_ecs::prelude::*; @@ -26,7 +26,7 @@ impl Plugin for GlobalsPlugin { render_app .init_resource::() .init_resource::