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
use crate::*;
pub use helper::*;
#[cfg(all(not(target_arch = "wasm32"), not(feature="window")))]
mod helper {
use super::*;
pub fn game_loop<G, U, R>(game: G, updates_per_second: u32, max_frame_time: f64, mut update: U, mut render: R) -> GameLoop<G, Time, ()>
where U: FnMut(&mut GameLoop<G, Time, ()>),
R: FnMut(&mut GameLoop<G, Time, ()>),
{
let mut game_loop = GameLoop::new(game, updates_per_second, max_frame_time, ());
while game_loop.next_frame(&mut update, &mut render) {}
game_loop
}
}
#[cfg(all(target_arch = "wasm32", not(feature="window")))]
mod helper {
use super::*;
use web_sys::window;
use wasm_bindgen::JsCast;
use wasm_bindgen::closure::Closure;
pub fn game_loop<G, U, R>(game: G, updates_per_second: u32, max_frame_time: f64, update: U, render: R)
where G: 'static,
U: FnMut(&mut GameLoop<G, Time, ()>) + 'static,
R: FnMut(&mut GameLoop<G, Time, ()>) + 'static,
{
let game_loop = GameLoop::new(game, updates_per_second, max_frame_time, ());
animation_frame(game_loop, update, render);
}
fn animation_frame<G, U, R>(mut g: GameLoop<G, Time, ()>, mut update: U, mut render: R)
where G: 'static,
U: FnMut(&mut GameLoop<G, Time, ()>) + 'static,
R: FnMut(&mut GameLoop<G, Time, ()>) + 'static,
{
if g.next_frame(&mut update, &mut render) {
let next_frame = move || animation_frame(g, update, render);
let closure = Closure::once_into_js(next_frame);
let js_func = closure.as_ref().unchecked_ref();
window().unwrap().request_animation_frame(js_func).unwrap();
}
}
}
#[cfg(feature="window")]
mod helper {
use super::*;
use winit::event::Event;
use winit::event_loop::{ControlFlow, EventLoop};
use winit::window::Window;
pub use winit;
pub fn game_loop<G, U, R, H, T>(event_loop: EventLoop<T>, window: Window, game: G, updates_per_second: u32, max_frame_time: f64, mut update: U, mut render: R, mut handler: H) -> !
where G: 'static,
U: FnMut(&mut GameLoop<G, Time, Window>) + 'static,
R: FnMut(&mut GameLoop<G, Time, Window>) + 'static,
H: FnMut(&mut GameLoop<G, Time, Window>, Event<'_, T>) + 'static,
T: 'static,
{
let mut game_loop = GameLoop::new(game, updates_per_second, max_frame_time, window);
event_loop.run(move |event, _, control_flow| {
*control_flow = ControlFlow::Poll;
match event {
Event::RedrawRequested(_) => {
if !game_loop.next_frame(&mut update, &mut render) {
*control_flow = ControlFlow::Exit;
}
},
Event::MainEventsCleared => {
game_loop.window.request_redraw();
},
event => {
handler(&mut game_loop, event);
}
}
})
}
}