use std::collections::VecDeque;
use std::time::Duration;
use crate::Context;
#[derive(Debug, Copy, Clone)]
#[cfg_attr(
feature = "serde_support",
derive(serde::Serialize, serde::Deserialize)
)]
pub enum Timestep {
Fixed(f64),
Variable,
}
pub(crate) struct TimeContext {
pub(crate) fps_tracker: VecDeque<f64>,
pub(crate) ticks_per_second: Option<f64>,
pub(crate) tick_rate: Option<Duration>,
pub(crate) delta_time: Duration,
pub(crate) accumulator: Duration,
}
impl TimeContext {
pub(crate) fn new(timestep: Timestep) -> TimeContext {
let mut fps_tracker = VecDeque::with_capacity(200);
fps_tracker.resize(200, 1.0 / 60.0);
let ticks_per_second = match timestep {
Timestep::Fixed(tps) => Some(tps),
Timestep::Variable => None,
};
let tick_rate = match timestep {
Timestep::Fixed(tps) => Some(Duration::from_secs_f64(1.0 / tps)),
Timestep::Variable => None,
};
TimeContext {
fps_tracker,
ticks_per_second,
tick_rate,
delta_time: Duration::from_secs(0),
accumulator: Duration::from_secs(0),
}
}
}
pub(crate) fn reset(ctx: &mut Context) {
ctx.time.delta_time = Duration::from_secs(0);
ctx.time.accumulator = Duration::from_secs(0);
}
pub fn get_delta_time(ctx: &Context) -> Duration {
ctx.time.delta_time
}
pub fn get_accumulator(ctx: &Context) -> Duration {
ctx.time.accumulator
}
pub fn get_blend_factor(ctx: &Context) -> f32 {
match ctx.time.tick_rate {
Some(tick_rate) => ctx.time.accumulator.as_secs_f32() / tick_rate.as_secs_f32(),
None => 0.0,
}
}
pub fn get_blend_factor_precise(ctx: &Context) -> f64 {
match ctx.time.tick_rate {
Some(tick_rate) => ctx.time.accumulator.as_secs_f64() / tick_rate.as_secs_f64(),
None => 0.0,
}
}
pub fn get_timestep(ctx: &Context) -> Timestep {
match ctx.time.ticks_per_second {
Some(tps) => Timestep::Fixed(tps),
None => Timestep::Variable,
}
}
pub fn set_timestep(ctx: &mut Context, timestep: Timestep) {
ctx.time.ticks_per_second = match timestep {
Timestep::Fixed(tps) => Some(tps),
Timestep::Variable => None,
};
ctx.time.tick_rate = match timestep {
Timestep::Fixed(tps) => Some(Duration::from_secs_f64(1.0 / tps)),
Timestep::Variable => None,
};
}
pub fn get_fps(ctx: &Context) -> f64 {
1.0 / (ctx.time.fps_tracker.iter().sum::<f64>() / ctx.time.fps_tracker.len() as f64)
}