Skip to main content

veilid_tools/
interval.rs

1use super::*;
2
3cfg_if! {
4    if #[cfg(all(target_arch = "wasm32", target_os = "unknown"))] {
5
6        pub fn interval<F, FUT>(name: &str, freq_ms: u32, immediate: bool, callback: F) -> PinBoxFutureStatic<()>
7        where
8            F: Fn() -> FUT + Send + Sync + 'static,
9            FUT: Future<Output = ()> + Send,
10        {
11            let e = Eventual::new();
12
13            let ie = e.clone();
14            let jh = spawn(name, Box::pin(async move {
15                let freq_u64 = (freq_ms as u64) * 1000u64;
16                let start_tick_ts = get_raw_timestamp();
17
18                let mut end_tick_ts = if immediate {
19                    callback().await;
20                    get_raw_timestamp()
21                } else {
22                    start_tick_ts
23                };
24                loop {
25                    let wait_ms = ((freq_u64 - end_tick_ts.saturating_sub(start_tick_ts) % freq_u64) / 1000) as u32;
26                    if timeout(wait_ms, ie.instance_clone(())).await.is_ok() {
27                        break;
28                    }
29
30                    callback().await;
31
32                    end_tick_ts = get_raw_timestamp();
33                }
34            }));
35
36            Box::pin(async move {
37                e.resolve().await;
38                jh.await;
39            })
40        }
41
42    } else {
43
44        pub fn interval<F, FUT>(name: &str, freq_ms: u32, immediate: bool, callback: F) -> PinBoxFutureStatic<()>
45        where
46            F: Fn() -> FUT + Send + Sync + 'static,
47            FUT: Future<Output = ()> + Send,
48        {
49            let e = Eventual::new();
50
51            let ie = e.clone();
52            let jh = spawn(name, async move {
53                let freq_u64 = (freq_ms as u64) * 1000u64;
54                let start_tick_ts = get_raw_timestamp();
55
56                let mut end_tick_ts = if immediate {
57                    callback().await;
58                    get_raw_timestamp()
59                } else {
60                    start_tick_ts
61                };
62                loop {
63                    let wait_ms = ((freq_u64 - end_tick_ts.saturating_sub(start_tick_ts) % freq_u64) / 1000) as u32;
64                    if timeout(wait_ms, ie.instance_clone(())).await.is_ok() {
65                        break;
66                    }
67
68                    callback().await;
69
70                    end_tick_ts = get_raw_timestamp();
71                }
72            });
73
74            Box::pin(async move {
75                e.resolve().await;
76                jh.await;
77            })
78        }
79
80    }
81}