Skip to content

Commit

Permalink
Removed live_real_ fns, changed real_ to raw_, added Time.fixedTime e…
Browse files Browse the repository at this point in the history
…quiv. with tests

When comparing dilated and raw delta/elapsed time measurements, be aware that `relative_speed` != 1.0 may have rounding errors, so the ratios might not be perfect.
  • Loading branch information
maniwani committed Nov 6, 2021
1 parent 6088d05 commit f9da443
Show file tree
Hide file tree
Showing 4 changed files with 270 additions and 159 deletions.
54 changes: 28 additions & 26 deletions crates/bevy_core/src/time/fixed_timestep.rs
Original file line number Diff line number Diff line change
@@ -1,39 +1,48 @@
use bevy_ecs::{schedule::ShouldRun, system::ResMut};

use bevy_utils::Duration;

use crate::Time;

#[derive(Debug, Clone)]
pub struct FixedTimestepState {
time: Duration,
steps: usize,
steps: u32,
}

impl Default for FixedTimestepState {
fn default() -> Self {
Self {
time: Duration::from_secs(0),
time: Duration::ZERO,
steps: 0,
}
}
}

impl FixedTimestepState {
pub fn new(time: Duration, steps: usize) -> Self {
pub fn new(time: Duration, steps: u32) -> Self {
Self { time, steps }
}

/// The number of accrued steps.
#[inline]
pub fn steps(&self) -> usize {
pub fn steps(&self) -> u32 {
self.steps
}

/// The amount of time accrued toward the next step as [`Duration`].
/// The amount of time accrued toward new steps as [`Duration`].
#[inline]
pub fn overstep(&self) -> Duration {
pub fn time(&self) -> Duration {
self.time
}

pub fn set_steps(&mut self, steps: u32) {
self.steps = steps;
}

pub fn set_time(&mut self, time: Duration) {
self.time = time;
}

/// The amount of time accrued toward the next step as [`f32`] % of timestep.
pub fn overstep_percentage(&self, timestep: Duration) -> f32 {
self.time.as_secs_f32() / timestep.as_secs_f32()
Expand All @@ -44,7 +53,7 @@ impl FixedTimestepState {
self.time.as_secs_f64() / timestep.as_secs_f64()
}

/// Add to the stored time, then convert into as many steps as possible.
/// Add to the accrued time, then convert into as many steps as possible.
pub fn add_time(&mut self, time: Duration, timestep: Duration) {
self.time += time;
while self.time >= timestep {
Expand All @@ -54,31 +63,24 @@ impl FixedTimestepState {
}

/// Consume a stored step (if any).
pub fn sub_step(&mut self) -> Option<usize> {
pub fn sub_step(&mut self) -> Option<u32> {
let remaining = self.steps.checked_sub(1);
self.steps = self.steps.saturating_sub(1);
remaining
}

pub fn set_time(&mut self, time: Duration) {
self.time = time;
}

pub fn set_steps(&mut self, steps: usize) {
self.steps = steps;
}

pub fn reset(&mut self) {
self.time = Duration::from_secs(0);
self.time = Duration::ZERO;
self.steps = 0;
}
}

pub struct FixedTimestep;

impl FixedTimestep {
pub fn step(mut accumulator: ResMut<FixedTimestepState>) -> ShouldRun {
pub fn step(mut time: ResMut<Time>, mut accumulator: ResMut<FixedTimestepState>) -> ShouldRun {
if accumulator.sub_step().is_some() {
time.advance_step();
ShouldRun::YesAndCheckAgain
} else {
ShouldRun::No
Expand All @@ -96,38 +98,38 @@ mod tests {
let mut accumulator = FixedTimestepState::default();

assert_eq!(accumulator.steps(), 0);
assert_eq!(accumulator.overstep(), Duration::from_secs(0));
assert_eq!(accumulator.time(), Duration::ZERO);

accumulator.add_time(Duration::from_secs(5), Duration::from_secs(1));

assert_eq!(accumulator.steps(), 5);
assert_eq!(accumulator.overstep(), Duration::from_secs(0));
assert_eq!(accumulator.time(), Duration::ZERO);

let steps_remaining = accumulator.sub_step();

assert_eq!(steps_remaining, Some(4));
assert_eq!(accumulator.steps(), 4);
assert_eq!(accumulator.overstep(), Duration::from_secs(0));
assert_eq!(accumulator.time(), Duration::ZERO);

accumulator.set_time(Duration::from_secs(1));

assert_eq!(accumulator.steps(), 4);
assert_eq!(accumulator.overstep(), Duration::from_secs(1));
assert_eq!(accumulator.time(), Duration::from_secs(1));

accumulator.set_steps(12);

assert_eq!(accumulator.steps(), 12);
assert_eq!(accumulator.overstep(), Duration::from_secs(1));
assert_eq!(accumulator.time(), Duration::from_secs(1));

accumulator.reset();

assert_eq!(accumulator.steps(), 0);
assert_eq!(accumulator.overstep(), Duration::from_secs(0));
assert_eq!(accumulator.time(), Duration::ZERO);

let steps_remaining = accumulator.sub_step();

assert_eq!(steps_remaining, None);
assert_eq!(accumulator.steps(), 0);
assert_eq!(accumulator.overstep(), Duration::from_secs(0));
assert_eq!(accumulator.time(), Duration::ZERO);
}
}
Loading

0 comments on commit f9da443

Please sign in to comment.