diff --git a/src/mocks/Clock.js b/src/mocks/Clock.js index fd49b313..6bbf5a1c 100644 --- a/src/mocks/Clock.js +++ b/src/mocks/Clock.js @@ -18,6 +18,34 @@ class Timeout { } } +class Interval { + constructor(elapsed, ms, callback) { + this._start = elapsed.get(); + this._last = this._start; + this._interval = ms; + this._callback = callback; + this._subscription = elapsed.subscribe(this._update.bind(this)); + } + + _update(elapsed) { + const prevAmount = Math.floor((this._last - this._start) / this._interval); + const newAmount = Math.floor((elapsed - this._start) / this._interval); + const amountDiff = Math.max(0, newAmount - prevAmount); + this._last = elapsed; + + for (let i = 0; i < amountDiff; ++i) { + this._callback(); + } + } + + dispose() { + if (this._subscription) { + this._subscription(); + this._subscription = null; + } + } +} + class TimeMeasure { constructor(elapsed) { this._elapsed = elapsed; @@ -47,6 +75,10 @@ export class Clock { return new Timeout(this._elapsed, ms); } + createInterval(callback, ms) { + return new Interval(this._elapsed, ms, callback); + } + now() { return this._baseTimestamp + this.elapsed; } @@ -72,6 +104,16 @@ export function tests() { const promise = timeout.elapsed(); assert(promise instanceof Promise); await promise; + }, + "test interval": assert => { + const clock = new Clock(); + let counter = 0; + const interval = clock.createInterval(() => counter += 1, 200); + clock.elapse(150); + assert.strictEqual(counter, 0); + clock.elapse(500); + assert.strictEqual(counter, 3); + interval.dispose(); } } } diff --git a/src/ui/web/dom/Clock.js b/src/ui/web/dom/Clock.js index 8a10499a..f5cc6ed0 100644 --- a/src/ui/web/dom/Clock.js +++ b/src/ui/web/dom/Clock.js @@ -25,8 +25,26 @@ class Timeout { this._reject = null; } } + + dispose() { + this.abort(); + } } +class Interval { + constructor(ms, callback) { + this._handle = setInterval(callback, ms); + } + + dispose() { + if (this._handle) { + clearInterval(this._handle); + this._handle = null; + } + } +} + + class TimeMeasure { constructor() { this._start = window.performance.now(); @@ -46,6 +64,10 @@ export class Clock { return new Timeout(ms); } + createInterval(callback, ms) { + return new Interval(ms, callback); + } + now() { return Date.now(); }