diff --git a/Cargo.toml b/Cargo.toml index 927119ccaa15a..778482e3d9d57 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2005,12 +2005,12 @@ category = "Window" wasm = true [[example]] -name = "low_power" -path = "examples/window/low_power.rs" +name = "run_control" +path = "examples/window/run_control.rs" -[package.metadata.example.low_power] -name = "Low Power" -description = "Demonstrates settings to reduce power use for bevy applications" +[package.metadata.example.run_control] +name = "Run Control" +description = "Demonstration of controlling the run of an application" category = "Window" wasm = true diff --git a/benches/benches/bevy_ecs/scheduling/schedule.rs b/benches/benches/bevy_ecs/scheduling/schedule.rs index e670c23d74b37..1e8b01aae4576 100644 --- a/benches/benches/bevy_ecs/scheduling/schedule.rs +++ b/benches/benches/bevy_ecs/scheduling/schedule.rs @@ -85,7 +85,7 @@ pub fn build_schedule(criterion: &mut Criterion) { for _ in 0..graph_size { app.add_systems(Update, empty_system); } - app.update(); + app.world.run_schedule(Update); }); }); @@ -111,7 +111,7 @@ pub fn build_schedule(criterion: &mut Criterion) { // This is necessary since dependency resolution does not occur until the game runs. // FIXME: Running the game clutters up the benchmarks, so ideally we'd be // able to benchmark the dependency resolution directly. - app.update(); + app.world.run_schedule(Update); }); }); } diff --git a/crates/bevy_app/src/app.rs b/crates/bevy_app/src/app.rs index aff7afe904c7c..dca7e92dfc6b9 100644 --- a/crates/bevy_app/src/app.rs +++ b/crates/bevy_app/src/app.rs @@ -1,4 +1,6 @@ -use crate::{First, Main, MainSchedulePlugin, Plugin, Plugins, Startup, StateTransition, Update}; +use crate::{ + First, MainSchedulePlugin, Plugin, Plugins, Startup, StateTransition, Update, UpdateFlow, +}; pub use bevy_derive::AppLabel; use bevy_ecs::{ prelude::*, @@ -64,13 +66,12 @@ pub struct App { /// the application's event loop and advancing the [`Schedule`]. /// Typically, it is not configured manually, but set by one of Bevy's built-in plugins. /// See `bevy::winit::WinitPlugin` and [`ScheduleRunnerPlugin`](crate::schedule_runner::ScheduleRunnerPlugin). - pub runner: Box, // Send bound is required to make App Send - /// The schedule that systems are added to by default. /// - /// The schedule that runs the main loop of schedule execution. + /// # Note /// - /// This is initially set to [`Main`]. - pub main_schedule_label: BoxedScheduleLabel, + /// Inside the runner function, `World::clear_trackers()` must be called periodically. + /// If that isn't called on a world, it may lead to memory leaks in `RemovedComponents`. + pub runner: Box, sub_apps: HashMap, plugin_registry: Vec>, plugin_name_added: HashSet, @@ -95,7 +96,7 @@ impl Debug for App { /// # Example /// /// ```rust -/// # use bevy_app::{App, AppLabel, SubApp, Main}; +/// # use bevy_app::{App, AppLabel, SubApp, UpdateFlow}; /// # use bevy_ecs::prelude::*; /// # use bevy_ecs::schedule::ScheduleLabel; /// @@ -116,7 +117,7 @@ impl Debug for App { /// sub_app.insert_resource(Val(100)); /// /// // initialize main schedule -/// sub_app.add_systems(Main, |counter: Res| { +/// sub_app.add_systems(UpdateFlow, |counter: Res| { /// // since we assigned the value from the main world in extract /// // we see that value instead of 100 /// assert_eq!(counter.0, 10); @@ -135,28 +136,34 @@ pub struct SubApp { /// The [`SubApp`]'s instance of [`App`] pub app: App, + /// The schedule to run by default. + /// + /// This is initially set to [`UpdateFlow`]. + pub main_schedule_label: BoxedScheduleLabel, + /// A function that allows access to both the main [`App`] [`World`] and the [`SubApp`]. This is /// useful for moving data between the sub app and the main app. - extract: Box, + extract: Box, } impl SubApp { /// Creates a new [`SubApp`]. /// - /// The provided function `extract` is normally called by the [`update`](App::update) method. + /// The provided function `extract` is normally called by the [`run_schedule`](World::run_schedule) method. /// After extract is called, the [`Schedule`] of the sub app is run. The [`World`] /// parameter represents the main app world, while the [`App`] parameter is just a mutable /// reference to the `SubApp` itself. - pub fn new(app: App, extract: impl Fn(&mut World, &mut App) + Send + 'static) -> Self { + pub fn new(app: App, extract: impl Fn(&mut World, &mut App) + Send + Sync + 'static) -> Self { Self { app, + main_schedule_label: Box::new(UpdateFlow), extract: Box::new(extract), } } /// Runs the [`SubApp`]'s default schedule. pub fn run(&mut self) { - self.app.world.run_schedule(&*self.app.main_schedule_label); + self.app.world.run_schedule(&*self.main_schedule_label); self.app.world.clear_trackers(); } @@ -219,38 +226,19 @@ impl App { sub_apps: HashMap::default(), plugin_registry: Vec::default(), plugin_name_added: Default::default(), - main_schedule_label: Box::new(Main), building_plugin_depth: 0, } } - /// Advances the execution of the [`Schedule`] by one cycle. - /// - /// This method also updates sub apps. + /// Update sub apps. /// See [`insert_sub_app`](Self::insert_sub_app) for more details. - /// - /// The schedule run by this method is determined by the [`main_schedule_label`](App) field. - /// By default this is [`Main`]. - /// - /// # Panics - /// - /// The active schedule of the app must be set before this method is called. - pub fn update(&mut self) { - #[cfg(feature = "trace")] - let _bevy_update_span = info_span!("update").entered(); - { - #[cfg(feature = "trace")] - let _bevy_main_update_span = info_span!("main app").entered(); - self.world.run_schedule(&*self.main_schedule_label); - } + pub fn update_sub_apps(&mut self) { for (_label, sub_app) in self.sub_apps.iter_mut() { #[cfg(feature = "trace")] let _sub_app_span = info_span!("sub app", name = ?_label).entered(); sub_app.extract(&mut self.world); sub_app.run(); } - - self.world.clear_trackers(); } /// Starts the application by calling the app's [runner function](Self::set_runner). @@ -293,7 +281,7 @@ impl App { } /// Check that [`Plugin::ready`] of all plugins returns true. This is usually called by the - /// event loop, but can be useful for situations where you want to use [`App::update`] + /// event loop, but can be useful for situations where you want to no use [`App::run`] pub fn ready(&self) -> bool { for plugin in &self.plugin_registry { if !plugin.ready(self) { @@ -304,8 +292,8 @@ impl App { } /// Run [`Plugin::finish`] for each plugin. This is usually called by the event loop once all - /// plugins are [`App::ready`], but can be useful for situations where you want to use - /// [`App::update`]. + /// plugins are [`App::ready`], but can be useful for situations where you want to no use + /// [`App::run`]. pub fn finish(&mut self) { // temporarily remove the plugin registry to run each plugin's setup function on app. let plugin_registry = std::mem::take(&mut self.plugin_registry); @@ -316,7 +304,7 @@ impl App { } /// Run [`Plugin::cleanup`] for each plugin. This is usually called by the event loop after - /// [`App::finish`], but can be useful for situations where you want to use [`App::update`]. + /// [`App::finish`], but can be useful for situations where you want to no use [`App::run`]. pub fn cleanup(&mut self) { // temporarily remove the plugin registry to run each plugin's setup function on app. let plugin_registry = std::mem::take(&mut self.plugin_registry); @@ -636,6 +624,11 @@ impl App { /// The runner function is usually not set manually, but by Bevy integrated plugins /// (e.g. `WinitPlugin`). /// + /// # Note + /// + /// Inside the runner function, `World::clear_trackers()` must be called periodically. + /// If that isn't called on a world, it may lead to memory leaks in `RemovedComponents`. + /// /// # Examples /// /// ``` @@ -644,14 +637,14 @@ impl App { /// fn my_runner(mut app: App) { /// loop { /// println!("In main loop"); - /// app.update(); + /// app.world.run_schedule(UpdateFlow); /// } /// } /// /// App::new() /// .set_runner(my_runner); /// ``` - pub fn set_runner(&mut self, run_fn: impl Fn(App) + 'static + Send) -> &mut Self { + pub fn set_runner(&mut self, run_fn: impl FnOnce(App) + 'static + Send + Sync) -> &mut Self { self.runner = Box::new(run_fn); self } @@ -970,7 +963,12 @@ fn run_once(mut app: App) { app.finish(); app.cleanup(); - app.update(); + { + #[cfg(feature = "trace")] + let _ = info_span!("run top schedule", name = ?UpdateFlow).entered(); + app.world.run_schedule(UpdateFlow); + } + app.update_sub_apps(); } /// An event that indicates the [`App`] should exit. This will fully exit the app process at the diff --git a/crates/bevy_app/src/lib.rs b/crates/bevy_app/src/lib.rs index 1941392ee0194..e804c1b222c81 100644 --- a/crates/bevy_app/src/lib.rs +++ b/crates/bevy_app/src/lib.rs @@ -25,8 +25,8 @@ pub mod prelude { pub use crate::{ app::App, main_schedule::{ - First, FixedUpdate, Last, Main, PostStartup, PostUpdate, PreStartup, PreUpdate, - Startup, StateTransition, Update, + Control, First, FixedUpdate, FrameReady, Last, PostStartup, PostUpdate, PreStartup, + PreUpdate, RenderFlow, Startup, StartupFlow, StateTransition, Update, UpdateFlow, }, DynamicPlugin, Plugin, PluginGroup, }; diff --git a/crates/bevy_app/src/main_schedule.rs b/crates/bevy_app/src/main_schedule.rs index c940fda5337b9..d25b4142ecdf8 100644 --- a/crates/bevy_app/src/main_schedule.rs +++ b/crates/bevy_app/src/main_schedule.rs @@ -1,48 +1,48 @@ use crate::{App, Plugin}; use bevy_ecs::{ schedule::{ExecutorKind, Schedule, ScheduleLabel}, - system::{Local, Resource}, + system::Resource, world::{Mut, World}, }; -/// The schedule that contains the app logic that is evaluated each tick of [`App::update()`]. -/// -/// By default, it will run the following schedules in the given order: -/// /// On the first run of the schedule (and only on the first run), it will run: /// * [`PreStartup`] /// * [`Startup`] /// * [`PostStartup`] -/// -/// Then it will run: -/// * [`First`] -/// * [`PreUpdate`] -/// * [`StateTransition`] -/// * [`RunFixedUpdateLoop`] -/// * This will run [`FixedUpdate`] zero to many times, based on how much time has elapsed. -/// * [`Update`] -/// * [`PostUpdate`] -/// * [`Last`] #[derive(ScheduleLabel, Clone, Debug, PartialEq, Eq, Hash)] -pub struct Main; +pub struct StartupFlow; /// The schedule that runs before [`Startup`]. -/// This is run by the [`Main`] schedule. +/// This is run by the [`StartupFlow`] schedule. #[derive(ScheduleLabel, Clone, Debug, PartialEq, Eq, Hash)] pub struct PreStartup; /// The schedule that runs once when the app starts. -/// This is run by the [`Main`] schedule. +/// This is run by the [`StartupFlow`] schedule. #[derive(ScheduleLabel, Clone, Debug, PartialEq, Eq, Hash)] pub struct Startup; /// The schedule that runs once after [`Startup`]. -/// This is run by the [`Main`] schedule. +/// This is run by the [`StartupFlow`] schedule. #[derive(ScheduleLabel, Clone, Debug, PartialEq, Eq, Hash)] pub struct PostStartup; +/// The schedule that contains the app logic that is evaluated each tick of event loop. +/// +/// By default, it will run the following schedules in the given order: +/// * [`First`] +/// * [`PreUpdate`] +/// * [`StateTransition`] +/// * [`RunFixedUpdateLoop`] +/// * This will run [`FixedUpdate`] zero to many times, based on how much time has elapsed. +/// * [`Update`] +/// * [`PostUpdate`] +/// * [`Last`] +#[derive(ScheduleLabel, Clone, Debug, PartialEq, Eq, Hash)] +pub struct UpdateFlow; + /// Runs first in the schedule. -/// This is run by the [`Main`] schedule. +/// This is run by the [`UpdateFlow`] schedule. #[derive(ScheduleLabel, Clone, Debug, PartialEq, Eq, Hash)] pub struct First; @@ -53,17 +53,17 @@ pub struct First; /// [`PreUpdate`] exists to do "engine/plugin preparation work" that ensures the APIs consumed in [`Update`] are "ready". /// [`PreUpdate`] abstracts out "pre work implementation details". /// -/// This is run by the [`Main`] schedule. +/// This is run by the [`UpdateFlow`] schedule. #[derive(ScheduleLabel, Clone, Debug, PartialEq, Eq, Hash)] pub struct PreUpdate; /// Runs [state transitions](bevy_ecs::schedule::States). -/// This is run by the [`Main`] schedule. +/// This is run by the [`UpdateFlow`] schedule. #[derive(ScheduleLabel, Clone, Debug, PartialEq, Eq, Hash)] pub struct StateTransition; /// Runs the [`FixedUpdate`] schedule in a loop according until all relevant elapsed time has been "consumed". -/// This is run by the [`Main`] schedule. +/// This is run by the [`UpdateFlow`] schedule. #[derive(ScheduleLabel, Clone, Debug, PartialEq, Eq, Hash)] pub struct RunFixedUpdateLoop; @@ -75,7 +75,7 @@ pub struct RunFixedUpdateLoop; pub struct FixedUpdate; /// The schedule that contains app logic. -/// This is run by the [`Main`] schedule. +/// This is run by the [`UpdateFlow`] schedule. #[derive(ScheduleLabel, Clone, Debug, PartialEq, Eq, Hash)] pub struct Update; @@ -86,24 +86,38 @@ pub struct Update; /// [`PostUpdate`] exists to do "engine/plugin response work" to things that happened in [`Update`]. /// [`PostUpdate`] abstracts out "implementation details" from users defining systems in [`Update`]. /// -/// This is run by the [`Main`] schedule. +/// This is run by the [`UpdateFlow`] schedule. #[derive(ScheduleLabel, Clone, Debug, PartialEq, Eq, Hash)] pub struct PostUpdate; /// Runs last in the schedule. -/// This is run by the [`Main`] schedule. +/// This is run by the [`UpdateFlow`] schedule. #[derive(ScheduleLabel, Clone, Debug, PartialEq, Eq, Hash)] pub struct Last; -/// Defines the schedules to be run for the [`Main`] schedule, including +/// Each time an event is received from windows and devices, this schedule is run. +/// This is useful for responding to events regardless of whether tick updates take place. +#[derive(ScheduleLabel, Clone, Debug, PartialEq, Eq, Hash)] +pub struct Control; + +/// Each time a frame is ready to be updated, this schedule is run. +/// This is the best place to decide whether to redraw. +#[derive(ScheduleLabel, Clone, Debug, PartialEq, Eq, Hash)] +pub struct FrameReady; + +/// The schedule that builds and sends drawing queries to the GPU. +#[derive(ScheduleLabel, Debug, Hash, PartialEq, Eq, Clone)] +pub struct RenderFlow; + +/// Defines the schedules to be run for the [`UpdateFlow`] schedule, including /// their order. #[derive(Resource, Debug)] -pub struct MainScheduleOrder { - /// The labels to run for the [`Main`] schedule (in the order they will be run). +pub struct UpdateFlowOrder { + /// The labels to run for the [`UpdateFlow`] schedule (in the order they will be run). pub labels: Vec>, } -impl Default for MainScheduleOrder { +impl Default for UpdateFlowOrder { fn default() -> Self { Self { labels: vec![ @@ -119,7 +133,7 @@ impl Default for MainScheduleOrder { } } -impl MainScheduleOrder { +impl UpdateFlowOrder { /// Adds the given `schedule` after the `after` schedule pub fn insert_after(&mut self, after: impl ScheduleLabel, schedule: impl ScheduleLabel) { let index = self @@ -131,17 +145,20 @@ impl MainScheduleOrder { } } -impl Main { - /// A system that runs the "main schedule" - pub fn run_main(world: &mut World, mut run_at_least_once: Local) { - if !*run_at_least_once { - let _ = world.try_run_schedule(PreStartup); - let _ = world.try_run_schedule(Startup); - let _ = world.try_run_schedule(PostStartup); - *run_at_least_once = true; - } +/// Initializes the [`StartupFlow`] schedule, [`UpdateFlow`] schedule, sub schedules, and resources for a given [`App`]. +pub struct MainSchedulePlugin; - world.resource_scope(|world, order: Mut| { +impl MainSchedulePlugin { + /// A system that runs the `StartupFlow` sub schedules + pub fn run_startup(world: &mut World) { + let _ = world.try_run_schedule(PreStartup); + let _ = world.try_run_schedule(Startup); + let _ = world.try_run_schedule(PostStartup); + } + + /// A system that runs the `UpdateFlow` sub schedules + pub fn run_update(world: &mut World) { + world.resource_scope(|world, order: Mut| { for label in &order.labels { let _ = world.try_run_schedule(&**label); } @@ -149,20 +166,21 @@ impl Main { } } -/// Initializes the [`Main`] schedule, sub schedules, and resources for a given [`App`]. -pub struct MainSchedulePlugin; - impl Plugin for MainSchedulePlugin { fn build(&self, app: &mut App) { // simple "facilitator" schedules benefit from simpler single threaded scheduling - let mut main_schedule = Schedule::new(); - main_schedule.set_executor_kind(ExecutorKind::SingleThreaded); + let mut startup_schedule = Schedule::new(); + startup_schedule.set_executor_kind(ExecutorKind::SingleThreaded); + let mut update_schedule = Schedule::new(); + update_schedule.set_executor_kind(ExecutorKind::SingleThreaded); let mut fixed_update_loop_schedule = Schedule::new(); fixed_update_loop_schedule.set_executor_kind(ExecutorKind::SingleThreaded); - app.add_schedule(Main, main_schedule) + app.add_schedule(StartupFlow, startup_schedule) + .add_schedule(UpdateFlow, update_schedule) .add_schedule(RunFixedUpdateLoop, fixed_update_loop_schedule) - .init_resource::() - .add_systems(Main, Main::run_main); + .init_resource::() + .add_systems(StartupFlow, Self::run_startup) + .add_systems(UpdateFlow, Self::run_update); } } diff --git a/crates/bevy_app/src/schedule_runner.rs b/crates/bevy_app/src/schedule_runner.rs index c143f75c42f53..927c7812352d2 100644 --- a/crates/bevy_app/src/schedule_runner.rs +++ b/crates/bevy_app/src/schedule_runner.rs @@ -1,10 +1,17 @@ use crate::{ app::{App, AppExit}, plugin::Plugin, + StartupFlow, UpdateFlow, +}; +use bevy_ecs::{ + event::{Events, ManualEventReader}, + schedule::BoxedScheduleLabel, }; -use bevy_ecs::event::{Events, ManualEventReader}; use bevy_utils::{Duration, Instant}; +#[cfg(feature = "trace")] +use bevy_utils::tracing::info_span; + #[cfg(target_arch = "wasm32")] use std::{cell::RefCell, rc::Rc}; #[cfg(target_arch = "wasm32")] @@ -43,10 +50,17 @@ impl Default for RunMode { /// typically, the `winit` event loop /// (see [`WinitPlugin`](https://docs.rs/bevy/latest/bevy/winit/struct.WinitPlugin.html)) /// executes the schedule making [`ScheduleRunnerPlugin`] unnecessary. -#[derive(Default)] pub struct ScheduleRunnerPlugin { /// Determines whether the [`Schedule`](bevy_ecs::schedule::Schedule) is run once or repeatedly. pub run_mode: RunMode, + /// This schedule is run only once at startup. + /// + /// The default is [`StartupFlow`]. + pub startup_schedule_label: BoxedScheduleLabel, + /// This schedule is run for each tick. + /// + /// The default is [`UpdateFlow`]. + pub update_schedule_label: BoxedScheduleLabel, } impl ScheduleRunnerPlugin { @@ -54,6 +68,7 @@ impl ScheduleRunnerPlugin { pub fn run_once() -> Self { ScheduleRunnerPlugin { run_mode: RunMode::Once, + ..Default::default() } } @@ -63,6 +78,17 @@ impl ScheduleRunnerPlugin { run_mode: RunMode::Loop { wait: Some(wait_duration), }, + ..Default::default() + } + } +} + +impl Default for ScheduleRunnerPlugin { + fn default() -> Self { + ScheduleRunnerPlugin { + run_mode: RunMode::Loop { wait: None }, + startup_schedule_label: Box::new(StartupFlow), + update_schedule_label: Box::new(UpdateFlow), } } } @@ -70,11 +96,29 @@ impl ScheduleRunnerPlugin { impl Plugin for ScheduleRunnerPlugin { fn build(&self, app: &mut App) { let run_mode = self.run_mode; + let startup_schedule_label = self.startup_schedule_label.clone(); + let update_schedule_label = self.update_schedule_label.clone(); app.set_runner(move |mut app: App| { + // Prevent panic when schedules do not exist + app.init_schedule(startup_schedule_label.clone()); + app.init_schedule(update_schedule_label.clone()); + + { + #[cfg(feature = "trace")] + let _ = info_span!("run top schedule", name = ?startup_schedule_label).entered(); + app.world.run_schedule(startup_schedule_label); + } + let mut app_exit_event_reader = ManualEventReader::::default(); match run_mode { RunMode::Once => { - app.update(); + { + #[cfg(feature = "trace")] + let _ = + info_span!("run top schedule", name = ?update_schedule_label).entered(); + app.world.run_schedule(update_schedule_label); + } + app.update_sub_apps(); } RunMode::Loop { wait } => { let mut tick = move |app: &mut App, @@ -91,7 +135,14 @@ impl Plugin for ScheduleRunnerPlugin { } } - app.update(); + { + #[cfg(feature = "trace")] + let _ = info_span!("run top schedule", name = ?update_schedule_label) + .entered(); + app.world.run_schedule(&update_schedule_label); + } + app.update_sub_apps(); + app.world.clear_trackers(); if let Some(app_exit_events) = app.world.get_resource_mut::>() diff --git a/crates/bevy_asset/src/asset_server.rs b/crates/bevy_asset/src/asset_server.rs index d97f206bbdc36..1faa501035186 100644 --- a/crates/bevy_asset/src/asset_server.rs +++ b/crates/bevy_asset/src/asset_server.rs @@ -645,7 +645,7 @@ pub fn free_unused_assets_system(asset_server: Res) { mod test { use super::*; use crate::{loader::LoadedAsset, update_asset_storage_system}; - use bevy_app::{App, Update}; + use bevy_app::{App, Update, UpdateFlow}; use bevy_ecs::prelude::*; use bevy_reflect::{TypePath, TypeUuid}; use bevy_utils::BoxedFuture; @@ -896,19 +896,19 @@ mod test { // asset is loading assert_eq!(LoadState::Loading, get_load_state(&handle, &app.world)); - app.update(); + app.world.run_schedule(UpdateFlow); // asset should exist and be loaded at this point assert_eq!(LoadState::Loaded, get_load_state(&handle, &app.world)); assert!(get_asset(&handle, &app.world).is_some()); // after dropping the handle, next call to `tick` will prepare the assets for removal. drop(handle); - app.update(); + app.world.run_schedule(UpdateFlow); assert_eq!(LoadState::Loaded, get_load_state(&weak_handle, &app.world)); assert!(get_asset(&weak_handle, &app.world).is_some()); // second call to tick will actually remove the asset. - app.update(); + app.world.run_schedule(UpdateFlow); assert_eq!( LoadState::Unloaded, get_load_state(&weak_handle, &app.world) @@ -918,7 +918,7 @@ mod test { // finally, reload the asset let handle = load_asset(path.clone(), &app.world).typed(); assert_eq!(LoadState::Loading, get_load_state(&handle, &app.world)); - app.update(); + app.world.run_schedule(UpdateFlow); assert_eq!(LoadState::Loaded, get_load_state(&handle, &app.world)); assert!(get_asset(&handle, &app.world).is_some()); } diff --git a/crates/bevy_asset/src/debug_asset_server.rs b/crates/bevy_asset/src/debug_asset_server.rs index 6c2e3d4815102..3c4394d7ab945 100644 --- a/crates/bevy_asset/src/debug_asset_server.rs +++ b/crates/bevy_asset/src/debug_asset_server.rs @@ -2,7 +2,7 @@ //! //! Internal assets (e.g. shaders) are bundled directly into an application and can't be hot //! reloaded using the conventional API. -use bevy_app::{App, Plugin, Update}; +use bevy_app::{App, Plugin, Update, UpdateFlow}; use bevy_ecs::{prelude::*, system::SystemState}; use bevy_tasks::{IoTaskPool, TaskPoolBuilder}; use bevy_utils::{Duration, HashMap}; @@ -76,12 +76,12 @@ impl Plugin for DebugAssetServerPlugin { watch_for_changes: ChangeWatcher::with_delay(Duration::from_millis(200)), }); app.insert_non_send_resource(DebugAssetApp(debug_asset_app)); - app.add_systems(Update, run_debug_asset_app); + app.add_systems(FrameReady, run_debug_asset_app); } } fn run_debug_asset_app(mut debug_asset_app: NonSendMut) { - debug_asset_app.0.update(); + debug_asset_app.0.world.run_schedule(UpdateFlow); } pub(crate) fn sync_debug_assets( diff --git a/crates/bevy_asset/src/diagnostic/asset_count_diagnostics_plugin.rs b/crates/bevy_asset/src/diagnostic/asset_count_diagnostics_plugin.rs index dafd21567347b..137239365c8c3 100644 --- a/crates/bevy_asset/src/diagnostic/asset_count_diagnostics_plugin.rs +++ b/crates/bevy_asset/src/diagnostic/asset_count_diagnostics_plugin.rs @@ -21,7 +21,7 @@ impl Default for AssetCountDiagnosticsPlugin { impl Plugin for AssetCountDiagnosticsPlugin { fn build(&self, app: &mut App) { app.add_systems(Startup, Self::setup_system) - .add_systems(Update, Self::diagnostic_system); + .add_systems(FrameReady, Self::diagnostic_system); } } diff --git a/crates/bevy_asset/src/lib.rs b/crates/bevy_asset/src/lib.rs index cc325d26c4dd5..284050f0fcf9f 100644 --- a/crates/bevy_asset/src/lib.rs +++ b/crates/bevy_asset/src/lib.rs @@ -47,8 +47,8 @@ pub use loader::*; pub use path::*; pub use reflect::*; -use bevy_app::{prelude::*, MainScheduleOrder}; -use bevy_ecs::schedule::ScheduleLabel; +use bevy_app::prelude::*; +use bevy_ecs::{schedule::ScheduleLabel, world::World}; use bevy_utils::Duration; /// Asset storages are updated. @@ -132,7 +132,6 @@ impl Plugin for AssetPlugin { app.register_type::(); app.register_type::(); - app.add_systems(PreUpdate, asset_server::free_unused_assets_system); app.init_schedule(LoadAssets); app.init_schedule(AssetEvents); @@ -141,9 +140,10 @@ impl Plugin for AssetPlugin { all(not(target_arch = "wasm32"), not(target_os = "android")) ))] app.add_systems(LoadAssets, io::filesystem_watcher_system); - - let mut order = app.world.resource_mut::(); - order.insert_after(First, LoadAssets); - order.insert_after(PostUpdate, AssetEvents); + app.add_systems(LoadAssets, asset_server::free_unused_assets_system); + app.add_systems(FrameReady, |world: &mut World| { + world.run_schedule(LoadAssets); + world.run_schedule(AssetEvents); + }); } } diff --git a/crates/bevy_audio/src/lib.rs b/crates/bevy_audio/src/lib.rs index 6544c789698fc..b5e9c3f6887eb 100644 --- a/crates/bevy_audio/src/lib.rs +++ b/crates/bevy_audio/src/lib.rs @@ -64,7 +64,7 @@ impl Plugin for AudioPlugin { .add_asset::() .init_resource::>() .insert_resource(self.global_volume) - .add_systems(PostUpdate, play_queued_audio_system::); + .add_systems(FrameReady, play_queued_audio_system::); #[cfg(any(feature = "mp3", feature = "flac", feature = "wav", feature = "vorbis"))] app.init_asset_loader::(); @@ -80,6 +80,6 @@ impl AddAudioSource for App { self.add_asset::() .init_resource::>() .init_resource::>() - .add_systems(PostUpdate, play_queued_audio_system::) + .add_systems(FrameReady, play_queued_audio_system::) } } diff --git a/crates/bevy_core/src/lib.rs b/crates/bevy_core/src/lib.rs index a9b10b1e81f2b..6e96343d8d3fd 100644 --- a/crates/bevy_core/src/lib.rs +++ b/crates/bevy_core/src/lib.rs @@ -114,7 +114,7 @@ impl Plugin for TaskPoolPlugin { self.task_pool_options.create_default_pools(); #[cfg(not(target_arch = "wasm32"))] - _app.add_systems(Last, tick_global_task_pools); + _app.add_systems(FrameReady, tick_global_task_pools); } } /// A dummy type that is [`!Send`](Send), to force systems to run on the main thread. @@ -203,7 +203,7 @@ mod tests { TypeRegistrationPlugin::default(), FrameCountPlugin::default(), )); - app.update(); + app.world.run_schedule(UpdateFlow); let frame_count = app.world.resource::(); assert_eq!(1, frame_count.0); diff --git a/crates/bevy_core_pipeline/src/bloom/mod.rs b/crates/bevy_core_pipeline/src/bloom/mod.rs index e5271544e2d78..927e3c691744c 100644 --- a/crates/bevy_core_pipeline/src/bloom/mod.rs +++ b/crates/bevy_core_pipeline/src/bloom/mod.rs @@ -8,7 +8,7 @@ use crate::{ core_2d::{self, CORE_2D}, core_3d::{self, CORE_3D}, }; -use bevy_app::{App, Plugin}; +use bevy_app::{App, Plugin, RenderFlow}; use bevy_asset::{load_internal_asset, HandleUntyped}; use bevy_ecs::{prelude::*, query::QueryItem}; use bevy_math::UVec2; @@ -24,7 +24,7 @@ use bevy_render::{ renderer::{RenderContext, RenderDevice}, texture::{CachedTexture, TextureCache}, view::ViewTarget, - Render, RenderApp, RenderSet, + RenderApp, RenderSet, }; use downsampling_pipeline::{ prepare_downsampling_pipeline, BloomDownsamplingPipeline, BloomDownsamplingPipelineIds, @@ -66,7 +66,7 @@ impl Plugin for BloomPlugin { .init_resource::>() .init_resource::>() .add_systems( - Render, + RenderFlow, ( prepare_bloom_textures.in_set(RenderSet::Prepare), prepare_downsampling_pipeline.in_set(RenderSet::Prepare), diff --git a/crates/bevy_core_pipeline/src/contrast_adaptive_sharpening/mod.rs b/crates/bevy_core_pipeline/src/contrast_adaptive_sharpening/mod.rs index b26c02b54754b..ae87e1f638bfa 100644 --- a/crates/bevy_core_pipeline/src/contrast_adaptive_sharpening/mod.rs +++ b/crates/bevy_core_pipeline/src/contrast_adaptive_sharpening/mod.rs @@ -15,7 +15,7 @@ use bevy_render::{ renderer::RenderDevice, texture::BevyDefault, view::{ExtractedView, ViewTarget}, - Render, RenderApp, RenderSet, + RenderApp, RenderSet, }; mod node; @@ -119,7 +119,7 @@ impl Plugin for CASPlugin { }; render_app .init_resource::>() - .add_systems(Render, prepare_cas_pipelines.in_set(RenderSet::Prepare)); + .add_systems(RenderFlow, prepare_cas_pipelines.in_set(RenderSet::Prepare)); { use core_3d::graph::node::*; diff --git a/crates/bevy_core_pipeline/src/core_2d/mod.rs b/crates/bevy_core_pipeline/src/core_2d/mod.rs index d3d12130b393f..49b867519529c 100644 --- a/crates/bevy_core_pipeline/src/core_2d/mod.rs +++ b/crates/bevy_core_pipeline/src/core_2d/mod.rs @@ -22,7 +22,7 @@ pub const CORE_2D: &str = graph::NAME; pub use camera_2d::*; pub use main_pass_2d_node::*; -use bevy_app::{App, Plugin}; +use bevy_app::{App, Plugin, RenderFlow}; use bevy_ecs::prelude::*; use bevy_render::{ camera::Camera, @@ -33,7 +33,7 @@ use bevy_render::{ DrawFunctionId, DrawFunctions, PhaseItem, RenderPhase, }, render_resource::CachedRenderPipelineId, - Extract, ExtractSchedule, Render, RenderApp, RenderSet, + Extract, ExtractSchedule, RenderApp, RenderSet, }; use bevy_utils::FloatOrd; use std::ops::Range; @@ -56,7 +56,7 @@ impl Plugin for Core2dPlugin { .init_resource::>() .add_systems(ExtractSchedule, extract_core_2d_camera_phases) .add_systems( - Render, + RenderFlow, ( sort_phase_system::.in_set(RenderSet::PhaseSort), 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 29e7157165d13..227068bc9c522 100644 --- a/crates/bevy_core_pipeline/src/core_3d/mod.rs +++ b/crates/bevy_core_pipeline/src/core_3d/mod.rs @@ -30,7 +30,7 @@ pub use camera_3d::*; pub use main_opaque_pass_3d_node::*; pub use main_transparent_pass_3d_node::*; -use bevy_app::{App, Plugin}; +use bevy_app::{App, Plugin, RenderFlow}; use bevy_ecs::prelude::*; use bevy_render::{ camera::{Camera, ExtractedCamera}, @@ -48,7 +48,7 @@ use bevy_render::{ renderer::RenderDevice, texture::TextureCache, view::ViewDepthTexture, - Extract, ExtractSchedule, Render, RenderApp, RenderSet, + Extract, ExtractSchedule, RenderApp, RenderSet, }; use bevy_utils::{FloatOrd, HashMap}; @@ -85,7 +85,7 @@ impl Plugin for Core3dPlugin { .add_systems(ExtractSchedule, extract_core_3d_camera_phases) .add_systems(ExtractSchedule, extract_camera_prepass_phase) .add_systems( - Render, + RenderFlow, ( prepare_core_3d_depth_textures .in_set(RenderSet::Prepare) diff --git a/crates/bevy_core_pipeline/src/fxaa/mod.rs b/crates/bevy_core_pipeline/src/fxaa/mod.rs index e153a77b623b0..c6c4bcd0cf420 100644 --- a/crates/bevy_core_pipeline/src/fxaa/mod.rs +++ b/crates/bevy_core_pipeline/src/fxaa/mod.rs @@ -19,7 +19,7 @@ use bevy_render::{ renderer::RenderDevice, texture::BevyDefault, view::{ExtractedView, ViewTarget}, - Render, RenderApp, RenderSet, + RenderApp, RenderSet, }; mod node; @@ -95,7 +95,10 @@ impl Plugin for FxaaPlugin { }; render_app .init_resource::>() - .add_systems(Render, prepare_fxaa_pipelines.in_set(RenderSet::Prepare)) + .add_systems( + RenderFlow, + prepare_fxaa_pipelines.in_set(RenderSet::Prepare), + ) .add_render_graph_node::>(CORE_3D, core_3d::graph::node::FXAA) .add_render_graph_edges( CORE_3D, diff --git a/crates/bevy_core_pipeline/src/msaa_writeback.rs b/crates/bevy_core_pipeline/src/msaa_writeback.rs index cf881b07b608e..1f6488545926a 100644 --- a/crates/bevy_core_pipeline/src/msaa_writeback.rs +++ b/crates/bevy_core_pipeline/src/msaa_writeback.rs @@ -3,14 +3,14 @@ use crate::{ core_2d::{self, CORE_2D}, core_3d::{self, CORE_3D}, }; -use bevy_app::{App, Plugin}; +use bevy_app::{App, Plugin, RenderFlow}; use bevy_ecs::prelude::*; use bevy_render::{ camera::ExtractedCamera, render_graph::{Node, NodeRunError, RenderGraphApp, RenderGraphContext}, renderer::RenderContext, view::{Msaa, ViewTarget}, - Render, RenderSet, + RenderSet, }; use bevy_render::{render_resource::*, RenderApp}; @@ -25,7 +25,7 @@ impl Plugin for MsaaWritebackPlugin { }; render_app.add_systems( - Render, + RenderFlow, queue_msaa_writeback_pipelines.in_set(RenderSet::Queue), ); { diff --git a/crates/bevy_core_pipeline/src/skybox/mod.rs b/crates/bevy_core_pipeline/src/skybox/mod.rs index ccf21334aa10a..7c6dd4b4552e4 100644 --- a/crates/bevy_core_pipeline/src/skybox/mod.rs +++ b/crates/bevy_core_pipeline/src/skybox/mod.rs @@ -1,4 +1,4 @@ -use bevy_app::{App, Plugin}; +use bevy_app::{App, Plugin, RenderFlow}; use bevy_asset::{load_internal_asset, Handle, HandleUntyped}; use bevy_ecs::{ prelude::{Component, Entity}, @@ -22,7 +22,7 @@ use bevy_render::{ renderer::RenderDevice, texture::{BevyDefault, Image}, view::{ExtractedView, Msaa, ViewTarget, ViewUniform, ViewUniforms}, - Render, RenderApp, RenderSet, + RenderApp, RenderSet, }; const SKYBOX_SHADER_HANDLE: HandleUntyped = @@ -44,7 +44,7 @@ impl Plugin for SkyboxPlugin { render_app .init_resource::>() .add_systems( - Render, + RenderFlow, ( prepare_skybox_pipelines.in_set(RenderSet::Prepare), queue_skybox_bind_groups.in_set(RenderSet::Queue), diff --git a/crates/bevy_core_pipeline/src/taa/mod.rs b/crates/bevy_core_pipeline/src/taa/mod.rs index 746f22ded9d66..4e3f6f7a384db 100644 --- a/crates/bevy_core_pipeline/src/taa/mod.rs +++ b/crates/bevy_core_pipeline/src/taa/mod.rs @@ -4,7 +4,7 @@ use crate::{ prelude::Camera3d, prepass::{DepthPrepass, MotionVectorPrepass, ViewPrepassTextures}, }; -use bevy_app::{App, Plugin}; +use bevy_app::{App, Plugin, RenderFlow}; use bevy_asset::{load_internal_asset, HandleUntyped}; use bevy_core::FrameCount; use bevy_ecs::{ @@ -32,7 +32,7 @@ use bevy_render::{ renderer::{RenderContext, RenderDevice}, texture::{BevyDefault, CachedTexture, TextureCache}, view::{prepare_view_uniforms, ExtractedView, Msaa, ViewTarget}, - ExtractSchedule, MainWorld, Render, RenderApp, RenderSet, + ExtractSchedule, MainWorld, RenderApp, RenderSet, }; mod draw_3d_graph { @@ -63,7 +63,7 @@ impl Plugin for TemporalAntiAliasPlugin { .init_resource::>() .add_systems(ExtractSchedule, extract_taa_settings) .add_systems( - Render, + RenderFlow, ( (prepare_taa_jitter_and_mip_bias, apply_deferred) .chain() diff --git a/crates/bevy_core_pipeline/src/tonemapping/mod.rs b/crates/bevy_core_pipeline/src/tonemapping/mod.rs index 0896c37f3ec9b..ccdea0edcf8e8 100644 --- a/crates/bevy_core_pipeline/src/tonemapping/mod.rs +++ b/crates/bevy_core_pipeline/src/tonemapping/mod.rs @@ -10,7 +10,7 @@ use bevy_render::render_asset::RenderAssets; use bevy_render::renderer::RenderDevice; use bevy_render::texture::{CompressedImageFormats, Image, ImageSampler, ImageType}; use bevy_render::view::{ViewTarget, ViewUniform}; -use bevy_render::{render_resource::*, Render, RenderApp, RenderSet}; +use bevy_render::{render_resource::*, RenderApp, RenderSet}; mod node; @@ -96,7 +96,7 @@ impl Plugin for TonemappingPlugin { render_app .init_resource::>() .add_systems( - Render, + RenderFlow, queue_view_tonemapping_pipelines.in_set(RenderSet::Queue), ); } diff --git a/crates/bevy_core_pipeline/src/upscaling/mod.rs b/crates/bevy_core_pipeline/src/upscaling/mod.rs index f3594397d5120..d8a6cc3d590dc 100644 --- a/crates/bevy_core_pipeline/src/upscaling/mod.rs +++ b/crates/bevy_core_pipeline/src/upscaling/mod.rs @@ -3,7 +3,7 @@ use bevy_app::prelude::*; use bevy_ecs::prelude::*; use bevy_render::camera::{CameraOutputMode, ExtractedCamera}; use bevy_render::view::ViewTarget; -use bevy_render::{render_resource::*, Render, RenderApp, RenderSet}; +use bevy_render::{render_resource::*, RenderApp, RenderSet}; mod node; @@ -15,7 +15,7 @@ impl Plugin for UpscalingPlugin { fn build(&self, app: &mut App) { if let Ok(render_app) = app.get_sub_app_mut(RenderApp) { render_app.add_systems( - Render, + RenderFlow, queue_view_upscaling_pipelines.in_set(RenderSet::Queue), ); } diff --git a/crates/bevy_diagnostic/src/entity_count_diagnostics_plugin.rs b/crates/bevy_diagnostic/src/entity_count_diagnostics_plugin.rs index 8999163aa9720..e2989d0134421 100644 --- a/crates/bevy_diagnostic/src/entity_count_diagnostics_plugin.rs +++ b/crates/bevy_diagnostic/src/entity_count_diagnostics_plugin.rs @@ -10,7 +10,7 @@ pub struct EntityCountDiagnosticsPlugin; impl Plugin for EntityCountDiagnosticsPlugin { fn build(&self, app: &mut App) { app.register_diagnostic(Diagnostic::new(Self::ENTITY_COUNT, "entity_count", 20)) - .add_systems(Update, Self::diagnostic_system); + .add_systems(FrameReady, Self::diagnostic_system); } } diff --git a/crates/bevy_diagnostic/src/frame_time_diagnostics_plugin.rs b/crates/bevy_diagnostic/src/frame_time_diagnostics_plugin.rs index a17a6a19d4c13..703ad54949169 100644 --- a/crates/bevy_diagnostic/src/frame_time_diagnostics_plugin.rs +++ b/crates/bevy_diagnostic/src/frame_time_diagnostics_plugin.rs @@ -17,7 +17,7 @@ impl Plugin for FrameTimeDiagnosticsPlugin { .register_diagnostic( Diagnostic::new(Self::FRAME_COUNT, "frame_count", 1).with_smoothing_factor(0.0), ) - .add_systems(Update, Self::diagnostic_system); + .add_systems(FrameReady, Self::diagnostic_system); } } diff --git a/crates/bevy_diagnostic/src/log_diagnostics_plugin.rs b/crates/bevy_diagnostic/src/log_diagnostics_plugin.rs index c59d128d890aa..6fc18ee2521bd 100644 --- a/crates/bevy_diagnostic/src/log_diagnostics_plugin.rs +++ b/crates/bevy_diagnostic/src/log_diagnostics_plugin.rs @@ -37,9 +37,9 @@ impl Plugin for LogDiagnosticsPlugin { }); if self.debug { - app.add_systems(PostUpdate, Self::log_diagnostics_debug_system); + app.add_systems(FrameReady, Self::log_diagnostics_debug_system); } else { - app.add_systems(PostUpdate, Self::log_diagnostics_system); + app.add_systems(FrameReady, Self::log_diagnostics_system); } } } diff --git a/crates/bevy_diagnostic/src/system_information_diagnostics_plugin.rs b/crates/bevy_diagnostic/src/system_information_diagnostics_plugin.rs index 5380bdbda2e4b..e6ce8b79bc517 100644 --- a/crates/bevy_diagnostic/src/system_information_diagnostics_plugin.rs +++ b/crates/bevy_diagnostic/src/system_information_diagnostics_plugin.rs @@ -15,7 +15,7 @@ pub struct SystemInformationDiagnosticsPlugin; impl Plugin for SystemInformationDiagnosticsPlugin { fn build(&self, app: &mut App) { app.add_systems(Startup, internal::setup_system) - .add_systems(Update, internal::diagnostic_system); + .add_systems(FrameReady, internal::diagnostic_system); } } diff --git a/crates/bevy_gilrs/src/lib.rs b/crates/bevy_gilrs/src/lib.rs index 1afcf515f6613..114b46a3357c9 100644 --- a/crates/bevy_gilrs/src/lib.rs +++ b/crates/bevy_gilrs/src/lib.rs @@ -4,7 +4,7 @@ mod converter; mod gilrs_system; mod rumble; -use bevy_app::{App, Plugin, PostUpdate, PreStartup, PreUpdate}; +use bevy_app::{App, Control, FrameReady, Plugin, PreStartup}; use bevy_ecs::prelude::*; use bevy_input::InputSystem; use bevy_utils::tracing::error; @@ -30,8 +30,8 @@ impl Plugin for GilrsPlugin { app.insert_non_send_resource(gilrs) .init_non_send_resource::() .add_systems(PreStartup, gilrs_event_startup_system) - .add_systems(PreUpdate, gilrs_event_system.before(InputSystem)) - .add_systems(PostUpdate, play_gilrs_rumble.in_set(RumbleSystem)); + .add_systems(Control, gilrs_event_system.before(InputSystem)) + .add_systems(FrameReady, play_gilrs_rumble.in_set(RumbleSystem)); } Err(err) => error!("Failed to start Gilrs. {}", err), } diff --git a/crates/bevy_gizmos/src/lib.rs b/crates/bevy_gizmos/src/lib.rs index 23c53c895d719..1cab57a530e99 100644 --- a/crates/bevy_gizmos/src/lib.rs +++ b/crates/bevy_gizmos/src/lib.rs @@ -18,7 +18,7 @@ use std::mem; -use bevy_app::{Last, Plugin, Update}; +use bevy_app::{FrameReady, Plugin, RenderFlow}; use bevy_asset::{load_internal_asset, AddAsset, Assets, Handle, HandleUntyped}; use bevy_core::cast_slice; use bevy_ecs::{ @@ -49,7 +49,7 @@ use bevy_render::{ VertexFormat, VertexStepMode, }, renderer::RenderDevice, - Extract, ExtractSchedule, Render, RenderApp, RenderSet, + Extract, ExtractSchedule, RenderApp, RenderSet, }; use bevy_transform::components::{GlobalTransform, Transform}; @@ -84,12 +84,12 @@ impl Plugin for GizmoPlugin { .init_resource::() .init_resource::() .init_resource::() - .add_systems(Last, update_gizmo_meshes) .add_systems( - Update, + FrameReady, ( draw_aabbs, draw_all_aabbs.run_if(|config: Res| config.aabb.draw_all), + update_gizmo_meshes, ), ); @@ -97,7 +97,10 @@ impl Plugin for GizmoPlugin { render_app .add_systems(ExtractSchedule, extract_gizmo_data) - .add_systems(Render, queue_line_gizmo_bind_group.in_set(RenderSet::Queue)); + .add_systems( + RenderFlow, + queue_line_gizmo_bind_group.in_set(RenderSet::Queue), + ); #[cfg(feature = "bevy_sprite")] app.add_plugins(pipeline_2d::LineGizmo2dPlugin); diff --git a/crates/bevy_gizmos/src/pipeline_2d.rs b/crates/bevy_gizmos/src/pipeline_2d.rs index 5e903b8e305da..fe4f664d96cd0 100644 --- a/crates/bevy_gizmos/src/pipeline_2d.rs +++ b/crates/bevy_gizmos/src/pipeline_2d.rs @@ -2,7 +2,7 @@ use crate::{ line_gizmo_vertex_buffer_layouts, DrawLineGizmo, LineGizmo, LineGizmoUniformBindgroupLayout, SetLineGizmoBindGroup, LINE_SHADER_HANDLE, }; -use bevy_app::{App, Plugin}; +use bevy_app::{App, Plugin, RenderFlow}; use bevy_asset::Handle; use bevy_core_pipeline::core_2d::Transparent2d; @@ -18,7 +18,7 @@ use bevy_render::{ render_resource::*, texture::BevyDefault, view::{ExtractedView, Msaa, ViewTarget}, - Render, RenderApp, RenderSet, + RenderApp, RenderSet, }; use bevy_sprite::{Mesh2dPipeline, Mesh2dPipelineKey, SetMesh2dViewBindGroup}; use bevy_utils::FloatOrd; @@ -32,7 +32,7 @@ impl Plugin for LineGizmo2dPlugin { render_app .add_render_command::() .init_resource::>() - .add_systems(Render, queue_line_gizmos_2d.in_set(RenderSet::Queue)); + .add_systems(RenderFlow, queue_line_gizmos_2d.in_set(RenderSet::Queue)); } fn finish(&self, app: &mut App) { diff --git a/crates/bevy_gizmos/src/pipeline_3d.rs b/crates/bevy_gizmos/src/pipeline_3d.rs index bfd1ed1a4cd2f..8189570dccb65 100644 --- a/crates/bevy_gizmos/src/pipeline_3d.rs +++ b/crates/bevy_gizmos/src/pipeline_3d.rs @@ -2,7 +2,7 @@ use crate::{ line_gizmo_vertex_buffer_layouts, DrawLineGizmo, GizmoConfig, LineGizmo, LineGizmoUniformBindgroupLayout, SetLineGizmoBindGroup, LINE_SHADER_HANDLE, }; -use bevy_app::{App, Plugin}; +use bevy_app::{App, Plugin, RenderFlow}; use bevy_asset::Handle; use bevy_core_pipeline::core_3d::Transparent3d; @@ -22,7 +22,7 @@ use bevy_render::{ render_resource::*, texture::BevyDefault, view::{ExtractedView, Msaa, ViewTarget}, - Render, RenderApp, RenderSet, + RenderApp, RenderSet, }; pub struct LineGizmo3dPlugin; @@ -33,7 +33,7 @@ impl Plugin for LineGizmo3dPlugin { render_app .add_render_command::() .init_resource::>() - .add_systems(Render, queue_line_gizmos_3d.in_set(RenderSet::Queue)); + .add_systems(RenderFlow, queue_line_gizmos_3d.in_set(RenderSet::Queue)); } fn finish(&self, app: &mut App) { diff --git a/crates/bevy_input/src/lib.rs b/crates/bevy_input/src/lib.rs index 4f343ece0dbf2..f6f744e1ff06f 100644 --- a/crates/bevy_input/src/lib.rs +++ b/crates/bevy_input/src/lib.rs @@ -62,13 +62,13 @@ impl Plugin for InputPlugin { .add_event::() .init_resource::>() .init_resource::>() - .add_systems(PreUpdate, keyboard_input_system.in_set(InputSystem)) + .add_systems(Control, keyboard_input_system.in_set(InputSystem)) // mouse .add_event::() .add_event::() .add_event::() .init_resource::>() - .add_systems(PreUpdate, mouse_button_input_system.in_set(InputSystem)) + .add_systems(Control, mouse_button_input_system.in_set(InputSystem)) .add_event::() .add_event::() // gamepad @@ -99,7 +99,7 @@ impl Plugin for InputPlugin { // touch .add_event::() .init_resource::() - .add_systems(PreUpdate, touch_screen_input_system.in_set(InputSystem)); + .add_systems(Control, touch_screen_input_system.in_set(InputSystem)); // Register common types app.register_type::(); diff --git a/crates/bevy_internal/src/prelude.rs b/crates/bevy_internal/src/prelude.rs index f9243382a11ef..3368a4f224425 100644 --- a/crates/bevy_internal/src/prelude.rs +++ b/crates/bevy_internal/src/prelude.rs @@ -2,7 +2,8 @@ pub use crate::{ app::prelude::*, core::prelude::*, ecs::prelude::*, hierarchy::prelude::*, input::prelude::*, log::prelude::*, math::prelude::*, reflect::prelude::*, time::prelude::*, - transform::prelude::*, utils::prelude::*, window::prelude::*, DefaultPlugins, MinimalPlugins, + transform::prelude::*, utils::prelude::*, window::prelude::*, winit::prelude::*, + DefaultPlugins, MinimalPlugins, }; pub use bevy_derive::{bevy_main, Deref, DerefMut}; diff --git a/crates/bevy_pbr/src/lib.rs b/crates/bevy_pbr/src/lib.rs index 2460a0e0f67df..dc3734bc769fa 100644 --- a/crates/bevy_pbr/src/lib.rs +++ b/crates/bevy_pbr/src/lib.rs @@ -63,7 +63,7 @@ use bevy_render::{ render_phase::sort_phase_system, render_resource::Shader, view::{ViewSet, VisibilitySystems}, - ExtractSchedule, Render, RenderApp, RenderSet, + ExtractSchedule, RenderApp, RenderSet, }; use bevy_transform::TransformSystem; use environment_map::EnvironmentMapPlugin; @@ -269,7 +269,7 @@ impl Plugin for PbrPlugin { // Extract the required data from the main world render_app .configure_sets( - Render, + RenderFlow, ( RenderLightSystems::PrepareLights.in_set(RenderSet::Prepare), RenderLightSystems::PrepareClusters.in_set(RenderSet::Prepare), @@ -284,7 +284,7 @@ impl Plugin for PbrPlugin { ), ) .add_systems( - Render, + RenderFlow, ( render::prepare_lights .before(ViewSet::PrepareUniforms) diff --git a/crates/bevy_pbr/src/material.rs b/crates/bevy_pbr/src/material.rs index ec9e4364b9521..ec7e91a4ec470 100644 --- a/crates/bevy_pbr/src/material.rs +++ b/crates/bevy_pbr/src/material.rs @@ -3,7 +3,7 @@ use crate::{ MeshUniform, PrepassPipelinePlugin, PrepassPlugin, RenderLightSystems, ScreenSpaceAmbientOcclusionSettings, SetMeshBindGroup, SetMeshViewBindGroup, Shadow, }; -use bevy_app::{App, Plugin}; +use bevy_app::{App, Plugin, RenderFlow}; use bevy_asset::{AddAsset, AssetEvent, AssetServer, Assets, Handle}; use bevy_core_pipeline::{ core_3d::{AlphaMask3d, Opaque3d, Transparent3d}, @@ -37,7 +37,7 @@ use bevy_render::{ renderer::RenderDevice, texture::FallbackImage, view::{ExtractedView, Msaa, VisibleEntities}, - Extract, ExtractSchedule, Render, RenderApp, RenderSet, + Extract, ExtractSchedule, RenderApp, RenderSet, }; use bevy_utils::{tracing::error, HashMap, HashSet}; use std::hash::Hash; @@ -202,7 +202,7 @@ where .init_resource::>>() .add_systems(ExtractSchedule, extract_materials::) .add_systems( - Render, + RenderFlow, ( 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 af854b9c22860..2e9a2b15cb2d3 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, PreUpdate, Update}; +use bevy_app::{Plugin, PreUpdate, RenderFlow, Update}; use bevy_asset::{load_internal_asset, AssetServer, Handle, HandleUntyped}; use bevy_core_pipeline::{ prelude::Camera3d, @@ -39,7 +39,7 @@ use bevy_render::{ renderer::{RenderDevice, RenderQueue}, texture::{FallbackImagesDepth, FallbackImagesMsaa}, view::{ExtractedView, Msaa, ViewUniform, ViewUniformOffset, ViewUniforms, VisibleEntities}, - Extract, ExtractSchedule, Render, RenderApp, RenderSet, + Extract, ExtractSchedule, RenderApp, RenderSet, }; use bevy_transform::prelude::GlobalTransform; use bevy_utils::tracing::error; @@ -104,7 +104,7 @@ where render_app .add_systems( - Render, + RenderFlow, queue_prepass_view_bind_group::.in_set(RenderSet::Queue), ) .init_resource::() @@ -154,7 +154,7 @@ where render_app .add_systems(ExtractSchedule, extract_camera_previous_view_projection) .add_systems( - Render, + RenderFlow, ( prepare_previous_view_projection_uniforms .in_set(RenderSet::Prepare) @@ -171,7 +171,7 @@ where .add_render_command::>() .add_render_command::>() .add_systems( - Render, + RenderFlow, queue_prepass_material_meshes::.in_set(RenderSet::Queue), ); } diff --git a/crates/bevy_pbr/src/render/fog.rs b/crates/bevy_pbr/src/render/fog.rs index 6c314ccd0495f..b03299fe680b7 100644 --- a/crates/bevy_pbr/src/render/fog.rs +++ b/crates/bevy_pbr/src/render/fog.rs @@ -1,4 +1,4 @@ -use bevy_app::{App, Plugin}; +use bevy_app::{App, Plugin, RenderFlow}; use bevy_asset::{load_internal_asset, HandleUntyped}; use bevy_ecs::prelude::*; use bevy_math::{Vec3, Vec4}; @@ -8,7 +8,7 @@ use bevy_render::{ render_resource::{DynamicUniformBuffer, Shader, ShaderType}, renderer::{RenderDevice, RenderQueue}, view::ExtractedView, - Render, RenderApp, RenderSet, + RenderApp, RenderSet, }; use crate::{FogFalloff, FogSettings}; @@ -143,9 +143,9 @@ impl Plugin for FogPlugin { if let Ok(render_app) = app.get_sub_app_mut(RenderApp) { render_app .init_resource::() - .add_systems(Render, prepare_fog.in_set(RenderFogSystems::PrepareFog)) + .add_systems(RenderFlow, prepare_fog.in_set(RenderFogSystems::PrepareFog)) .configure_set( - Render, + RenderFlow, RenderFogSystems::PrepareFog.in_set(RenderSet::Prepare), ); } diff --git a/crates/bevy_pbr/src/render/mesh.rs b/crates/bevy_pbr/src/render/mesh.rs index 26aeadb0517e5..88a742d44f321 100644 --- a/crates/bevy_pbr/src/render/mesh.rs +++ b/crates/bevy_pbr/src/render/mesh.rs @@ -5,7 +5,7 @@ use crate::{ ViewLightsUniformOffset, ViewShadowBindings, CLUSTERED_FORWARD_STORAGE_BUFFER_COUNT, MAX_CASCADES_PER_LIGHT, MAX_DIRECTIONAL_LIGHTS, }; -use bevy_app::Plugin; +use bevy_app::{Plugin, RenderFlow}; use bevy_asset::{load_internal_asset, Assets, Handle, HandleId, HandleUntyped}; use bevy_core_pipeline::{ prepass::ViewPrepassTextures, @@ -38,7 +38,7 @@ use bevy_render::{ FallbackImagesMsaa, GpuImage, Image, ImageSampler, TextureFormatPixelInfo, }, view::{ComputedVisibility, ViewTarget, ViewUniform, ViewUniformOffset, ViewUniforms}, - Extract, ExtractSchedule, Render, RenderApp, RenderSet, + Extract, ExtractSchedule, RenderApp, RenderSet, }; use bevy_transform::components::GlobalTransform; use bevy_utils::{tracing::error, HashMap, Hashed}; @@ -123,7 +123,7 @@ impl Plugin for MeshRenderPlugin { (extract_meshes, extract_skinned_meshes, extract_morphs), ) .add_systems( - Render, + RenderFlow, ( prepare_skinned_meshes.in_set(RenderSet::Prepare), prepare_morphs.in_set(RenderSet::Prepare), diff --git a/crates/bevy_pbr/src/ssao/mod.rs b/crates/bevy_pbr/src/ssao/mod.rs index 276ee261a5e01..6ffcbb4a08ffc 100644 --- a/crates/bevy_pbr/src/ssao/mod.rs +++ b/crates/bevy_pbr/src/ssao/mod.rs @@ -1,4 +1,4 @@ -use bevy_app::{App, Plugin}; +use bevy_app::{App, Plugin, RenderFlow}; use bevy_asset::{load_internal_asset, HandleUntyped}; use bevy_core_pipeline::{ core_3d::CORE_3D, @@ -33,7 +33,7 @@ use bevy_render::{ renderer::{RenderAdapter, RenderContext, RenderDevice, RenderQueue}, texture::{CachedTexture, TextureCache}, view::{Msaa, ViewUniform, ViewUniformOffset, ViewUniforms}, - Extract, ExtractSchedule, Render, RenderApp, RenderSet, + Extract, ExtractSchedule, RenderApp, RenderSet, }; use bevy_utils::{ prelude::default, @@ -114,9 +114,12 @@ impl Plugin for ScreenSpaceAmbientOcclusionPlugin { .init_resource::() .init_resource::>() .add_systems(ExtractSchedule, extract_ssao_settings) - .add_systems(Render, prepare_ssao_textures.in_set(RenderSet::Prepare)) - .add_systems(Render, prepare_ssao_pipelines.in_set(RenderSet::Prepare)) - .add_systems(Render, queue_ssao_bind_groups.in_set(RenderSet::Queue)) + .add_systems(RenderFlow, prepare_ssao_textures.in_set(RenderSet::Prepare)) + .add_systems( + RenderFlow, + prepare_ssao_pipelines.in_set(RenderSet::Prepare), + ) + .add_systems(RenderFlow, queue_ssao_bind_groups.in_set(RenderSet::Queue)) .add_render_graph_node::>( CORE_3D, draw_3d_graph::node::SCREEN_SPACE_AMBIENT_OCCLUSION, diff --git a/crates/bevy_pbr/src/wireframe.rs b/crates/bevy_pbr/src/wireframe.rs index d3c8b3ba47509..0ceac4d5139c2 100644 --- a/crates/bevy_pbr/src/wireframe.rs +++ b/crates/bevy_pbr/src/wireframe.rs @@ -1,13 +1,12 @@ use crate::MeshPipeline; use crate::{DrawMesh, MeshPipelineKey, MeshUniform, SetMeshBindGroup, SetMeshViewBindGroup}; -use bevy_app::Plugin; +use bevy_app::{Plugin, RenderFlow}; use bevy_asset::{load_internal_asset, Handle, HandleUntyped}; use bevy_core_pipeline::core_3d::Opaque3d; use bevy_ecs::{prelude::*, reflect::ReflectComponent}; use bevy_reflect::std_traits::ReflectDefault; use bevy_reflect::{FromReflect, Reflect, ReflectFromReflect, TypeUuid}; use bevy_render::extract_component::{ExtractComponent, ExtractComponentPlugin}; -use bevy_render::Render; use bevy_render::{ extract_resource::{ExtractResource, ExtractResourcePlugin}, mesh::{Mesh, MeshVertexBufferLayout}, @@ -49,7 +48,7 @@ impl Plugin for WireframePlugin { render_app .add_render_command::() .init_resource::>() - .add_systems(Render, queue_wireframes.in_set(RenderSet::Queue)); + .add_systems(RenderFlow, queue_wireframes.in_set(RenderSet::Queue)); } } diff --git a/crates/bevy_render/src/camera/mod.rs b/crates/bevy_render/src/camera/mod.rs index b57ae98dc7941..c543d28ace25f 100644 --- a/crates/bevy_render/src/camera/mod.rs +++ b/crates/bevy_render/src/camera/mod.rs @@ -10,8 +10,8 @@ pub use manual_texture_view::*; pub use projection::*; use crate::{ - extract_resource::ExtractResourcePlugin, render_graph::RenderGraph, ExtractSchedule, Render, - RenderApp, RenderSet, + extract_resource::ExtractResourcePlugin, render_graph::RenderGraph, ExtractSchedule, RenderApp, + RenderFlow, RenderSet, }; use bevy_app::{App, Plugin}; use bevy_ecs::schedule::IntoSystemConfigs; @@ -39,7 +39,7 @@ impl Plugin for CameraPlugin { render_app .init_resource::() .add_systems(ExtractSchedule, extract_cameras) - .add_systems(Render, sort_cameras.in_set(RenderSet::Prepare)); + .add_systems(RenderFlow, sort_cameras.in_set(RenderSet::Prepare)); 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 606c8ccbe09ac..25cfed0b73464 100644 --- a/crates/bevy_render/src/extract_component.rs +++ b/crates/bevy_render/src/extract_component.rs @@ -2,7 +2,7 @@ use crate::{ render_resource::{encase::internal::WriteInto, DynamicUniformBuffer, ShaderType}, renderer::{RenderDevice, RenderQueue}, view::ComputedVisibility, - Extract, ExtractSchedule, Render, RenderApp, RenderSet, + Extract, ExtractSchedule, RenderApp, RenderFlow, RenderSet, }; use bevy_app::{App, Plugin}; use bevy_asset::{Asset, Handle}; @@ -84,7 +84,7 @@ impl Plugin for UniformComponentP render_app .insert_resource(ComponentUniforms::::default()) .add_systems( - Render, + RenderFlow, prepare_uniform_components::.in_set(RenderSet::Prepare), ); } diff --git a/crates/bevy_render/src/globals.rs b/crates/bevy_render/src/globals.rs index eb91d019f3cf6..3d1c9c7459ead 100644 --- a/crates/bevy_render/src/globals.rs +++ b/crates/bevy_render/src/globals.rs @@ -3,7 +3,7 @@ use crate::{ prelude::Shader, render_resource::{ShaderType, UniformBuffer}, renderer::{RenderDevice, RenderQueue}, - Extract, ExtractSchedule, Render, RenderApp, RenderSet, + Extract, ExtractSchedule, RenderApp, RenderFlow, RenderSet, }; use bevy_app::{App, Plugin}; use bevy_asset::{load_internal_asset, HandleUntyped}; @@ -27,7 +27,10 @@ impl Plugin for GlobalsPlugin { .init_resource::() .init_resource::