tricu

An interpreted language for exploring Tree Calculus
Log | Files | Refs | README | LICENSE

clock.ts (1350B)


      1 // Active-time deadline: input/step/idle pauses are excluded. Long delays are
      2 // chunked to fit the browser's signed 32-bit timer range.
      3 export class ActiveClock {
      4   private remaining = Infinity;
      5   private since: number | undefined;
      6   private timer: ReturnType<typeof setTimeout> | undefined;
      7   constructor(private readonly expire: () => void,
      8     private readonly now: () => number = () => performance.now(),
      9     private readonly schedule: typeof setTimeout = (handler, delay, ...args) => globalThis.setTimeout(handler, delay, ...args),
     10     private readonly cancel: typeof clearTimeout = id => globalThis.clearTimeout(id)) {}
     11   reset(milliseconds: number): void {
     12     if (milliseconds !== Infinity && (!Number.isSafeInteger(milliseconds) || milliseconds < 1)) throw new Error('Invalid active deadline');
     13     this.pause(); this.remaining = milliseconds;
     14   }
     15   start(): void {
     16     if (this.since !== undefined || this.remaining === Infinity) return;
     17     this.since = this.now();
     18     this.timer = this.schedule(() => {
     19       this.pause();
     20       if (this.remaining <= 0) this.expire(); else this.start();
     21     }, Math.min(2_147_483_647, Math.max(0, this.remaining)));
     22   }
     23   pause(): void {
     24     this.cancel(this.timer);
     25     if (this.since !== undefined) this.remaining -= this.now() - this.since;
     26     this.since = undefined; this.timer = undefined;
     27   }
     28 }