From fcee4656923a1128d0a2faf781242ee2d7835db4 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 19 Dec 2018 12:00:42 -0800 Subject: [PATCH] Add a comment about memory management --- examples/request-animation-frame/src/lib.rs | 49 +++++++++++++-------- 1 file changed, 30 insertions(+), 19 deletions(-) diff --git a/examples/request-animation-frame/src/lib.rs b/examples/request-animation-frame/src/lib.rs index fd83b6843..81def4c63 100644 --- a/examples/request-animation-frame/src/lib.rs +++ b/examples/request-animation-frame/src/lib.rs @@ -26,31 +26,42 @@ fn body() -> web_sys::HtmlElement { // This function is automatically invoked after the wasm module is instantiated. #[wasm_bindgen(start)] 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 g = f.clone(); - { - let mut i = 0; - *g.borrow_mut() = Some(Closure::wrap(Box::new(move || { - if i > 300 { - body().set_text_content(Some("All done!")); + let mut i = 0; + *g.borrow_mut() = Some(Closure::wrap(Box::new(move || { + if i > 300 { + body().set_text_content(Some("All done!")); - // Drop our handle to this closure so that it will get cleaned - // up once we return. - let _ = f.borrow_mut().take(); - return; - } + // Drop our handle to this closure so that it will get cleaned + // up once we return. + let _ = f.borrow_mut().take(); + return; + } - // Set the body's text content to how many times this - // requestAnimationFrame callback has fired. - i += 1; - let text = format!("requestAnimationFrame has been called {} times.", i); - body().set_text_content(Some(&text)); + // Set the body's text content to how many times this + // requestAnimationFrame callback has fired. + i += 1; + let text = format!("requestAnimationFrame has been called {} times.", i); + body().set_text_content(Some(&text)); - // Schedule ourself for another requestAnimationFrame callback. - request_animation_frame(f.borrow().as_ref().unwrap()); - }) as Box)); - } + // Schedule ourself for another requestAnimationFrame callback. + request_animation_frame(f.borrow().as_ref().unwrap()); + }) as Box)); request_animation_frame(g.borrow().as_ref().unwrap()); Ok(())