UNPKG

@tempest/core

Version:

The core of the Tempest Stream Library

109 lines 2.89 kB
import { findIndex, removeAll } from '../util/array'; export class BinaryTimeline { constructor() { this.tasks = []; } nextArrival() { return this.isEmpty() ? Infinity : this.tasks[0].time; } isEmpty() { return this.tasks.length === 0; } add(task) { insertByTime(task, this.tasks); } remove(task) { const i = binarySearch(task.time, this.tasks); if (i >= 0 && i < this.tasks.length) { const at = findIndex(task, this.tasks[i].events); if (at >= 0) { this.tasks[i].events.splice(at, 1); return true; } } return false; } removeAll(f) { for (let i = 0, l = this.tasks.length; i < l; ++i) { removeAllFrom(f, this.tasks[i]); } } runTasks(time, runTask) { const tasks = this.tasks; const l = tasks.length; let i = 0; while (i < l && tasks[i].time <= time) { ++i; } this.tasks = tasks.slice(i); for (let j = 0; j < i; ++j) { this.tasks = runTasks(runTask, tasks[j], this.tasks); } } } function runTasks(runTask, timeslot, tasks) { const { events } = timeslot; for (let i = 0; i < events.length; ++i) { const task = events[i]; if (task.active) { runTask(task); if (task.period >= 0 && task.active) { task.time = task.time + task.period; insertByTime(task, tasks); } } } return tasks; } function insertByTime(task, timeslots) { const l = timeslots.length; if (l === 0) { timeslots.push(BinaryTimeslot.create(task.time, [task])); return; } const i = binarySearch(task.time, timeslots); if (i >= l) { timeslots.push(BinaryTimeslot.create(task.time, [task])); } else if (task.time === timeslots[i].time) { timeslots[i].events.push(task); } else { timeslots.splice(i, 0, BinaryTimeslot.create(task.time, [task])); } } function removeAllFrom(f, timeslot) { timeslot.events = removeAll(f, timeslot.events); } function binarySearch(time, sortedArray) { let lo = 0; let hi = sortedArray.length; let mid; let y; while (lo < hi) { mid = Math.floor((lo + hi) / 2); y = sortedArray[mid]; if (time === y.time) { return mid; } else if (time < y.time) { hi = mid; } else { lo = mid + 1; } return hi; } } export class BinaryTimeslot { constructor(time, events) { this.time = time; this.events = events; } static create(time, events) { return new BinaryTimeslot(time, events); } } //# sourceMappingURL=BinaryTimeline.js.map