sclass Schedule {
Timestamp start;
sclass Entry {}
srecord Action(A action) extends Entry {}
srecord Jump (Seconds dest) extends Entry {}
new TreeMultiMap entries;
void add(double seconds, A a) {
entries.put(Seconds(seconds), new Action(a));
}
void jumpFromTo(double from, double to) {
entries.put(Seconds(from), new Jump(Seconds(to)));
}
void speedUp(double factor) {
entries = (TreeMultiMap) mapMultiMapKeys(entries, seconds -> seconds.div(factor));
}
run {
start = tsNow();
fire(first(entries));
}
scaffolded void fire(Pair p) {
if (p == null) ret;
entries.removePair(p);
sleepUntil(start.plus(p.a));
var e = p.b;
if (e cast Action)
pcallF(e.action);
else if (e cast Jump)
start = start.plus(e.dest.minus(p.a));
else
fail(e);
fire(first(entries));
}
}