2019-08-20 16:41:37 +02:00

86 lines
1.5 KiB
TypeScript

"use strict";
// License: MIT
const NUM_VALUES = 20;
class Sequence {
protected readonly values: Uint32Array;
protected fill: number;
protected full: boolean;
constructor() {
this.values = new Uint32Array(NUM_VALUES);
}
get validValues() {
return this.full ? this.values : this.values.slice(0, this.fill);
}
get current() {
return this.fill ? this.values[this.fill - 1] : 0;
}
clear() {
this.fill = 0;
this.full = false;
}
add(value: number) {
if (!this.full) {
this.values[this.fill++] = value;
this.full = this.fill === NUM_VALUES;
}
else {
this.values.copyWithin(0, 1);
this.values[NUM_VALUES - 1] = value;
}
}
}
export class Stats extends Sequence {
public readonly avgs: Sequence;
public avg: number;
private lastTime: number;
constructor() {
super();
this.avgs = new Sequence();
this.clear();
Object.seal(this);
}
clear() {
super.clear();
this.avgs.clear();
this.avg = 0;
this.lastTime = 0;
}
add(value: number) {
const now = Date.now();
if (this.lastTime) {
const diff = now - this.lastTime;
value = (value / diff * 1000) | 0;
}
this.lastTime = now;
super.add(value);
const valid = this.validValues;
const cavg = valid.reduce((p, c) => p + c, 0) / valid.length;
if (this.avg < 1000) {
this.avg = cavg;
}
else {
// eslint-disable-next-line no-magic-numbers
this.avg = this.avg * 0.85 + cavg * 0.15;
}
this.avgs.add(this.avg);
}
}