main_loop 0.3.3

main loop for real time applications
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));
        }
    }
}