diff --git a/Cargo.toml b/Cargo.toml index 0609e02c33e14..a5fbaa57b09fe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -85,8 +85,12 @@ default = [ "default_font", "webgl2", "sysinfo_plugin", + "fixed_time", ] +# Provides the fixed update schedules +fixed_time = ["bevy_internal/fixed_time"] + # Force dynamic linking, which improves iterative compile times dynamic_linking = ["dep:bevy_dylib", "bevy_internal/dynamic_linking"] diff --git a/crates/bevy_app/Cargo.toml b/crates/bevy_app/Cargo.toml index 758654b656695..6b34fc078666c 100644 --- a/crates/bevy_app/Cargo.toml +++ b/crates/bevy_app/Cargo.toml @@ -11,13 +11,14 @@ keywords = ["bevy"] [features] trace = [] bevy_debug_stepping = [] -default = ["bevy_reflect"] +default = ["bevy_reflect", "fixed_time"] bevy_reflect = ["dep:bevy_reflect", "bevy_ecs/bevy_reflect"] reflect_functions = [ "bevy_reflect", "bevy_reflect/functions", "bevy_ecs/reflect_functions", ] +fixed_time = [] [dependencies] # bevy diff --git a/crates/bevy_app/src/lib.rs b/crates/bevy_app/src/lib.rs index 8ea7c0e767566..bad7e10f8a7b2 100644 --- a/crates/bevy_app/src/lib.rs +++ b/crates/bevy_app/src/lib.rs @@ -31,13 +31,17 @@ pub use terminal_ctrl_c_handler::*; /// /// This includes the most common types in this crate, re-exported for your convenience. pub mod prelude { + #[cfg(feature = "fixed_time")] + pub use crate::main_schedule::{ + FixedFirst, FixedLast, FixedPostUpdate, FixedPreUpdate, FixedUpdate, RunFixedMainLoop, + RunFixedMainLoopSystem, + }; #[doc(hidden)] pub use crate::{ app::{App, AppExit}, main_schedule::{ - First, FixedFirst, FixedLast, FixedPostUpdate, FixedPreUpdate, FixedUpdate, Last, Main, - PostStartup, PostUpdate, PreStartup, PreUpdate, RunFixedMainLoop, - RunFixedMainLoopSystem, SpawnScene, Startup, Update, + First, Last, Main, PostStartup, PostUpdate, PreStartup, PreUpdate, SpawnScene, Startup, + Update, }, sub_app::SubApp, Plugin, PluginGroup, diff --git a/crates/bevy_app/src/main_schedule.rs b/crates/bevy_app/src/main_schedule.rs index 3ee0a07a746d2..57064a9309044 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_time")] +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_time")] #[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_time")] #[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_time")] #[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_time")] #[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_time")] #[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_time")] #[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_time")] #[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_time")] RunFixedMainLoop.intern(), Update.intern(), SpawnScene.intern(), @@ -285,28 +291,31 @@ 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); 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_time")] + { + 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::() + .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 +326,14 @@ impl Plugin for MainSchedulePlugin { /// Defines the schedules to be run for the [`FixedMain`] schedule, including /// their order. +#[cfg(feature = "fixed_time")] #[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_time")] impl Default for FixedMainScheduleOrder { fn default() -> Self { Self { @@ -337,6 +348,7 @@ impl Default for FixedMainScheduleOrder { } } +#[cfg(feature = "fixed_time")] impl FixedMainScheduleOrder { /// Adds the given `schedule` after the `after` schedule pub fn insert_after(&mut self, after: impl ScheduleLabel, schedule: impl ScheduleLabel) { @@ -359,6 +371,7 @@ impl FixedMainScheduleOrder { } } +#[cfg(feature = "fixed_time")] impl FixedMain { /// A system that runs the fixed timestep's "main schedule" pub fn run_fixed_main(world: &mut World) { @@ -381,6 +394,7 @@ impl FixedMain { /// /// Note that in contrast to most other Bevy schedules, systems added directly to /// [`RunFixedMainLoop`] will *not* be parallelized between each other. +#[cfg(feature = "fixed_time")] #[derive(Debug, Hash, PartialEq, Eq, Copy, Clone, SystemSet)] pub enum RunFixedMainLoopSystem { /// Runs before the fixed update logic. diff --git a/crates/bevy_gizmos/Cargo.toml b/crates/bevy_gizmos/Cargo.toml index 5f79b93d3a266..385084cf3b74b 100644 --- a/crates/bevy_gizmos/Cargo.toml +++ b/crates/bevy_gizmos/Cargo.toml @@ -9,8 +9,10 @@ license = "MIT OR Apache-2.0" keywords = ["bevy"] [features] +default = ["fixed_time"] webgl = [] webgpu = [] +fixed_time = ["bevy_app/fixed_time"] 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 bbef44df46677..1dc284ba54501 100644 --- a/crates/bevy_gizmos/src/lib.rs +++ b/crates/bevy_gizmos/src/lib.rs @@ -72,6 +72,15 @@ pub mod prelude { pub use crate::light::{LightGizmoColor, LightGizmoConfigGroup, ShowLightGizmo}; } +#[cfg(not(feature = "fixed_time"))] +use bevy_app::First; +use bevy_app::{App, Last, Plugin}; +#[cfg(feature = "fixed_time")] +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, @@ -80,12 +89,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}, @@ -249,8 +252,11 @@ impl AppGizmoBuilder for App { self.init_resource::>() .init_resource::>() - .init_resource::>>() - .add_systems( + .init_resource::>>(); + + #[cfg(feature = "fixed_time")] + { + self.add_systems( RunFixedMainLoop, start_gizmo_context:: .in_set(bevy_app::RunFixedMainLoopSystem::BeforeFixedMainLoop), @@ -269,6 +275,19 @@ impl AppGizmoBuilder for App { update_gizmo_meshes::.in_set(UpdateGizmoMeshes), ), ); + } + #[cfg(not(feature = "fixed_time"))] + { + self.add_systems(First, clear_gizmo_context::) + .add_systems( + Last, + ( + collect_requested_gizmos::, + propagate_gizmos::.before(UpdateGizmoMeshes), + update_gizmo_meshes::.in_set(UpdateGizmoMeshes), + ), + ); + } self } diff --git a/crates/bevy_internal/Cargo.toml b/crates/bevy_internal/Cargo.toml index 2cd6e22162319..defcb4b48b44a 100644 --- a/crates/bevy_internal/Cargo.toml +++ b/crates/bevy_internal/Cargo.toml @@ -21,6 +21,13 @@ trace = [ "bevy_hierarchy/trace", "bevy_winit?/trace", ] + +fixed_time = [ + "bevy_gizmos/fixed_time", + "bevy_app/fixed_time", + "bevy_time/fixed_time", +] + trace_chrome = ["bevy_log/tracing-chrome"] trace_tracy = ["bevy_render?/tracing-tracy", "bevy_log/tracing-tracy"] trace_tracy_memory = ["bevy_log/trace_tracy_memory"] diff --git a/crates/bevy_time/Cargo.toml b/crates/bevy_time/Cargo.toml index 93d14281198d0..94cee61cfe3fb 100644 --- a/crates/bevy_time/Cargo.toml +++ b/crates/bevy_time/Cargo.toml @@ -9,8 +9,9 @@ license = "MIT OR Apache-2.0" keywords = ["bevy"] [features] -default = ["bevy_reflect"] +default = ["bevy_reflect", "fixed_time"] serialize = ["serde"] +fixed_time = ["bevy_app/fixed_time"] [dependencies] # bevy diff --git a/crates/bevy_time/src/fixed.rs b/crates/bevy_time/src/fixed.rs index 4b60461e34791..c0aed88e4f1ab 100644 --- a/crates/bevy_time/src/fixed.rs +++ b/crates/bevy_time/src/fixed.rs @@ -1,16 +1,20 @@ +#[cfg(feature = "fixed_time")] use bevy_app::FixedMain; +#[cfg(feature = "fixed_time")] 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_time")] +use crate::virt::Virtual; /// The fixed timestep game clock following virtual time. /// /// A specialization of the [`Time`] structure. **For method documentation, see /// [`Time#impl-Time`].** -/// +/// /// It is automatically inserted as a resource by /// [`TimePlugin`](crate::TimePlugin) and updated based on /// [`Time`](Virtual). The fixed clock is automatically set as the @@ -65,12 +69,14 @@ use crate::{time::Time, virt::Virtual}; /// frame. Any [`overstep()`](Time::overstep) present in the accumulator will be /// processed according to the new [`timestep()`](Time::timestep) value. #[derive(Debug, Copy, Clone)] +#[cfg(feature = "fixed_time")] #[cfg_attr(feature = "bevy_reflect", derive(Reflect))] pub struct Fixed { timestep: Duration, overstep: Duration, } +#[cfg(feature = "fixed_time")] impl Time { /// Corresponds to 64 Hz. const DEFAULT_TIMESTEP: Duration = Duration::from_micros(15625); @@ -205,10 +211,12 @@ impl Time { self.context().overstep.as_secs_f64() / self.context().timestep.as_secs_f64() } + #[cfg(feature = "fixed_time")] fn accumulate(&mut self, delta: Duration) { self.context_mut().overstep += delta; } + #[cfg(feature = "fixed_time")] fn expend(&mut self) -> bool { let timestep = self.timestep(); if let Some(new_value) = self.context_mut().overstep.checked_sub(timestep) { @@ -223,6 +231,7 @@ impl Time { } } +#[cfg(feature = "fixed_time")] impl Default for Fixed { fn default() -> Self { Self { @@ -236,6 +245,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_time")] pub(super) fn run_fixed_main_schedule(world: &mut World) { let delta = world.resource::>().delta(); world.resource_mut::>().accumulate(delta); @@ -251,6 +261,7 @@ pub(super) fn run_fixed_main_schedule(world: &mut World) { *world.resource_mut::