Implement requestAnimationFrame for web (#1519)
* Use requestAnimationFrame for polling wasm * Implement `requestAnimationFrame` for stdweb Co-authored-by: Ryan G <ryanisaacg@users.noreply.github.com>
This commit is contained in:
parent
a8e777a5df
commit
1f24a09570
8 changed files with 93 additions and 6 deletions
|
|
@ -1,3 +1,5 @@
|
|||
use std::cell::Cell;
|
||||
use std::rc::Rc;
|
||||
use std::time::Duration;
|
||||
use wasm_bindgen::closure::Closure;
|
||||
use wasm_bindgen::JsCast;
|
||||
|
|
@ -38,3 +40,48 @@ impl Drop for Timeout {
|
|||
window.clear_timeout_with_handle(self.handle);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct AnimationFrameRequest {
|
||||
handle: i32,
|
||||
// track callback state, because `cancelAnimationFrame` is slow
|
||||
fired: Rc<Cell<bool>>,
|
||||
_closure: Closure<dyn FnMut()>,
|
||||
}
|
||||
|
||||
impl AnimationFrameRequest {
|
||||
pub fn new<F>(mut f: F) -> AnimationFrameRequest
|
||||
where
|
||||
F: 'static + FnMut(),
|
||||
{
|
||||
let window = web_sys::window().expect("Failed to obtain window");
|
||||
|
||||
let fired = Rc::new(Cell::new(false));
|
||||
let c_fired = fired.clone();
|
||||
let closure = Closure::wrap(Box::new(move || {
|
||||
(*c_fired).set(true);
|
||||
f();
|
||||
}) as Box<dyn FnMut()>);
|
||||
|
||||
let handle = window
|
||||
.request_animation_frame(&closure.as_ref().unchecked_ref())
|
||||
.expect("Failed to request animation frame");
|
||||
|
||||
AnimationFrameRequest {
|
||||
handle,
|
||||
fired,
|
||||
_closure: closure,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for AnimationFrameRequest {
|
||||
fn drop(&mut self) {
|
||||
if !(*self.fired).get() {
|
||||
let window = web_sys::window().expect("Failed to obtain window");
|
||||
window
|
||||
.cancel_animation_frame(self.handle)
|
||||
.expect("Failed to cancel animation frame");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue