Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix timers in web workers #56

Merged
merged 2 commits into from
Mar 29, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 11 additions & 15 deletions crates/timers/src/callback.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Callback-style timer APIs.

use super::window;
use super::sys::*;
use std::fmt;
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;
Expand All @@ -20,7 +20,7 @@ pub struct Timeout {
impl Drop for Timeout {
fn drop(&mut self) {
if let Some(id) = self.id {
window().clear_timeout_with_handle(id);
clear_timeout(id);
}
}
}
Expand Down Expand Up @@ -50,12 +50,10 @@ impl Timeout {
{
let closure = Closure::once(callback);

let id = window()
.set_timeout_with_callback_and_timeout_and_arguments_0(
closure.as_ref().unchecked_ref::<js_sys::Function>(),
millis as i32,
)
.unwrap_throw();
let id = set_timeout(
closure.as_ref().unchecked_ref::<js_sys::Function>(),
millis as i32,
);

Timeout {
id: Some(id),
Expand Down Expand Up @@ -125,7 +123,7 @@ pub struct Interval {
impl Drop for Interval {
fn drop(&mut self) {
if let Some(id) = self.id {
window().clear_interval_with_handle(id);
clear_interval(id);
}
}
}
Expand Down Expand Up @@ -158,12 +156,10 @@ impl Interval {
callback();
}) as Box<FnMut()>);

let id = window()
.set_interval_with_callback_and_timeout_and_arguments_0(
closure.as_ref().unchecked_ref::<js_sys::Function>(),
millis as i32,
)
.unwrap_throw();
let id = set_interval(
closure.as_ref().unchecked_ref::<js_sys::Function>(),
millis as i32,
);

Interval {
id: Some(id),
Expand Down
24 changes: 8 additions & 16 deletions crates/timers/src/future.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! `Future`- and `Stream`-backed timers APIs.

use super::window;
use super::sys::*;
use futures::prelude::*;
use futures::sync::mpsc;
use std::fmt;
Expand Down Expand Up @@ -56,7 +56,7 @@ pub struct TimeoutFuture {
impl Drop for TimeoutFuture {
fn drop(&mut self) {
if let Some(id) = self.id {
window().clear_timeout_with_handle(id);
clear_timeout(id);
}
}
}
Expand Down Expand Up @@ -84,11 +84,7 @@ impl TimeoutFuture {
pub fn new(millis: u32) -> TimeoutFuture {
let mut id = None;
let promise = js_sys::Promise::new(&mut |resolve, _reject| {
id = Some(
window()
.set_timeout_with_callback_and_timeout_and_arguments_0(&resolve, millis as i32)
.unwrap_throw(),
);
id = Some(set_timeout(&resolve, millis as i32));
});
debug_assert!(id.is_some());
let inner = JsFuture::from(promise);
Expand Down Expand Up @@ -173,7 +169,7 @@ impl IntervalStream {
impl Drop for IntervalStream {
fn drop(&mut self) {
if let Some(id) = self.id {
window().clear_interval_with_handle(id);
clear_interval(id);
}
}
}
Expand All @@ -192,14 +188,10 @@ impl Stream for IntervalStream {

fn poll(&mut self) -> Poll<Option<()>, ()> {
if self.id.is_none() {
self.id = Some(
window()
.set_interval_with_callback_and_timeout_and_arguments_0(
self.closure.as_ref().unchecked_ref::<js_sys::Function>(),
self.millis as i32,
)
.unwrap_throw(),
);
self.id = Some(set_interval(
self.closure.as_ref().unchecked_ref::<js_sys::Function>(),
self.millis as i32,
));
}

self.inner.poll()
Expand Down
8 changes: 2 additions & 6 deletions crates/timers/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,9 @@ TODO
#[cfg(feature = "futures")]
extern crate futures_rs as futures;

use wasm_bindgen::prelude::*;

fn window() -> web_sys::Window {
web_sys::window().unwrap_throw()
}

pub mod callback;

#[cfg(feature = "futures")]
pub mod future;

mod sys;
20 changes: 20 additions & 0 deletions crates/timers/src/sys.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//! Raw bindings to the Javascript APIs we need, namely set(Timeout|Interval) and clear(Timeout|Interval).
//! Depending on how rustwasm/wasm-bindgen#1046 is resolved, we may be able to remove this at a later date.

use js_sys::Function;
use wasm_bindgen::prelude::*;

#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(js_name = "setTimeout")]
pub fn set_timeout(handler: &Function, timeout: i32) -> i32;

#[wasm_bindgen(js_name = "clearTimeout")]
pub fn clear_timeout(token: i32);

#[wasm_bindgen(js_name = "setInterval")]
pub fn set_interval(handler: &Function, timeout: i32) -> i32;

#[wasm_bindgen(js_name = "clearInterval")]
pub fn clear_interval(token: i32);
}