yew_stdweb/services/
interval.rs1use super::Task;
5use crate::callback::Callback;
6use cfg_if::cfg_if;
7use cfg_match::cfg_match;
8use std::convert::TryInto;
9use std::fmt;
10use std::time::Duration;
11cfg_if! {
12 if #[cfg(feature = "std_web")] {
13 use stdweb::Value;
14 #[allow(unused_imports)]
15 use stdweb::{_js_impl, js};
16 } else if #[cfg(feature = "web_sys")] {
17 use gloo::timers::callback::Interval;
18 }
19}
20
21#[must_use = "the interval is only active until the handle is dropped"]
24pub struct IntervalTask(
25 #[cfg(feature = "std_web")] Value,
26 #[cfg(feature = "web_sys")] Interval,
27);
28
29impl fmt::Debug for IntervalTask {
30 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31 f.write_str("IntervalTask")
32 }
33}
34
35#[derive(Default, Debug)]
37pub struct IntervalService {}
38
39impl IntervalService {
40 pub fn spawn(duration: Duration, callback: Callback<()>) -> IntervalTask {
47 let callback = move || {
48 callback.emit(());
49 };
50 let ms: u32 = duration
51 .as_millis()
52 .try_into()
53 .expect("duration doesn't fit in u32");
54 let handle = cfg_match! {
55 feature = "std_web" => js! {
56 var callback = @{callback};
57 var action = function() {
58 callback();
59 };
60 var delay = @{ms};
61 return {
62 interval_id: setInterval(action, delay),
63 callback: callback,
64 };
65 },
66 feature = "web_sys" => Interval::new(ms, callback),
67 };
68 IntervalTask(handle)
69 }
70}
71
72impl Task for IntervalTask {
73 fn is_active(&self) -> bool {
74 true
75 }
76}
77
78impl Drop for IntervalTask {
79 fn drop(&mut self) {
80 #[cfg(feature = "std_web")]
81 {
82 if self.is_active() {
83 let handle = &self.0;
84 js! { @(no_return)
85 var handle = @{handle};
86 clearInterval(handle.interval_id);
87 handle.callback.drop();
88 }
89 }
90 }
91 }
92}