rat_salsa/timer/
mod.rs

1use crate::event::TimerEvent;
2use std::cell::{Cell, RefCell};
3use std::time::{Duration, Instant};
4
5/// Holds all the timers.
6#[derive(Debug, Default)]
7pub(crate) struct Timers {
8    tags: Cell<usize>,
9    timers: RefCell<Vec<TimerImpl>>,
10}
11
12/// Handle for a submitted timer.
13#[derive(Debug, Default, PartialEq, Eq, Hash, Clone, Copy)]
14pub struct TimerHandle(usize);
15
16#[derive(Debug)]
17struct TimerImpl {
18    tag: usize,
19    count: usize,
20    repeat: Option<usize>,
21    next: Instant,
22    timer: Duration,
23}
24
25impl Timers {
26    /// Returns the next sleep time.
27    pub(crate) fn sleep_time(&self) -> Option<Duration> {
28        let timers = self.timers.borrow();
29        if let Some(timer) = timers.last() {
30            let now = Instant::now();
31            if now > timer.next {
32                Some(Duration::from_nanos(0))
33            } else {
34                Some(timer.next.duration_since(now))
35            }
36        } else {
37            None
38        }
39    }
40
41    /// Polls for the next timer event.
42    pub(crate) fn poll(&self) -> bool {
43        let timers = self.timers.borrow();
44        if let Some(timer) = timers.last() {
45            Instant::now() >= timer.next
46        } else {
47            false
48        }
49    }
50
51    /// Polls for the next timer event.
52    /// Removes/recalculates the event and reorders the queue.
53    pub(crate) fn read(&self) -> Option<TimerEvent> {
54        let mut timers = self.timers.borrow_mut();
55
56        let timer = timers.pop();
57        if let Some(mut timer) = timer {
58            if Instant::now() >= timer.next {
59                let evt = TimerEvent(TimeOut {
60                    handle: TimerHandle(timer.tag),
61                    counter: timer.count,
62                });
63
64                // reschedule
65                if let Some(repeat) = timer.repeat {
66                    timer.count += 1;
67                    if timer.count < repeat {
68                        timer.next += timer.timer;
69                        Self::add_impl(timers.as_mut(), timer);
70                    }
71                }
72
73                Some(evt)
74            } else {
75                timers.push(timer);
76                None
77            }
78        } else {
79            None
80        }
81    }
82
83    fn add_impl(timers: &mut Vec<TimerImpl>, t: TimerImpl) {
84        'f: {
85            for i in 0..timers.len() {
86                if timers[i].next <= t.next {
87                    timers.insert(i, t);
88                    break 'f;
89                }
90            }
91            timers.push(t);
92        }
93    }
94
95    /// Add a timer.
96    #[must_use]
97    pub(crate) fn add(&self, t: TimerDef) -> TimerHandle {
98        let tag = self.tags.get() + 1;
99        self.tags.set(tag);
100
101        let t = TimerImpl {
102            tag,
103            count: 0,
104            repeat: t.repeat,
105            next: if let Some(next) = t.next {
106                next
107            } else {
108                Instant::now() + t.timer
109            },
110            timer: t.timer,
111        };
112
113        let mut timers = self.timers.borrow_mut();
114        Self::add_impl(timers.as_mut(), t);
115
116        TimerHandle(tag)
117    }
118
119    /// Remove a timer.
120    pub(crate) fn remove(&self, tag: TimerHandle) {
121        let mut timer = self.timers.borrow_mut();
122        for i in 0..timer.len() {
123            if timer[i].tag == tag.0 {
124                timer.remove(i);
125                break;
126            }
127        }
128    }
129}
130
131/// Timing event data. Used by [TimerEvent].
132#[derive(Debug, Clone, Copy, PartialEq, Eq)]
133pub struct TimeOut {
134    pub handle: TimerHandle,
135    pub counter: usize,
136}
137
138/// Holds the information to start a timer.
139#[derive(Debug, Default)]
140pub struct TimerDef {
141    /// Optional repeat.
142    repeat: Option<usize>,
143    /// Duration
144    timer: Duration,
145    /// Specific time.
146    next: Option<Instant>,
147}
148
149impl TimerDef {
150    pub fn new() -> Self {
151        Default::default()
152    }
153
154    /// Repeat forever.
155    pub fn repeat_forever(mut self) -> Self {
156        self.repeat = Some(usize::MAX);
157        self
158    }
159
160    /// Repeat count.
161    pub fn repeat(mut self, repeat: usize) -> Self {
162        self.repeat = Some(repeat);
163        self
164    }
165
166    /// Timer interval.
167    pub fn timer(mut self, timer: Duration) -> Self {
168        self.timer = timer;
169        self
170    }
171
172    /// Next time the timer is due. Can set a start delay for a repeating timer,
173    /// or as an oneshot event for a given instant.
174    pub fn next(mut self, next: Instant) -> Self {
175        self.next = Some(next);
176        self
177    }
178}