driver_interface/timer/
queue.rs

1use alloc::{boxed::Box, vec::Vec};
2use core::fmt::Debug;
3
4#[derive(Debug)]
5pub struct Queue {
6    events: Vec<Event>,
7}
8
9pub struct Event {
10    pub at_tick: u64,
11    pub interval: Option<u64>,
12    pub called: bool,
13    pub callback: Box<dyn Fn()>,
14}
15
16impl Debug for Event {
17    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
18        f.debug_struct("Event")
19            .field("at_tick", &self.at_tick)
20            .field("interval", &self.interval)
21            .field("called", &self.called)
22            .finish()
23    }
24}
25
26impl Queue {
27    pub fn new() -> Self {
28        Self { events: Vec::new() }
29    }
30
31    pub fn add_and_next_tick(&mut self, event: Event) -> u64 {
32        self.events.retain(|e| !e.called);
33        self.events.push(event);
34        self.events.sort_by(|a, b| a.at_tick.cmp(&b.at_tick));
35        self.events[0].at_tick
36    }
37
38    pub fn next_tick(&self) -> Option<u64> {
39        for e in self.events.iter() {
40            if e.called {
41                continue;
42            }
43
44            return Some(e.at_tick);
45        }
46        None
47    }
48
49    pub fn pop(&mut self, now: u64) -> Option<&Event> {
50        for e in self.events.iter_mut() {
51            if e.called {
52                continue;
53            }
54            if e.at_tick <= now {
55                if let Some(interval) = e.interval {
56                    e.at_tick += interval;
57                } else {
58                    e.called = true;
59                }
60                return Some(e);
61            }
62        }
63        None
64    }
65}