49 lines
1.1 KiB
JavaScript
49 lines
1.1 KiB
JavaScript
import {compose} from '@avocado/core';
|
|
import {EventEmitter, Property} from '@avocado/mixins';
|
|
import {Ticker} from '@avocado/timing';
|
|
|
|
const decorate = compose(
|
|
EventEmitter,
|
|
Property('count', {
|
|
track: true,
|
|
}),
|
|
Property('jitter', {
|
|
track: true,
|
|
}),
|
|
);
|
|
|
|
export class CycleTracker extends decorate(class {}) {
|
|
|
|
constructor(targetFrequency) {
|
|
super();
|
|
this.count = 0;
|
|
this.jitter = [0, 0];
|
|
this.targetFrequency = targetFrequency;
|
|
this.ticker = new Ticker(.25);
|
|
this.trackCount = 0;
|
|
this.trackJitter = [0, 0];
|
|
this.ticker.on('tick', this.onTick, this);
|
|
}
|
|
|
|
onTick() {
|
|
this.count = this.trackCount * 4;
|
|
this.trackCount = 0;
|
|
this.jitter = this.trackJitter;
|
|
this.trackJitter = [0, 0];
|
|
this.emit('updated');
|
|
}
|
|
|
|
sample(elapsed) {
|
|
this.trackCount += 1;
|
|
const jitter = elapsed - this.targetFrequency;
|
|
if (jitter < 0 && elapsed < this.trackJitter[0]) {
|
|
this.trackJitter[0] = Math.round(1000 * jitter) / 1000;
|
|
}
|
|
if (jitter > 0 && elapsed > this.trackJitter[1]) {
|
|
this.trackJitter[1] = Math.round(1000 * jitter) / 1000;
|
|
}
|
|
this.ticker.tick(elapsed);
|
|
}
|
|
}
|
|
|