aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib.rs
blob: f43b2adf75c034702232a086b8d8da46fc0b6e14 (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
use std::cell::RefCell;
use std::rc::Rc;

use log::{Level, info};
use wasm_bindgen::prelude::*;

use state::State;

mod line;
mod point;
mod state;

struct RenderLoop {
    animation_id: Option<i32>,
    pub closure: Option<Closure<dyn FnMut(f64)>>,
}

impl RenderLoop {
    pub fn new() -> Self {
        Self {
            animation_id: None,
            closure: None,
        }
    }
}

fn window() -> web_sys::Window {
    web_sys::window().expect("no window")
}

#[wasm_bindgen(start)]
pub fn init() -> Result<(), JsValue> {
    console_log::init_with_level(Level::Debug).expect("couldn't init console log");
    info!("wasm init");

    let mut s = State::new()?;
    s.render_frame(0.0)?;

    //
    // from https://users.rust-lang.org/t/wasm-web-sys-how-to-use-window-request-animation-frame-resolved/20882
    //

    let render_loop: Rc<RefCell<RenderLoop>> = Rc::new(RefCell::new(RenderLoop::new()));
    {
        let closure: Closure<dyn FnMut(f64)> = {
            let render_loop = render_loop.clone();
            Closure::wrap(Box::new(move |t| {
                s.render_frame(t).expect("should render frame");
                if !s.paused {
                    let mut render_loop = render_loop.borrow_mut();
                    render_loop.animation_id = if let Some(ref closure) = render_loop.closure {
                        Some(
                            window()
                                .request_animation_frame(closure.as_ref().unchecked_ref())
                                .expect("req anim frame"),
                        )
                    } else {
                        None
                    }
                }
            }))
        };
        let mut render_loop = render_loop.borrow_mut();
        render_loop.animation_id = Some(
            window()
                .request_animation_frame(closure.as_ref().unchecked_ref())
                .expect("req anim frame"),
        );
        render_loop.closure = Some(closure);
    }

    //
    //
    //

    Ok(())
}