From e6caf023375cfdf89d7e9696e2c16b2d0e7ece99 Mon Sep 17 00:00:00 2001 From: Lubba64 Date: Sun, 25 Aug 2024 02:05:48 -0400 Subject: [PATCH 01/11] feat: Hide fixed-update behind a feature flag --- crates/bevy_app/Cargo.toml | 1 + crates/bevy_app/src/lib.rs | 7 +++- crates/bevy_app/src/main_schedule.rs | 63 +++++++++++++++++----------- crates/bevy_time/Cargo.toml | 1 + crates/bevy_time/src/fixed.rs | 2 + crates/bevy_time/src/lib.rs | 38 +++++++++++------ 6 files changed, 73 insertions(+), 39 deletions(-) diff --git a/crates/bevy_app/Cargo.toml b/crates/bevy_app/Cargo.toml index 758654b656695..182478ef018ba 100644 --- a/crates/bevy_app/Cargo.toml +++ b/crates/bevy_app/Cargo.toml @@ -18,6 +18,7 @@ reflect_functions = [ "bevy_reflect/functions", "bevy_ecs/reflect_functions", ] +fixed_update = [] [dependencies] # bevy diff --git a/crates/bevy_app/src/lib.rs b/crates/bevy_app/src/lib.rs index b389395d3dee7..d656fb377ff6c 100644 --- a/crates/bevy_app/src/lib.rs +++ b/crates/bevy_app/src/lib.rs @@ -29,12 +29,15 @@ pub use terminal_ctrl_c_handler::*; #[allow(missing_docs)] pub mod prelude { + #[cfg(feature = "fixed_update")] + pub use crate::main_schedule::{ + FixedFirst, FixedLast, FixedPostUpdate, FixedPreUpdate, FixedUpdate, RunFixedMainLoop, + }; #[doc(hidden)] pub use crate::{ app::{App, AppExit}, main_schedule::{ - First, FixedFirst, FixedLast, FixedPostUpdate, FixedPreUpdate, FixedUpdate, Last, Main, - PostStartup, PostUpdate, PreStartup, PreUpdate, RunFixedMainLoop, + First, Last, Main, PostStartup, PostUpdate, PreStartup, PreUpdate, RunFixedMainLoopSystem, SpawnScene, Startup, Update, }, sub_app::SubApp, diff --git a/crates/bevy_app/src/main_schedule.rs b/crates/bevy_app/src/main_schedule.rs index 3ee0a07a746d2..f1abe9273d280 100644 --- a/crates/bevy_app/src/main_schedule.rs +++ b/crates/bevy_app/src/main_schedule.rs @@ -1,13 +1,11 @@ use crate::{App, Plugin}; +#[cfg(feature = "fixed_update")] +use bevy_ecs::schedule::IntoSystemSetConfigs; use bevy_ecs::{ - schedule::{ - ExecutorKind, InternedScheduleLabel, IntoSystemSetConfigs, Schedule, ScheduleLabel, - SystemSet, - }, + schedule::{ExecutorKind, InternedScheduleLabel, Schedule, ScheduleLabel, SystemSet}, system::{Local, 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: @@ -85,6 +83,7 @@ pub struct PreUpdate; /// [`RunFixedMainLoop`] will *not* be parallelized between each other. /// /// See the [`Main`] schedule for some details about how schedules are run. +#[cfg(feature = "fixed_update")] #[derive(ScheduleLabel, Clone, Debug, PartialEq, Eq, Hash)] pub struct RunFixedMainLoop; @@ -92,6 +91,7 @@ pub struct RunFixedMainLoop; /// /// See the [`FixedMain`] schedule for details on how fixed updates work. /// See the [`Main`] schedule for some details about how schedules are run. +#[cfg(feature = "fixed_update")] #[derive(ScheduleLabel, Clone, Debug, PartialEq, Eq, Hash)] pub struct FixedFirst; @@ -99,6 +99,7 @@ pub struct FixedFirst; /// /// See the [`FixedMain`] schedule for details on how fixed updates work. /// See the [`Main`] schedule for some details about how schedules are run. +#[cfg(feature = "fixed_update")] #[derive(ScheduleLabel, Clone, Debug, PartialEq, Eq, Hash)] pub struct FixedPreUpdate; @@ -114,6 +115,7 @@ pub struct FixedPreUpdate; /// See the [`Update`] schedule for examples of systems that *should not* use this schedule. /// See the [`FixedMain`] schedule for details on how fixed updates work. /// See the [`Main`] schedule for some details about how schedules are run. +#[cfg(feature = "fixed_update")] #[derive(ScheduleLabel, Clone, Debug, PartialEq, Eq, Hash)] pub struct FixedUpdate; @@ -122,6 +124,7 @@ pub struct FixedUpdate; /// /// See the [`FixedMain`] schedule for details on how fixed updates work. /// See the [`Main`] schedule for some details about how schedules are run. +#[cfg(feature = "fixed_update")] #[derive(ScheduleLabel, Clone, Debug, PartialEq, Eq, Hash)] pub struct FixedPostUpdate; @@ -129,6 +132,7 @@ pub struct FixedPostUpdate; /// /// See the [`FixedMain`] schedule for details on how fixed updates work. /// See the [`Main`] schedule for some details about how schedules are run. +#[cfg(feature = "fixed_update")] #[derive(ScheduleLabel, Clone, Debug, PartialEq, Eq, Hash)] pub struct FixedLast; @@ -141,6 +145,7 @@ pub struct FixedLast; /// See [this example](https://github.com/bevyengine/bevy/blob/latest/examples/time/time.rs). /// /// See the [`Main`] schedule for some details about how schedules are run. +#[cfg(feature = "fixed_update")] #[derive(ScheduleLabel, Clone, Debug, PartialEq, Eq, Hash)] pub struct FixedMain; @@ -196,6 +201,7 @@ impl Default for MainScheduleOrder { labels: vec![ First.intern(), PreUpdate.intern(), + #[cfg(feature = "fixed_update")] RunFixedMainLoop.intern(), Update.intern(), SpawnScene.intern(), @@ -285,28 +291,33 @@ impl Plugin for MainSchedulePlugin { // simple "facilitator" schedules benefit from simpler single threaded scheduling let mut main_schedule = Schedule::new(Main); main_schedule.set_executor_kind(ExecutorKind::SingleThreaded); - let mut fixed_main_schedule = Schedule::new(FixedMain); - fixed_main_schedule.set_executor_kind(ExecutorKind::SingleThreaded); - let mut fixed_main_loop_schedule = Schedule::new(RunFixedMainLoop); - fixed_main_loop_schedule.set_executor_kind(ExecutorKind::SingleThreaded); + #[cfg(feature = "fixed_update")] + { + let mut fixed_main_schedule = Schedule::new(FixedMain); + fixed_main_schedule.set_executor_kind(ExecutorKind::SingleThreaded); + let mut fixed_main_loop_schedule = Schedule::new(RunFixedMainLoop); + fixed_main_loop_schedule.set_executor_kind(ExecutorKind::SingleThreaded); + } app.add_schedule(main_schedule) - .add_schedule(fixed_main_schedule) - .add_schedule(fixed_main_loop_schedule) .init_resource::() - .init_resource::() - .add_systems(Main, Main::run_main) - .add_systems(FixedMain, FixedMain::run_fixed_main) - .configure_sets( - RunFixedMainLoop, - ( - RunFixedMainLoopSystem::BeforeFixedMainLoop, - RunFixedMainLoopSystem::FixedMainLoop, - RunFixedMainLoopSystem::AfterFixedMainLoop, - ) - .chain(), - ); - + .add_systems(Main, Main::run_main); + #[cfg(feature = "fixed_update")] + { + app.add_schedule(fixed_main_schedule) + .add_schedule(fixed_main_loop_schedule) + .init_resource::() + .add_systems(FixedMain, FixedMain::run_fixed_main) + .configure_sets( + RunFixedMainLoop, + ( + RunFixedMainLoopSystem::BeforeFixedMainLoop, + RunFixedMainLoopSystem::FixedMainLoop, + RunFixedMainLoopSystem::AfterFixedMainLoop, + ) + .chain(), + ); + } #[cfg(feature = "bevy_debug_stepping")] { use bevy_ecs::schedule::{IntoSystemConfigs, Stepping}; @@ -317,12 +328,14 @@ impl Plugin for MainSchedulePlugin { /// Defines the schedules to be run for the [`FixedMain`] schedule, including /// their order. +#[cfg(feature = "fixed_update")] #[derive(Resource, Debug)] pub struct FixedMainScheduleOrder { /// The labels to run for the [`FixedMain`] schedule (in the order they will be run). pub labels: Vec, } +#[cfg(feature = "fixed_update")] impl Default for FixedMainScheduleOrder { fn default() -> Self { Self { @@ -337,6 +350,7 @@ impl Default for FixedMainScheduleOrder { } } +#[cfg(feature = "fixed_update")] impl FixedMainScheduleOrder { /// Adds the given `schedule` after the `after` schedule pub fn insert_after(&mut self, after: impl ScheduleLabel, schedule: impl ScheduleLabel) { @@ -359,6 +373,7 @@ impl FixedMainScheduleOrder { } } +#[cfg(feature = "fixed_update")] impl FixedMain { /// A system that runs the fixed timestep's "main schedule" pub fn run_fixed_main(world: &mut World) { diff --git a/crates/bevy_time/Cargo.toml b/crates/bevy_time/Cargo.toml index 93d14281198d0..42f28ebd2f555 100644 --- a/crates/bevy_time/Cargo.toml +++ b/crates/bevy_time/Cargo.toml @@ -11,6 +11,7 @@ keywords = ["bevy"] [features] default = ["bevy_reflect"] serialize = ["serde"] +fixed_update = ["bevy_app/fixed_update"] [dependencies] # bevy diff --git a/crates/bevy_time/src/fixed.rs b/crates/bevy_time/src/fixed.rs index 4b60461e34791..4bb165c3bdda5 100644 --- a/crates/bevy_time/src/fixed.rs +++ b/crates/bevy_time/src/fixed.rs @@ -1,3 +1,4 @@ +#[cfg(feature = "fixed_update")] use bevy_app::FixedMain; use bevy_ecs::world::World; #[cfg(feature = "bevy_reflect")] @@ -236,6 +237,7 @@ impl Default for Fixed { /// [`Time`](Virtual) and [`Time::overstep`]. /// You can order your systems relative to this by using /// [`RunFixedMainLoopSystem`](bevy_app::prelude::RunFixedMainLoopSystem). +#[cfg(feature = "fixed_update")] pub(super) fn run_fixed_main_schedule(world: &mut World) { let delta = world.resource::>().delta(); world.resource_mut::>().accumulate(delta); diff --git a/crates/bevy_time/src/lib.rs b/crates/bevy_time/src/lib.rs index 5181bc4335c4c..1f34b59cd4835 100644 --- a/crates/bevy_time/src/lib.rs +++ b/crates/bevy_time/src/lib.rs @@ -29,10 +29,12 @@ pub mod prelude { pub use crate::{Fixed, Real, Time, Timer, TimerMode, Virtual}; } -use bevy_app::{prelude::*, RunFixedMainLoop}; -use bevy_ecs::event::{ - event_update_system, signal_event_update_system, EventRegistry, ShouldUpdateEvents, -}; +use bevy_app::prelude::*; +#[cfg(feature = "fixed_update")] +use bevy_app::RunFixedMainLoop; +#[cfg(feature = "fixed_update")] +use bevy_ecs::event::signal_event_update_system; +use bevy_ecs::event::{event_update_system, EventRegistry, ShouldUpdateEvents}; use bevy_ecs::prelude::*; use bevy_utils::{tracing::warn, Duration, Instant}; pub use crossbeam_channel::TrySendError; @@ -69,14 +71,17 @@ impl Plugin for TimePlugin { time_system .in_set(TimeSystem) .ambiguous_with(event_update_system), - ) - .add_systems( - RunFixedMainLoop, - run_fixed_main_schedule.in_set(RunFixedMainLoopSystem::FixedMainLoop), ); + #[cfg(feature = "fixed_update")] + { + app.add_systems( + RunFixedMainLoop, + run_fixed_main_schedule.in_set(RunFixedMainLoopSystem::FixedMainLoop), + ); + // Ensure the events are not dropped until `FixedMain` systems can observe them + app.add_systems(FixedPostUpdate, signal_event_update_system); + } - // Ensure the events are not dropped until `FixedMain` systems can observe them - app.add_systems(FixedPostUpdate, signal_event_update_system); let mut event_registry = app.world_mut().resource_mut::(); // We need to start in a waiting state so that the events are not updated until the first fixed update event_registry.should_update = ShouldUpdateEvents::Waiting; @@ -155,7 +160,9 @@ pub fn time_system( #[cfg(test)] mod tests { use crate::{Fixed, Time, TimePlugin, TimeUpdateStrategy, Virtual}; - use bevy_app::{App, FixedUpdate, Startup, Update}; + #[cfg(feature = "fixed_update")] + use bevy_app::FixedUpdate; + use bevy_app::{App, Startup, Update}; use bevy_ecs::{ event::{Event, EventReader, EventRegistry, EventWriter, Events, ShouldUpdateEvents}, system::{Local, Res, ResMut, Resource}, @@ -182,6 +189,7 @@ mod tests { #[derive(Resource, Default)] struct FixedUpdateCounter(u8); + #[cfg(feature = "fixed_update")] fn count_fixed_updates(mut counter: ResMut) { counter.0 += 1; } @@ -214,8 +222,10 @@ mod tests { let time_step = fixed_update_timestep / 2 + Duration::from_millis(1); let mut app = App::new(); + #[cfg(feature = "fixed_update")] + app.add_systems(FixedUpdate, count_fixed_updates); + app.add_plugins(TimePlugin) - .add_systems(FixedUpdate, count_fixed_updates) .add_systems(Update, report_time) .init_resource::() .insert_resource(TimeUpdateStrategy::ManualDuration(time_step)); @@ -315,11 +325,13 @@ mod tests { } let mut app = App::new(); + #[cfg(feature = "fixed_update")] + app.add_systems(FixedUpdate, count_fixed_updates); + app.add_plugins(TimePlugin) .add_event::() .init_resource::() .add_systems(Startup, send_event) - .add_systems(FixedUpdate, count_fixed_updates) .insert_resource(TimeUpdateStrategy::ManualDuration(time_step)); for frame in 0..10 { From 553ca5ad70cc7b752bc785c1f343569d098b6a48 Mon Sep 17 00:00:00 2001 From: Lubba64 Date: Sun, 25 Aug 2024 02:17:16 -0400 Subject: [PATCH 02/11] fix: Fix some compiler errors --- crates/bevy_app/src/main_schedule.rs | 12 +++++------- crates/bevy_gizmos/Cargo.toml | 1 + crates/bevy_gizmos/src/lib.rs | 13 +++++++------ crates/bevy_time/src/fixed.rs | 8 +++++++- 4 files changed, 20 insertions(+), 14 deletions(-) diff --git a/crates/bevy_app/src/main_schedule.rs b/crates/bevy_app/src/main_schedule.rs index f1abe9273d280..302838df01a25 100644 --- a/crates/bevy_app/src/main_schedule.rs +++ b/crates/bevy_app/src/main_schedule.rs @@ -291,19 +291,17 @@ impl Plugin for MainSchedulePlugin { // simple "facilitator" schedules benefit from simpler single threaded scheduling let mut main_schedule = Schedule::new(Main); main_schedule.set_executor_kind(ExecutorKind::SingleThreaded); - #[cfg(feature = "fixed_update")] - { - let mut fixed_main_schedule = Schedule::new(FixedMain); - fixed_main_schedule.set_executor_kind(ExecutorKind::SingleThreaded); - let mut fixed_main_loop_schedule = Schedule::new(RunFixedMainLoop); - fixed_main_loop_schedule.set_executor_kind(ExecutorKind::SingleThreaded); - } app.add_schedule(main_schedule) .init_resource::() .add_systems(Main, Main::run_main); + #[cfg(feature = "fixed_update")] { + let mut fixed_main_schedule = Schedule::new(FixedMain); + fixed_main_schedule.set_executor_kind(ExecutorKind::SingleThreaded); + let mut fixed_main_loop_schedule = Schedule::new(RunFixedMainLoop); + fixed_main_loop_schedule.set_executor_kind(ExecutorKind::SingleThreaded); app.add_schedule(fixed_main_schedule) .add_schedule(fixed_main_loop_schedule) .init_resource::() diff --git a/crates/bevy_gizmos/Cargo.toml b/crates/bevy_gizmos/Cargo.toml index 5f79b93d3a266..32ee0400de8a3 100644 --- a/crates/bevy_gizmos/Cargo.toml +++ b/crates/bevy_gizmos/Cargo.toml @@ -11,6 +11,7 @@ keywords = ["bevy"] [features] webgl = [] webgpu = [] +fixed_update = ["bevy_app/fixed_update"] bevy_render = ["dep:bevy_render", "bevy_core_pipeline"] [dependencies] diff --git a/crates/bevy_gizmos/src/lib.rs b/crates/bevy_gizmos/src/lib.rs index 1d42c589470ba..0311716f93dc7 100644 --- a/crates/bevy_gizmos/src/lib.rs +++ b/crates/bevy_gizmos/src/lib.rs @@ -69,6 +69,13 @@ pub mod prelude { pub use crate::light::{LightGizmoColor, LightGizmoConfigGroup, ShowLightGizmo}; } +use bevy_app::{App, Last, Plugin}; +#[cfg(feature = "fixed_update")] +use bevy_app::{FixedFirst, FixedLast, RunFixedMainLoop}; +use bevy_asset::{Asset, AssetApp, Assets, Handle}; +use bevy_color::LinearRgba; +#[cfg(feature = "bevy_render")] +use bevy_ecs::component::Component; #[cfg(feature = "bevy_render")] use bevy_ecs::{ query::ROQueryItem, @@ -77,12 +84,6 @@ use bevy_ecs::{ Commands, SystemParamItem, }, }; - -use bevy_app::{App, FixedFirst, FixedLast, Last, Plugin, RunFixedMainLoop}; -use bevy_asset::{Asset, AssetApp, Assets, Handle}; -use bevy_color::LinearRgba; -#[cfg(feature = "bevy_render")] -use bevy_ecs::component::Component; use bevy_ecs::{ schedule::{IntoSystemConfigs, SystemSet}, system::{Res, ResMut, Resource}, diff --git a/crates/bevy_time/src/fixed.rs b/crates/bevy_time/src/fixed.rs index 4bb165c3bdda5..88039529e68bd 100644 --- a/crates/bevy_time/src/fixed.rs +++ b/crates/bevy_time/src/fixed.rs @@ -1,11 +1,14 @@ #[cfg(feature = "fixed_update")] use bevy_app::FixedMain; +#[cfg(feature = "fixed_update")] use bevy_ecs::world::World; #[cfg(feature = "bevy_reflect")] use bevy_reflect::Reflect; use bevy_utils::Duration; -use crate::{time::Time, virt::Virtual}; +use crate::time::Time; +#[cfg(feature = "fixed_update")] +use crate::virt::Virtual; /// The fixed timestep game clock following virtual time. /// @@ -206,10 +209,12 @@ impl Time { self.context().overstep.as_secs_f64() / self.context().timestep.as_secs_f64() } + #[cfg(feature = "fixed_update")] fn accumulate(&mut self, delta: Duration) { self.context_mut().overstep += delta; } + #[cfg(feature = "fixed_update")] fn expend(&mut self) -> bool { let timestep = self.timestep(); if let Some(new_value) = self.context_mut().overstep.checked_sub(timestep) { @@ -253,6 +258,7 @@ pub(super) fn run_fixed_main_schedule(world: &mut World) { *world.resource_mut::