From df43e984dff819e9743992cb7b047d9d17506384 Mon Sep 17 00:00:00 2001 From: brian cully Date: Sun, 28 Dec 2025 16:04:39 -0500 Subject: use unsafecell for render so we don't need runtime checks on borrows. the mutability is only used once during init, so we can guarantee that it's always safe by the time init is done. --- src/render_loop.rs | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'src') 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>>, + inner: Rc>>, } impl RenderLoop { @@ -22,15 +22,16 @@ impl RenderLoop { /// timeline and returns a flag specifying whether we should /// schedule another frame.. pub fn new 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(()) } } -- cgit v1.3