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
use core::prelude::*; use std::{cell::RefCell, rc::Rc, time::Duration}; use wasm_bindgen::{prelude::*, JsCast}; fn window() -> web_sys::Window { web_sys::window().expect("no global `window` exists") } fn request_animation_frame(f: &Closure<FnMut()>) { window() .request_animation_frame(f.as_ref().unchecked_ref()) .expect("should register `requestAnimationFrame` OK"); } fn performance() -> web_sys::Performance { window() .performance() .expect("no `window.performance` exists") } pub struct WebAppTimer { timer: f64, delta_time: Duration, delta_time_seconds: f64, } impl Default for WebAppTimer { fn default() -> Self { Self { timer: performance().now() * 0.001, delta_time: Duration::default(), delta_time_seconds: 0.0, } } } impl AppTimer for WebAppTimer { fn tick(&mut self) { let t = performance().now() * 0.001; let d = t - self.timer; self.timer = t; self.delta_time = Duration::new(d as u64, (d.fract() * 1e9) as u32); self.delta_time_seconds = d; } fn delta_time(&self) -> Duration { self.delta_time } fn delta_time_seconds(&self) -> f64 { self.delta_time_seconds } } pub struct WebAppRunner; impl BackendAppRunner<'static, 'static, JsValue> for WebAppRunner { fn run(app: Rc<RefCell<App<'static, 'static>>>) -> Result<(), JsValue> { let f = Rc::new(RefCell::new(None)); let g = f.clone(); *g.borrow_mut() = Some(Closure::wrap(Box::new(move || { if !app.borrow().world().read_resource::<AppLifeCycle>().running { drop(f.borrow_mut().take()); return; } app.borrow_mut().process(); request_animation_frame(f.borrow().as_ref().unwrap()); }) as Box<FnMut()>)); request_animation_frame(g.borrow().as_ref().unwrap()); Ok(()) } }