use std::time::Duration;
use bevy_core::Time;
use bevy_ecs::prelude::*;
pub struct FixedTimestepStage {
step: Duration,
accumulator: Duration,
stages: Vec<Box<dyn Stage>>,
}
impl FixedTimestepStage {
pub fn from_stage<S: Stage>(timestep: Duration, stage: S) -> Self {
Self {
step: timestep,
accumulator: Duration::default(),
stages: vec![Box::new(stage)],
}
}
pub fn new(timestep: Duration) -> Self {
Self {
step: timestep,
accumulator: Duration::default(),
stages: Vec::new(),
}
}
pub fn add_stage<S: Stage>(&mut self, stage: S) {
self.stages.push(Box::new(stage));
}
pub fn with_stage<S: Stage>(mut self, stage: S) -> Self {
self.add_stage(stage);
self
}
}
impl Stage for FixedTimestepStage {
fn run(&mut self, world: &mut World) {
self.accumulator += {
let time = world.get_resource::<Time>();
if let Some(time) = time {
time.delta()
} else {
return;
}
};
while self.accumulator >= self.step {
self.accumulator -= self.step;
for stage in self.stages.iter_mut() {
stage.run(world);
}
}
}
}