use alloc::{boxed::Box, vec::Vec};
use core::fmt::Debug;
#[derive(Debug)]
pub struct Queue {
events: Vec<Event>,
}
pub struct Event {
pub at_tick: u64,
pub interval: Option<u64>,
pub called: bool,
pub callback: Box<dyn Fn()>,
}
impl Debug for Event {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("Event")
.field("at_tick", &self.at_tick)
.field("interval", &self.interval)
.field("called", &self.called)
.finish()
}
}
impl Queue {
pub fn new() -> Self {
Self { events: Vec::new() }
}
pub fn add_and_next_tick(&mut self, event: Event) -> u64 {
self.events.retain(|e| !e.called);
self.events.push(event);
self.events.sort_by(|a, b| a.at_tick.cmp(&b.at_tick));
self.events[0].at_tick
}
pub fn next_tick(&self) -> Option<u64> {
for e in self.events.iter() {
if e.called {
continue;
}
return Some(e.at_tick);
}
None
}
pub fn pop(&mut self, now: u64) -> Option<&Event> {
for e in self.events.iter_mut() {
if e.called {
continue;
}
if e.at_tick <= now {
if let Some(interval) = e.interval {
e.at_tick += interval;
} else {
e.called = true;
}
return Some(e);
}
}
None
}
}