mod event_holder;
pub(super) mod event_traits;
use crate::{SimState, SimTime};
use event_holder::ScheduledEvent;
use event_traits::Event;
use std::cmp::Reverse;
use std::collections::BinaryHeap;
use std::fmt::{Debug, Formatter};
#[derive(Default)]
struct BinaryHeapWrapper<State, Time>
where
State: SimState<Time>,
Time: SimTime,
{
heap: BinaryHeap<Reverse<ScheduledEvent<State, Time>>>,
}
impl<State, Time> Debug for BinaryHeapWrapper<State, Time>
where
State: SimState<Time>,
Time: SimTime,
{
fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
f.debug_list()
.entries(self.heap.iter().map(|holder| &holder.0))
.finish()
}
}
#[derive(Default)]
pub(super) struct EventQueue<State, Time>
where
State: SimState<Time>,
Time: SimTime,
{
events: BinaryHeapWrapper<State, Time>,
total_events_scheduled: usize,
}
impl<State, Time> EventQueue<State, Time>
where
State: SimState<Time>,
Time: SimTime,
{
pub fn new() -> Self {
Self {
events: BinaryHeapWrapper {
heap: BinaryHeap::default(),
},
total_events_scheduled: 0,
}
}
pub fn schedule_event(&mut self, event: Box<dyn Event<State, Time>>, time: Time) {
let count = self.increment_event_count();
self.events.heap.push(Reverse(ScheduledEvent {
execution_time: time,
event,
insertion_sequence: count,
}));
}
fn increment_event_count(&mut self) -> usize {
let count = self.total_events_scheduled;
self.total_events_scheduled += 1;
count
}
pub fn next(&mut self) -> Option<(Box<dyn Event<State, Time>>, Time)> {
if let Some(event_holder) = self.events.heap.pop() {
Some((event_holder.0.event, event_holder.0.execution_time))
} else {
None
}
}
}
impl<State, Time> Debug for EventQueue<State, Time>
where
State: SimState<Time>,
Time: SimTime,
{
fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
f.debug_struct("EventQueue")
.field("events", &self.events)
.field("total_events_scheduled", &self.total_events_scheduled)
.finish()
}
}
impl<State, Time> std::fmt::Display for EventQueue<State, Time>
where
State: SimState<Time>,
Time: SimTime,
{
fn fmt(&self, formatter: &mut Formatter) -> std::fmt::Result {
write!(formatter, "EventQueue with {} scheduled events", self.events.heap.len(),)
}
}