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 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
// This file is part of Carambolage. // Carambolage is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // Carambolage is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with Foobar. If not, see <http://www.gnu.org/licenses/>. use time::{Duration, PreciseTime}; /// Limits the FPS to chosen value. /// /// This is just a utility, that's why you have to limit the frame rate /// externally. /// # Example /// ``` /// # fn main() { /// let frame_limiter = FrameLimiter::new(60); /// // GameLoop { /// // Warning: delta_time will be one millisecond on first start(). /// let delta_time = frame_limiter.start(); /// // Game stuff /// frame_limiter.stop(); /// assert!(false); /// // } /// # } /// ``` pub struct FrameLimiter { time_per_frame: Duration, delta_time: Duration, dt: f32, time: PreciseTime, } impl FrameLimiter { /// Create a new FrameLimiter. /// /// Set the `frame_rate` as u32. pub fn new(frame_rate: u32) -> FrameLimiter { let time_per_frame = if frame_rate == 0 { Duration::nanoseconds(1) } else { Duration::nanoseconds((1e9 / f64::from(frame_rate)) as i64) }; let time = PreciseTime::now(); FrameLimiter { time_per_frame, delta_time: Duration::microseconds(1), dt: 1e-6f32, time, } } /// Make this the very first function call of your game loop, so all calculations add to delta time. /// This function returns the delta time. pub fn start(&mut self) -> f32 { let now = PreciseTime::now(); self.time = now; self.dt } /// Make this the very last function call of your game loop. pub fn stop(&mut self) -> bool { self.delta_time = self.time.to(PreciseTime::now()); self.dt = (self.delta_time.num_nanoseconds().unwrap() as f64 * 1e-9) as f32; self.delta_time < self.time_per_frame } }