Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"]

Expand Down
3 changes: 2 additions & 1 deletion crates/bevy_app/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
10 changes: 7 additions & 3 deletions crates/bevy_app/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
60 changes: 37 additions & 23 deletions crates/bevy_app/src/main_schedule.rs
Original file line number Diff line number Diff line change
@@ -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:
Expand Down Expand Up @@ -85,20 +83,23 @@ 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;

/// Runs first in the [`FixedMain`] 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 FixedFirst;

/// The schedule that contains logic that must run before [`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 FixedPreUpdate;

Expand All @@ -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;

Expand All @@ -122,13 +124,15 @@ 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;

/// The schedule that runs last in [`FixedMain`]
///
/// 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;

Expand All @@ -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;

Expand Down Expand Up @@ -196,6 +201,7 @@ impl Default for MainScheduleOrder {
labels: vec![
First.intern(),
PreUpdate.intern(),
#[cfg(feature = "fixed_time")]
RunFixedMainLoop.intern(),
Update.intern(),
SpawnScene.intern(),
Expand Down Expand Up @@ -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::<MainScheduleOrder>()
.init_resource::<FixedMainScheduleOrder>()
.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::<FixedMainScheduleOrder>()
.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};
Expand All @@ -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<InternedScheduleLabel>,
}

#[cfg(feature = "fixed_time")]
impl Default for FixedMainScheduleOrder {
fn default() -> Self {
Self {
Expand All @@ -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) {
Expand All @@ -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) {
Expand All @@ -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.
Expand Down
2 changes: 2 additions & 0 deletions crates/bevy_gizmos/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
35 changes: 27 additions & 8 deletions crates/bevy_gizmos/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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},
Expand Down Expand Up @@ -249,8 +252,11 @@ impl AppGizmoBuilder for App {

self.init_resource::<GizmoStorage<Config, ()>>()
.init_resource::<GizmoStorage<Config, Fixed>>()
.init_resource::<GizmoStorage<Config, Swap<Fixed>>>()
.add_systems(
.init_resource::<GizmoStorage<Config, Swap<Fixed>>>();

#[cfg(feature = "fixed_time")]
{
self.add_systems(
RunFixedMainLoop,
start_gizmo_context::<Config, Fixed>
.in_set(bevy_app::RunFixedMainLoopSystem::BeforeFixedMainLoop),
Expand All @@ -269,6 +275,19 @@ impl AppGizmoBuilder for App {
update_gizmo_meshes::<Config>.in_set(UpdateGizmoMeshes),
),
);
}
#[cfg(not(feature = "fixed_time"))]
{
self.add_systems(First, clear_gizmo_context::<Config, Fixed>)
.add_systems(
Last,
(
collect_requested_gizmos::<Config, Fixed>,
propagate_gizmos::<Config, Fixed>.before(UpdateGizmoMeshes),
update_gizmo_meshes::<Config>.in_set(UpdateGizmoMeshes),
),
);
}

self
}
Expand Down
7 changes: 7 additions & 0 deletions crates/bevy_internal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
Expand Down
3 changes: 2 additions & 1 deletion crates/bevy_time/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
15 changes: 13 additions & 2 deletions crates/bevy_time/src/fixed.rs
Original file line number Diff line number Diff line change
@@ -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<Fixed>#impl-Time<Fixed>`].**
///
///
/// It is automatically inserted as a resource by
/// [`TimePlugin`](crate::TimePlugin) and updated based on
/// [`Time<Virtual>`](Virtual). The fixed clock is automatically set as the
Expand Down Expand Up @@ -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<Fixed> {
/// Corresponds to 64 Hz.
const DEFAULT_TIMESTEP: Duration = Duration::from_micros(15625);
Expand Down Expand Up @@ -205,10 +211,12 @@ impl Time<Fixed> {
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) {
Expand All @@ -223,6 +231,7 @@ impl Time<Fixed> {
}
}

#[cfg(feature = "fixed_time")]
impl Default for Fixed {
fn default() -> Self {
Self {
Expand All @@ -236,6 +245,7 @@ impl Default for Fixed {
/// [`Time<Virtual>`](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::<Time<Virtual>>().delta();
world.resource_mut::<Time<Fixed>>().accumulate(delta);
Expand All @@ -251,6 +261,7 @@ pub(super) fn run_fixed_main_schedule(world: &mut World) {
*world.resource_mut::<Time>() = world.resource::<Time<Virtual>>().as_generic();
}

#[cfg(feature = "fixed_time")]
#[cfg(test)]
mod test {
use super::*;
Expand Down
Loading