Add a comment about memory management

This commit is contained in:
Alex Crichton 2018-12-19 12:00:42 -08:00
parent 46464b6abf
commit fcee465692

View File

@ -26,31 +26,42 @@ fn body() -> web_sys::HtmlElement {
// This function is automatically invoked after the wasm module is instantiated. // This function is automatically invoked after the wasm module is instantiated.
#[wasm_bindgen(start)] #[wasm_bindgen(start)]
pub fn run() -> Result<(), JsValue> { pub fn run() -> Result<(), JsValue> {
// Here we want to call `requestAnimationFrame` in a loop, but only a fixed
// number of times. After it's done we want all our resources cleaned up. To
// achieve this we're using an `Rc`. The `Rc` will eventually store the
// closure we want to execute on each frame, but to start out it contains
// `None`.
//
// After the `Rc` is made we'll actually create the closure, and the closure
// will reference one of the `Rc` instances. The other `Rc` reference is
// used to store the closure, request the first frame, and then is dropped
// by this function.
//
// Inside the closure we've got a persistent `Rc` reference, which we use
// for all future iterations of the loop
let f = Rc::new(RefCell::new(None)); let f = Rc::new(RefCell::new(None));
let g = f.clone(); let g = f.clone();
{ let mut i = 0;
let mut i = 0; *g.borrow_mut() = Some(Closure::wrap(Box::new(move || {
*g.borrow_mut() = Some(Closure::wrap(Box::new(move || { if i > 300 {
if i > 300 { body().set_text_content(Some("All done!"));
body().set_text_content(Some("All done!"));
// Drop our handle to this closure so that it will get cleaned // Drop our handle to this closure so that it will get cleaned
// up once we return. // up once we return.
let _ = f.borrow_mut().take(); let _ = f.borrow_mut().take();
return; return;
} }
// Set the body's text content to how many times this // Set the body's text content to how many times this
// requestAnimationFrame callback has fired. // requestAnimationFrame callback has fired.
i += 1; i += 1;
let text = format!("requestAnimationFrame has been called {} times.", i); let text = format!("requestAnimationFrame has been called {} times.", i);
body().set_text_content(Some(&text)); body().set_text_content(Some(&text));
// Schedule ourself for another requestAnimationFrame callback. // Schedule ourself for another requestAnimationFrame callback.
request_animation_frame(f.borrow().as_ref().unwrap()); request_animation_frame(f.borrow().as_ref().unwrap());
}) as Box<FnMut()>)); }) as Box<FnMut()>));
}
request_animation_frame(g.borrow().as_ref().unwrap()); request_animation_frame(g.borrow().as_ref().unwrap());
Ok(()) Ok(())