diff options
| -rw-r--r-- | src/render_loop.rs | 20 |
1 files changed, 11 insertions, 9 deletions
diff --git a/src/render_loop.rs b/src/render_loop.rs index 8fc0164..628e687 100644 --- a/src/render_loop.rs +++ b/src/render_loop.rs @@ -1,4 +1,4 @@ -use std::cell::RefCell; +use std::cell::UnsafeCell; use std::rc::Rc; use log::error; @@ -7,7 +7,7 @@ use wasm_bindgen::prelude::*; /// use `window.requestAnimationFrame()` to schedule calling a /// function as long as the function returns true. pub struct RenderLoop { - inner: Rc<RefCell<Closure<dyn FnMut(f64)>>>, + inner: Rc<UnsafeCell<Closure<dyn FnMut(f64)>>>, } impl RenderLoop { @@ -22,15 +22,16 @@ impl RenderLoop { /// timeline and returns a flag specifying whether we should /// schedule another frame.. pub fn new<T: FnMut(f64) -> bool + 'static>(mut fun: T) -> Self { - // use stub closure so we don't need an `Option` to flag - // whether the `RefCell` is filled or not, and otherwise we'd - // need to use `MaybeUninit` and `unsafe`. - let inner = Rc::new(RefCell::new(Closure::new(|_| {}))); + // init with stub closure because rust wants that, then change + // it later once we have our rc clone. + let inner = Rc::new(UnsafeCell::new(Closure::new(|_| {}))); let rloop = inner.clone(); - *inner.borrow_mut() = Closure::new(move |t| { + let f = unsafe { &mut *inner.get() }; + *f = Closure::new(move |t| { if fun(t) { - if let Err(e) = Self::request_animation_frame(&rloop.borrow()) { + let cl = unsafe { &*rloop.get() }; + if let Err(e) = Self::request_animation_frame(cl) { error!("couldn't request animation frame: {:?}", e); } } @@ -41,7 +42,8 @@ impl RenderLoop { /// start animating. pub fn start(&self) -> Result<(), JsValue> { - Self::request_animation_frame(&self.inner.borrow())?; + let cl = unsafe { &*self.inner.get() }; + Self::request_animation_frame(cl)?; Ok(()) } } |
