aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorbrian cully <bjc@spork.org>2025-12-28 16:04:39 -0500
committerbrian cully <bjc@spork.org>2025-12-28 16:04:39 -0500
commitdf43e984dff819e9743992cb7b047d9d17506384 (patch)
treea30c03d38e167601f5b6eb45d9344a48378bf05b /src
parent6b3ecb884b38730ea20e2a44136a79e573525509 (diff)
downloadpolyring-df43e984dff819e9743992cb7b047d9d17506384.tar.gz
polyring-df43e984dff819e9743992cb7b047d9d17506384.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/render_loop.rs20
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(())
}
}