use super::sys::*;
use futures::prelude::*;
use futures::sync::mpsc;
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;
use wasm_bindgen_futures::JsFuture;
#[derive(Debug)]
#[must_use = "futures do nothing unless polled or spawned"]
pub struct TimeoutFuture {
id: Option<i32>,
inner: JsFuture,
}
impl Drop for TimeoutFuture {
fn drop(&mut self) {
if let Some(id) = self.id {
clear_timeout(id);
}
}
}
impl TimeoutFuture {
pub fn new(millis: u32) -> TimeoutFuture {
let mut id = None;
let promise = js_sys::Promise::new(&mut |resolve, _reject| {
id = Some(set_timeout(&resolve, millis as i32));
});
debug_assert!(id.is_some());
let inner = JsFuture::from(promise);
TimeoutFuture { id, inner }
}
}
impl Future for TimeoutFuture {
type Item = ();
type Error = ();
fn poll(&mut self) -> Poll<(), ()> {
match self.inner.poll() {
Ok(Async::Ready(_)) => Ok(Async::Ready(())),
Ok(Async::NotReady) => Ok(Async::NotReady),
Err(_) => wasm_bindgen::throw_str("unreachable"),
}
}
}
#[derive(Debug)]
#[must_use = "streams do nothing unless polled or spawned"]
pub struct IntervalStream {
millis: u32,
id: Option<i32>,
closure: Closure<FnMut()>,
inner: mpsc::UnboundedReceiver<()>,
}
impl IntervalStream {
pub fn new(millis: u32) -> IntervalStream {
let (sender, receiver) = mpsc::unbounded();
let closure = Closure::wrap(Box::new(move || {
sender.unbounded_send(()).unwrap();
}) as Box<FnMut()>);
IntervalStream {
millis,
id: None,
closure,
inner: receiver,
}
}
}
impl Drop for IntervalStream {
fn drop(&mut self) {
if let Some(id) = self.id {
clear_interval(id);
}
}
}
impl Stream for IntervalStream {
type Item = ();
type Error = ();
fn poll(&mut self) -> Poll<Option<()>, ()> {
if self.id.is_none() {
self.id = Some(set_interval(
self.closure.as_ref().unchecked_ref::<js_sys::Function>(),
self.millis as i32,
));
}
self.inner.poll()
}
}