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 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
use crate::*; pub struct GameLoop<G, T: TimeTrait, W> { pub game: G, pub updates_per_second: u32, pub max_frame_time: f64, pub exit_next_iteration: bool, pub window: W, fixed_time_step: f64, number_of_updates: u32, number_of_renders: u32, last_frame_time: f64, running_time: f64, accumulated_time: f64, blending_factor: f64, previous_instant: T, current_instant: T, } impl<G, T: TimeTrait, W> GameLoop<G, T, W> { pub fn new(game: G, updates_per_second: u32, max_frame_time: f64, window: W) -> Self { Self { game, updates_per_second, max_frame_time, window, exit_next_iteration: false, fixed_time_step: 1.0 / updates_per_second as f64, number_of_updates: 0, number_of_renders: 0, running_time: 0.0, accumulated_time: 0.0, blending_factor: 0.0, previous_instant: T::now(), current_instant: T::now(), last_frame_time: 0.0, } } pub fn next_frame<U, R>(&mut self, mut update: U, mut render: R) -> bool where U: FnMut(&mut GameLoop<G, T, W>), R: FnMut(&mut GameLoop<G, T, W>), { let mut g = self; if g.exit_next_iteration { return false; } g.current_instant = T::now(); let mut elapsed = g.current_instant.sub(&g.previous_instant); if elapsed > g.max_frame_time { elapsed = g.max_frame_time; } g.last_frame_time = elapsed; g.running_time += elapsed; g.accumulated_time += elapsed; while g.accumulated_time >= g.fixed_time_step { update(&mut g); g.accumulated_time -= g.fixed_time_step; g.number_of_updates += 1; } g.blending_factor = g.accumulated_time / g.fixed_time_step; render(&mut g); g.number_of_renders += 1; g.previous_instant = g.current_instant; return true; } pub fn exit(&mut self) { self.exit_next_iteration = true; } pub fn fixed_time_step(&self) -> f64 { self.fixed_time_step } pub fn number_of_updates(&self) -> u32 { self.number_of_updates } pub fn number_of_renders(&self) -> u32 { self.number_of_renders } pub fn last_frame_time(&self) -> f64 { self.last_frame_time } pub fn running_time(&self) -> f64 { self.running_time } pub fn accumulated_time(&self) -> f64 { self.accumulated_time } pub fn blending_factor(&self) -> f64 { self.blending_factor } pub fn previous_instant(&self) -> T { self.previous_instant } pub fn current_instant(&self) -> T { self.current_instant } }