use std::collections::BinaryHeap;
use std::cmp::Ordering;
use std::thread;
use std::time::{Duration, Instant};
// Define a custom event struct with priority and callback
struct Event {
priority: Instant,
callback: Box<dyn Fn() + Send>,
}
// Implement Ord trait for Event to allow priority comparison in the binary heap
impl Ord for Event {
fn cmp(&self, other: &Self) -> Ordering {
other.priority.cmp(&self.priority)
}
}
// Implement PartialOrd trait for Event
impl PartialOrd for Event {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
// Implement Eq trait for Event
impl Eq for Event {}
// Implement PartialEq trait for Event
impl PartialEq for Event {
fn eq(&self, other: &Self) -> bool {
self.priority == other.priority
}
}
// Priority queue based event timer
struct EventTimer {
events: BinaryHeap<Event>,
}
impl EventTimer {
fn new() -> EventTimer {
EventTimer { events: BinaryHeap::new() }
}
fn schedule<F>(&mut self, callback: F, delay: Duration)
where
F: Fn() + Send + 'static,
{
let priority = Instant::now() + delay;
let event = Event {
priority,
callback: Box::new(callback),
};
self.events.push(event);
}
fn is_empty(&self) -> bool {
self.events.len() == 0
}
fn run_pending(&mut self) {
let current_time = Instant::now();
while let Some(event) = self.events.peek() {
if event.priority <= current_time {
let event = self.events.pop().unwrap();
(event.callback)();
} else {
break;
}
}
}
}
// Example usage
fn main() {
let mut timer = EventTimer::new();
// Schedule callback1 to run after 2 seconds
timer.schedule(|| {
println!("Callback 1 executed");
}, Duration::from_secs(2));
// Schedule callback2 to run after 5 seconds
timer.schedule(|| {
println!("Callback 2 executed");
}, Duration::from_secs(5));
// Simulate the passage of time
while ! timer.is_empty() {
thread::sleep(Duration::from_secs(1));
// Run pending callbacks
timer.run_pending();
}
}