1#[cfg(feature = "async")]
2pub use async_interval::AsyncRtcInterval;
3
4use std::time::Duration;
5
6use bma_ts::Timestamp;
7
8pub struct RtcInterval {
9 interval: rtsc::time::Interval,
10 d: Duration,
11 tick_prev: u64,
12}
13
14impl RtcInterval {
15 pub fn new(d: Duration) -> Self {
16 let mut interval = rtsc::time::interval(if d >= Duration::from_secs(1) {
17 Duration::from_millis(200)
18 } else {
19 d
20 });
21 interval = interval.set_missing_tick_behavior(rtsc::time::MissedTickBehavior::Skip);
22 Self {
23 interval,
24 d,
25 tick_prev: 0,
26 }
27 }
28 pub fn tick(&mut self) -> Timestamp {
29 if self.d >= Duration::from_secs(1) {
30 loop {
31 self.interval.tick();
32 let t_secs = Timestamp::now().as_secs();
33 if t_secs.is_multiple_of(self.d.as_secs()) && t_secs != self.tick_prev {
34 self.tick_prev = t_secs;
35 break Timestamp::from_secs(t_secs);
36 }
37 }
38 } else {
39 self.interval.tick();
40 Timestamp::now()
41 }
42 }
43}
44
45#[cfg(feature = "async")]
46mod async_interval {
47 use std::time::Duration;
48
49 use bma_ts::Timestamp;
50
51 pub struct AsyncRtcInterval {
52 interval: tokio::time::Interval,
53 d: Duration,
54 tick_prev: u64,
55 }
56
57 impl AsyncRtcInterval {
58 pub fn new(d: Duration) -> Self {
59 let mut interval = tokio::time::interval(if d >= Duration::from_secs(1) {
60 Duration::from_millis(200)
61 } else {
62 d
63 });
64 interval.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Skip);
65 Self {
66 interval,
67 d,
68 tick_prev: 0,
69 }
70 }
71 pub async fn tick(&mut self) -> Timestamp {
72 if self.d >= Duration::from_secs(1) {
73 loop {
74 self.interval.tick().await;
75 let t_secs = Timestamp::now().as_secs();
76 if t_secs.is_multiple_of(self.d.as_secs()) && t_secs != self.tick_prev {
77 self.tick_prev = t_secs;
78 break Timestamp::from_secs(t_secs);
79 }
80 }
81 } else {
82 self.interval.tick().await;
83 Timestamp::now()
84 }
85 }
86 }
87}