Dup Ver Goto 📝

Priority Queue Based Timer In Rust

PT2/lang/rust/examples rust timer does not exist
To
98 lines, 274 words, 2295 chars Page 'PriorityQueueTimer_01' does not exist.
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();
    }
}