use std::time::{Instant, Duration};
use std::thread;
#[derive(Copy, Clone)]
pub struct LoopState {
pub delta : Duration,
pub delta_f32 : f32,
pub elapsed : Duration,
pub elapsed_f32 : f32,
pub frame_id : u64,
pub fps : u32,
pub state_id : u32,
}
pub fn mainloop<F, G>(interval: Duration, mut state_callback: F, mut render_callback: G) where F: FnMut(LoopState) -> bool, G: FnMut(LoopState) -> bool {
let mut accumulator = Duration::new(0, 0);
let mut previous_clock = Instant::now();
let start_clock = previous_clock;
let second = Duration::new(1, 0);
let mut second_elapsed = Duration::new(0, 0);
let mut frames_elapsed = 0;
let mut fps = 0;
let mut frame_id = 0;
loop {
let now = Instant::now();
let delta = now - previous_clock;
let elapsed = now - start_clock;
let mut state_info = LoopState {
delta : delta,
delta_f32 : delta.as_secs() as f32 + (delta.subsec_nanos() as f64 / 1000000000.0) as f32,
elapsed : elapsed,
elapsed_f32 : elapsed.as_secs() as f32 + (elapsed.subsec_nanos() as f64 / 1000000000.0) as f32,
frame_id : frame_id,
fps : fps,
state_id : 0,
};
if render_callback(state_info) == false {
break;
}
accumulator += delta;
while accumulator >= interval {
accumulator -= interval;
if state_callback(state_info) == false {
break;
}
state_info.state_id += 1;
}
second_elapsed += now - previous_clock;
frames_elapsed += 1;
frame_id += 1;
if second_elapsed >= second {
fps = frames_elapsed;
second_elapsed -= second;
frames_elapsed = 0;
}
previous_clock = now;
thread::sleep(interval - accumulator);
}
}
pub fn renderloop<G>(mut render_callback: G) where G: FnMut(LoopState) -> bool {
let mut previous_clock = Instant::now();
let start_clock = previous_clock;
let second = Duration::new(1, 0);
let mut second_elapsed = Duration::new(0, 0);
let mut frames_elapsed = 0;
let mut fps = 0;
let mut frame_id = 0;
loop {
let now = Instant::now();
let delta = now - previous_clock;
let elapsed = now - start_clock;
let state_info = LoopState {
delta : delta,
delta_f32 : delta.as_secs() as f32 + (delta.subsec_nanos() as f64 / 1000000000.0) as f32,
elapsed : elapsed,
elapsed_f32 : elapsed.as_secs() as f32 + (elapsed.subsec_nanos() as f64 / 1000000000.0) as f32,
frame_id : frame_id,
fps : fps,
state_id : 0,
};
if render_callback(state_info) == false {
break;
}
second_elapsed += now - previous_clock;
frames_elapsed += 1;
frame_id += 1;
if second_elapsed >= second {
fps = frames_elapsed;
second_elapsed -= second;
frames_elapsed = 0;
}
previous_clock = now;
}
}