gemini-mainloop 0.2.0

An engine-agnostic mainloop abstraction library
Documentation
use std::{thread::sleep, time::Duration};

/// Sleep for `1 / fps` seconds, accounting for elapsed time to maintain the desired FPS.
///
/// Returns a `bool` indicating whether the frame took longer to render than the intended fps wait, meaning the frame overall took too long to process to maintain the desired FPS.
/// ## Example
/// ```no_run
/// use gemini_engine::gameloop;
/// use std::time::Instant;
///
/// let mut frame_skip = false;
/// const FPS: f32 = 60.0;
/// loop {
///     let now = Instant::now();
///
///     // all code here will run at 60 FPS
///
///     if !frame_skip {
///         // calculations and rendering. will not be run if the previous frame was too slow to maintain 60 FPS
///     }
///
///     frame_skip = gameloop::sleep_fps(FPS, Some(now.elapsed()));
/// }
/// ```
#[allow(clippy::must_use_candidate)]
pub fn sleep_fps(fps: f32, elapsed: Option<Duration>) -> bool {
    let elapsed = elapsed.unwrap_or(Duration::ZERO);
    let frame_length = Duration::from_secs_f32(1.0 / fps);
    if frame_length > elapsed {
        sleep(frame_length - elapsed);
        false
    } else {
        true
    }
}