1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
use std::thread;
use std::cell::RefCell;
use std::time::Duration;

use super::super::{now, ControlFlow};

thread_local!(
    static MAIN_TARGET_FPS: RefCell<f64> = RefCell::new(1000_f64 / 60_f64);
);

#[inline]
pub fn set_target_fps(target_fps: f64) {
    MAIN_TARGET_FPS.with(|ref_cell| {
        *ref_cell.borrow_mut() = 1000_f64 / target_fps;
    });
}

#[inline(always)]
pub fn target_fps() -> f64 {
    MAIN_TARGET_FPS.with(|ref_cell| *ref_cell.borrow())
}

#[inline]
pub fn run<F>(mut callback: F)
where
    F: FnMut(f64) -> ControlFlow,
{
    let run_start_time = now();
    let mut is_looping = true;

    while is_looping {
        let ms = now() - run_start_time;

        match callback(ms) {
            ControlFlow::Break => is_looping = false,
            ControlFlow::Continue => (),
        }

        let target_fps = MAIN_TARGET_FPS.with(|ref_cell| *ref_cell.borrow());
        let delta = target_fps - ((now() - run_start_time) - ms);
        if delta > 0.0 {
            thread::sleep(Duration::from_millis(delta as u64));
        }
    }
}