add realtime timers to EventSimulator

This commit is contained in:
serxa 2024-11-20 19:15:51 +00:00
parent f1d647d173
commit 7623b5becd
2 changed files with 44 additions and 0 deletions

View File

@ -52,6 +52,9 @@ export class EventSimulator
this.ready_events = []; // Events ready to be executed this.ready_events = []; // Events ready to be executed
this.pending_events = new Heap((a, b) => a.time - b.time); // Use min Heap for pending events this.pending_events = new Heap((a, b) => a.time - b.time); // Use min Heap for pending events
this.time = 0; this.time = 0;
this.timers = [];
this.last_timer = 0;
this.min_timer_interval_ms = 100; // At least check every 100 ms
} }
// Schedule new event to be executed at specific time // Schedule new event to be executed at specific time
@ -83,11 +86,47 @@ export class EventSimulator
this.scheduleAt(0, name, callback, []); this.scheduleAt(0, name, callback, []);
} }
// Register a callback to be called every `interval` ms in realtime (not simulation)
addTimer(interval_ms, callback)
{
this.timers.push({
last: performance.now(),
interval_ms,
callback,
});
this.min_timer_interval_ms = Math.min(this.min_timer_interval_ms, interval_ms);
}
// Handle timers
async #handleTimers()
{
if (this.timers.length > 0)
{
const now = performance.now();
if (this.last_timer + this.min_timer_interval_ms < now)
{
this.last_timer = now;
for (const timer of this.timers)
{
if (timer.last + timer.interval_ms < now)
{
timer.last = now;
await timer.callback();
}
}
}
}
}
// Run the simulation // Run the simulation
async run() async run()
{ {
const startTime = performance.now();
while (this.ready_events.length > 0 || this.pending_events.size() > 0) while (this.ready_events.length > 0 || this.pending_events.size() > 0)
{
await this.#executeNextEvent(); await this.#executeNextEvent();
await this.#handleTimers();
}
} }
// All dependencies of an event are now satisfied // All dependencies of an event are now satisfied

View File

@ -20,6 +20,11 @@ export async function customScenario(scenario, signals)
await inserter.start(); await inserter.start();
await merger.start(); await merger.start();
// Make timer
const {every_real_second: on_every_real_second} = signals;
if (on_every_real_second)
sim.addTimer(1000, async () => await on_every_real_second({mt, sim}));
// Run the simulation // Run the simulation
await sim.run(); await sim.run();