openreplay/frontend/app/player/MessageDistributor/managers/PerformanceTrackManager.ts

102 lines
No EOL
2.6 KiB
TypeScript

import type { PerformanceTrack, SetPageVisibility } from '../messages';
import type { Timed } from '../Timed';
import ListWalker from './ListWalker';
type TimedPerformanceTrack = Timed & PerformanceTrack;
type TimedSetPageVisibility = Timed & SetPageVisibility;
export type PerformanceChartPoint = {
time: number,
usedHeap: number,
totalHeap: number,
fps?: number,
cpu?: number,
nodesCount: number,
}
export default class PerformanceTrackManager extends ListWalker<TimedPerformanceTrack> {
private chart: Array<PerformanceChartPoint> = [];
private isHidden: boolean = false;
private timeCorrection: number = 0;
private heapAvaliable: boolean = false;
private fpsAvaliable: boolean = false;
private cpuAvaliable: boolean = false;
private prevTime: number | null = null;
private prevNodesCount: number = 0;
add(msg: TimedPerformanceTrack):void {
let fps: number | undefined;
let cpu: number | undefined;
if (!this.isHidden && this.prevTime != null) {
let timePassed = msg.time - this.prevTime + this.timeCorrection;
if (timePassed > 0 && msg.frames >= 0) {
if (msg.frames > 0) { this.fpsAvaliable = true; }
fps = msg.frames*1e3/timePassed; // Multiply by 1e3 as time in ms;
fps = Math.min(fps,60); // What if 120? TODO: alert if more than 60
if (this.chart.length === 1) {
this.chart[0].fps = fps;
}
}
if (timePassed > 0 && msg.ticks >= 0) {
this.cpuAvaliable = true;
let tickRate = msg.ticks * 30 / timePassed;
if (tickRate > 1) {
tickRate = 1;
}
cpu = Math.round(100 - tickRate*100);
if (this.chart.length === 1) {
this.chart[0].cpu = cpu;
}
}
}
this.prevTime = msg.time;
this.timeCorrection = 0
this.heapAvaliable = this.heapAvaliable || msg.usedJSHeapSize > 0;
this.chart.push({
usedHeap: msg.usedJSHeapSize,
totalHeap: msg.totalJSHeapSize,
fps,
cpu,
time: msg.time,
nodesCount: this.prevNodesCount,
});
super.add(msg);
}
setCurrentNodesCount(count: number) {
this.prevNodesCount = count;
if (this.chart.length > 0) {
this.chart[ this.chart.length - 1 ].nodesCount = count;
}
}
handleVisibility(msg: TimedSetPageVisibility):void {
if (!this.isHidden && msg.hidden && this.prevTime != null) {
this.timeCorrection = msg.time - this.prevTime;
}
if (this.isHidden && !msg.hidden) {
this.prevTime = msg.time;
}
this.isHidden = msg.hidden;
}
get chartData(): Array<PerformanceChartPoint> {
return this.chart;
}
get avaliability(): { cpu: boolean, fps: boolean, heap: boolean, nodes: boolean } {
return {
cpu: this.cpuAvaliable,
fps: this.fpsAvaliable,
heap: this.heapAvaliable,
nodes: true,
}
}
}