Skip to content

Commit de8edd3

Browse files
committed
Rename fixed timestep state and add a test (#3260)
# Objective fixes #3234 ## Solution - rename `bevy::core::State` to `LocalFixedTimestepState` - add a test for FixedTimestep since I am already there
1 parent fe9b500 commit de8edd3

File tree

1 file changed

+86
-8
lines changed

1 file changed

+86
-8
lines changed

crates/bevy_core/src/time/fixed_timestep.rs

Lines changed: 86 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use bevy_ecs::{
1010
use bevy_utils::HashMap;
1111
use std::borrow::Cow;
1212

13+
#[derive(Debug)]
1314
pub struct FixedTimestepState {
1415
pub step: f64,
1516
pub accumulator: f64,
@@ -49,14 +50,14 @@ impl FixedTimesteps {
4950
}
5051

5152
pub struct FixedTimestep {
52-
state: State,
53+
state: LocalFixedTimestepState,
5354
internal_system: Box<dyn System<In = (), Out = ShouldRun>>,
5455
}
5556

5657
impl Default for FixedTimestep {
5758
fn default() -> Self {
5859
Self {
59-
state: State::default(),
60+
state: LocalFixedTimestepState::default(),
6061
internal_system: Box::new(Self::prepare_system.system()),
6162
}
6263
}
@@ -65,7 +66,7 @@ impl Default for FixedTimestep {
6566
impl FixedTimestep {
6667
pub fn step(step: f64) -> Self {
6768
Self {
68-
state: State {
69+
state: LocalFixedTimestepState {
6970
step,
7071
..Default::default()
7172
},
@@ -75,7 +76,7 @@ impl FixedTimestep {
7576

7677
pub fn steps_per_second(rate: f64) -> Self {
7778
Self {
78-
state: State {
79+
state: LocalFixedTimestepState {
7980
step: 1.0 / rate,
8081
..Default::default()
8182
},
@@ -89,7 +90,7 @@ impl FixedTimestep {
8990
}
9091

9192
fn prepare_system(
92-
mut state: Local<State>,
93+
mut state: Local<LocalFixedTimestepState>,
9394
time: Res<Time>,
9495
mut fixed_timesteps: ResMut<FixedTimesteps>,
9596
) -> ShouldRun {
@@ -105,14 +106,14 @@ impl FixedTimestep {
105106
}
106107

107108
#[derive(Clone)]
108-
pub struct State {
109+
pub struct LocalFixedTimestepState {
109110
label: Option<String>, // TODO: consider making this a TypedLabel
110111
step: f64,
111112
accumulator: f64,
112113
looping: bool,
113114
}
114115

115-
impl Default for State {
116+
impl Default for LocalFixedTimestepState {
116117
fn default() -> Self {
117118
Self {
118119
step: 1.0 / 60.0,
@@ -123,7 +124,7 @@ impl Default for State {
123124
}
124125
}
125126

126-
impl State {
127+
impl LocalFixedTimestepState {
127128
fn update(&mut self, time: &Time) -> ShouldRun {
128129
if !self.looping {
129130
self.accumulator += time.delta_seconds_f64();
@@ -194,3 +195,80 @@ impl System for FixedTimestep {
194195
self.internal_system.check_change_tick(change_tick);
195196
}
196197
}
198+
199+
#[cfg(test)]
200+
mod test {
201+
use super::*;
202+
use bevy_ecs::prelude::*;
203+
use bevy_utils::Instant;
204+
use std::ops::{Add, Mul};
205+
use std::time::Duration;
206+
207+
type Count = usize;
208+
const LABEL: &str = "test_step";
209+
210+
#[test]
211+
fn test() {
212+
let mut world = World::default();
213+
let mut time = Time::default();
214+
let instance = Instant::now();
215+
time.update_with_instant(instance);
216+
world.insert_resource(time);
217+
world.insert_resource(FixedTimesteps::default());
218+
world.insert_resource::<Count>(0);
219+
let mut schedule = Schedule::default();
220+
221+
schedule.add_stage(
222+
"update",
223+
SystemStage::parallel()
224+
.with_run_criteria(FixedTimestep::step(0.5).with_label(LABEL))
225+
.with_system(fixed_update),
226+
);
227+
228+
// if time does not progress, the step does not run
229+
schedule.run(&mut world);
230+
schedule.run(&mut world);
231+
assert_eq!(0, *world.get_resource::<Count>().unwrap());
232+
assert_eq!(0., get_accumulator_deciseconds(&world));
233+
234+
// let's progress less than one step
235+
advance_time(&mut world, instance, 0.4);
236+
schedule.run(&mut world);
237+
assert_eq!(0, *world.get_resource::<Count>().unwrap());
238+
assert_eq!(4., get_accumulator_deciseconds(&world));
239+
240+
// finish the first step with 0.1s above the step length
241+
advance_time(&mut world, instance, 0.6);
242+
schedule.run(&mut world);
243+
assert_eq!(1, *world.get_resource::<Count>().unwrap());
244+
assert_eq!(1., get_accumulator_deciseconds(&world));
245+
246+
// runs multiple times if the delta is multiple step lengths
247+
advance_time(&mut world, instance, 1.7);
248+
schedule.run(&mut world);
249+
assert_eq!(3, *world.get_resource::<Count>().unwrap());
250+
assert_eq!(2., get_accumulator_deciseconds(&world));
251+
}
252+
253+
fn fixed_update(mut count: ResMut<Count>) {
254+
*count += 1;
255+
}
256+
257+
fn advance_time(world: &mut World, instance: Instant, seconds: f32) {
258+
world
259+
.get_resource_mut::<Time>()
260+
.unwrap()
261+
.update_with_instant(instance.add(Duration::from_secs_f32(seconds)));
262+
}
263+
264+
fn get_accumulator_deciseconds(world: &World) -> f64 {
265+
world
266+
.get_resource::<FixedTimesteps>()
267+
.unwrap()
268+
.get(LABEL)
269+
.unwrap()
270+
.accumulator
271+
.mul(10.)
272+
.round()
273+
}
274+
}

0 commit comments

Comments
 (0)