@tempest/core
Version:
The core of the Tempest Stream Library
109 lines • 2.89 kB
JavaScript
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