export class TimeKeeper { fps: number; startedTs: number; isPaused: boolean; ts: number; rate: number; skippingFunc: () => boolean; constructor(startedTs: number, fps: number, skippingFunc: () => boolean) { this.fps = fps; this.startedTs = startedTs; this.ts = this.startedTs; this.isPaused = false; this.rate = 2; this.skippingFunc = skippingFunc; } reset(ts: number) { this.startedTs = ts; this.ts = ts; } pause() { this.isPaused = true; } resume() { this.isPaused = false; } start() { setInterval(() => { if (this.isPaused) return; if (this.skippingFunc()) return; this.ts += (1000 / this.fps) * this.rate; }, 1000 / this.fps); } jump(ts: number) { this.ts = ts; } jumpByFrame(frameNumber: number) { this.ts = this.startedTs + frameNumber * (1000 / this.fps); } }