blob: 16b1d257fb3aa2a5768ffb029b4930e689a3ee93 (
plain)
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
|
use std::rc::Rc;
use std::sync::Mutex;
use log::{Level, debug, info};
use wasm_bindgen::prelude::*;
use render_loop::RenderLoop;
use state::State;
use web_sys::Event;
mod line;
mod point;
mod render_loop;
mod state;
type JSResult<T> = Result<T, JsValue>;
type HandlerClosure = Closure<dyn FnMut(Event) -> JSResult<()>>;
fn window() -> web_sys::Window {
web_sys::window().expect("no window")
}
fn document() -> web_sys::Document {
window().document().expect("no document")
}
fn canvas() -> JSResult<web_sys::HtmlCanvasElement> {
let x = document().query_selector("canvas")?.ok_or("no canvas")?;
Ok(x.dyn_into::<web_sys::HtmlCanvasElement>()?)
}
fn fps() -> JSResult<web_sys::HtmlElement> {
let x = document().query_selector("#fps")?.ok_or("no fps counter")?;
Ok(x.dyn_into::<web_sys::HtmlElement>()?)
}
fn go() -> JSResult<web_sys::HtmlElement> {
let x = document().query_selector("button")?.ok_or("no go button")?;
Ok(x.dyn_into::<web_sys::HtmlElement>()?)
}
#[wasm_bindgen(start)]
pub fn init() -> JSResult<()> {
console_log::init_with_level(Level::Debug)
.map_err(|e| format!("couldn't init console: {e}"))?;
info!("wasm init");
let paused = Rc::new(Mutex::new(true));
let p1 = paused.clone();
let mut s = State::new(canvas()?, fps()?)?;
s.render_frame(0.0)?;
let render_loop = RenderLoop::new(move |t| {
s.update()?;
s.render_frame(t)?;
Ok(!*paused.lock().unwrap())
});
let go_handler: HandlerClosure = Closure::new(move |e| {
debug!("go clicked: {:?}", e);
let mut p = p1.lock().unwrap();
*p = !*p;
let text = if *p {
"go"
} else {
render_loop.start()?;
"pause"
};
go()?.set_text_content(Some(text));
Ok(())
});
go()?.set_onclick(Some(go_handler.as_ref().unchecked_ref()));
// otherwise it gets dropped after we're done, invalidating the
// handler.
go_handler.forget();
Ok(())
}
|