///|
pub(all) enum ClockStatus {
Idle
Running
Paused
Completed
} derive(Debug, Eq)
///|
pub(all) struct Clock {
mut time : SimTime
mut next_seq : Int64
heap : EventHeap
mut status : ClockStatus
mut target_time : Double?
} derive(Debug)
///|
pub fn Clock::new() -> Clock {
{
time: SimTime::zero(),
next_seq: 1L,
heap: EventHeap::new(),
status: Idle,
target_time: None,
}
}
///|
pub fn Clock::now(self : Clock) -> SimTime {
self.time
}
///|
pub fn Clock::now_seconds(self : Clock) -> Double {
self.time.to_seconds()
}
///|
pub fn Clock::status(self : Clock) -> ClockStatus {
self.status
}
///|
pub fn Clock::reset(self : Clock) -> Unit {
self.time = SimTime::zero()
self.next_seq = 1L
self.heap.clear()
self.status = Idle
self.target_time = None
}
///|
fn Clock::generate_id(self : Clock) -> EventId {
let id = { seq: self.next_seq }
self.next_seq = self.next_seq + 1L
id
}
///|
pub fn Clock::schedule_at(
self : Clock,
target : SimTime,
priority : Int,
payload_id : Int,
) -> EventId {
if target.val < self.time.val {
abort("Cannot schedule event in the past")
}
let id = self.generate_id()
let ev = { time: target, priority, id, cancelled: false, payload_id }
self.heap.push(ev)
id
}
///|
pub fn Clock::schedule(
self : Clock,
delta_seconds : Double,
priority : Int,
payload_id : Int,
) -> EventId {
let target = self.time.op_add(delta_seconds)
self.schedule_at(target, priority, payload_id)
}
///|
pub fn Clock::cancel(self : Clock, id : EventId) -> Bool {
self.heap.cancel_by_id(id)
}
///|
pub fn Clock::filter_events(
self : Clock,
predicate : (PriorityEvent) -> Bool,
) -> Int {
self.heap.filter_events(predicate)
}
///|
pub fn Clock::active_count(self : Clock) -> Int {
self.heap.active_count()
}
///|
pub fn Clock::get_event(self : Clock, id : EventId) -> PriorityEvent? {
self.heap.get_event_by_id(id)
}
///|
pub fn Clock::next_event(self : Clock) -> PriorityEvent? {
while true {
match self.heap.pop() {
None => return None
Some(ev) => {
if ev.cancelled {
continue
}
match self.target_time {
Some(limit) =>
if ev.time.val > limit {
self.heap.push(ev)
return None
}
None => ()
}
self.time = ev.time
return Some(ev)
}
}
}
None
}
///|
pub fn Clock::set_target_time(self : Clock, limit_seconds : Double?) -> Unit {
self.target_time = limit_seconds
}