///|
/// A delayed event with a countdown measured in logical ticks.
pub(all) struct ScheduledEvent {
id : Int
event : Event
remaining_ticks : Int
} derive(Eq, Debug)
///|
pub fn ScheduledEvent::new(
id : Int,
event : Event,
delay_ticks : Int,
) -> ScheduledEvent {
{ id, event, remaining_ticks: delay_ticks }
}
///|
pub fn EventBus::schedule_in(
self : EventBus,
event : Event,
delay_ticks : Int,
) -> EventBus {
let scheduled : Array[ScheduledEvent] = []
for item in self.scheduled {
scheduled.push(item)
}
scheduled.push(ScheduledEvent::new(self.next_id, event, delay_ticks))
{ ..self, scheduled, next_id: self.next_id + 1 }.append_trace(
TraceSchedule,
event.name,
self.name,
"scheduled in " + delay_ticks.to_string() + " tick(s)",
)
}
///|
pub fn EventBus::tick(self : EventBus) -> (EventBus, Array[DispatchReport]) {
let due : Array[Event] = []
let pending : Array[ScheduledEvent] = []
for item in self.scheduled {
let remaining = item.remaining_ticks - 1
if remaining <= 0 {
due.push(item.event)
} else {
pending.push({ ..item, remaining_ticks: remaining })
}
}
let bus = { ..self, scheduled: pending }
bus.publish_many(due)
}
///|
pub fn EventBus::tick_many(
self : EventBus,
count : Int,
) -> (EventBus, Array[DispatchReport]) {
let all_reports : Array[DispatchReport] = []
let mut bus = self
let mut index = 0
while index < count {
let (next, reports) = bus.tick()
bus = next
for report in reports {
all_reports.push(report)
}
index = index + 1
}
(bus, all_reports)
}