-
Notifications
You must be signed in to change notification settings - Fork 6
CPU Graph Example
Sciumo edited this page Oct 20, 2022
·
6 revisions
import { h, render } from "preact"
import { signal, Signal } from "preact/signals";
import { Process } from "System/Diagnostics"
import { Dom } from "OneJS/Dom";
import { useEffect, useRef } from "preact/hooks";
import { MeshGenerationContext, Painter2D } from "UnityEngine/UIElements";
import { Color, Vector2 } from "UnityEngine";
import { Style } from "preact/jsx";
import { GetCurrentProcess } from "Process"
import { DateTime, TimeSpan } from "System";
import { ProcessorCount } from "Environment"
export class PerformanceManager {
/// timeout handle
id?: number = null;
/// timeout in milliseconds
timeout = 1000;
proc? : Process;
data: Signal<number[]>;
lastUsage : number;
lastTime : number;
procCount : number;
constructor( public samples:number = 20 ) {
this.data = signal<number[]>(new Array<number>(samples).fill(0));
this.procCount = ProcessorCount;
log(`proc count: ${this.procCount}`);
}
push( elem: number ) {
// not efficient.
const data = new Array(...this.data.value);
data.shift();
data.push(elem);
this.data.value = data;
}
start() {
if( this.id != null ) return;
this.proc = GetCurrentProcess();
if( this.proc != null ){
this.lastTime = performance.now();
this.lastUsage = this.proc.TotalProcessorTime.TotalMilliseconds;
this.id = setInterval( () => this.onUpdate(), this.timeout );
return true;
}else{
log("GetCurrentProcess returned null");
return false;
}
}
getCPUUsage() : number {
if( !this.proc ){
return 0;
}
const p = this.proc;
p.Refresh();
var curTime = performance.now();
var curUsage = p.TotalProcessorTime.TotalMilliseconds;
var cpuUsedMs = curUsage - this.lastUsage;
var totalMsPassed = curTime - this.lastTime;
var cpuUsageTotal = cpuUsedMs / (this.procCount * totalMsPassed);
this.lastUsage = curUsage;
this.lastTime = curTime;
let pct = (cpuUsageTotal * 100.0);
log( pct );
return pct;
}
stop() {
if( this.id != null ){
clearInterval( this.id );
this.id = null;
this.proc = null;
}
}
onUpdate() {
if( this.proc != null){
this.push(this.getCPUUsage());
}
}
}
export const PERFMAN = new PerformanceManager(20);
export function DrawGrid( p2: Painter2D, w: number, h:number ){
let div = 10;
p2.strokeColor = Color.gray;
p2.lineWidth = 1;
p2.BeginPath();
p2.MoveTo( new Vector2(0,0) );
p2.LineTo( new Vector2(0,h) );
p2.LineTo( new Vector2(w,h) );
p2.LineTo( new Vector2(w,0) );
p2.LineTo( new Vector2(0,0) );
const dh = h/div;
const dw = w/div;
for( let ih = dh; ih < h; ih += dh ){
p2.MoveTo( new Vector2(0,ih) );
p2.LineTo( new Vector2(w,ih) );
}
for( let iw = dw; iw < w; iw += dw ){
p2.MoveTo( new Vector2(iw,0) );
p2.LineTo( new Vector2(iw,h) );
}
p2.Stroke();
}
interface GraphProps {
data : Signal<number[]>
style?: Style
sample?: number
minX? : number
maxX? : number
grid? : number
lineWidth? :number;
}
const Graph = (props:GraphProps) => {
const ref = useRef<Dom>()
const data = props.data;
const lw = props.lineWidth | 1;
useEffect(() => {
ref.current.ve.generateVisualContent = onGenerateVisualContent
}, [])
useEffect(() => {
ref.current.ve.MarkDirtyRepaint()
}, [data.value])
function onGenerateVisualContent(mgc: MeshGenerationContext) {
const d = data.value;
var p2 = mgc.painter2D
var rs = ref.current.ve.resolvedStyle;
var w: number = rs.width;
var h:number = rs.height;
var dw = w / d.length;
DrawGrid(p2,w,h);
p2.BeginPath()
p2.strokeColor = Color.blue;
p2.lineWidth = lw;
for( let i = 0, iw = 0; i < d.length; i++, iw += dw ){
let dh = h * (1.0 - (d[i] / 100.0));
if( i == 0 ){
p2.MoveTo( new Vector2(iw,dh) );
}else{
p2.LineTo( new Vector2(iw,dh) );
}
}
p2.Stroke()
}
return <div id="graph" ref={ref} style={{...props.style}}>
</div>
}
const Performance = (props:any) => {
return (<div style={{...props.style, width: "275px", height: "300px" }} class="bg-white block p-6 rounded-lg shadow-lg max-w-sm">
<h5 class="text-gray-900 text-xl leading-tight font-medium mb-2">CPU</h5>
<Graph data={PERFMAN.data} lineWidth={5} style={{width:"100%", height:"100%"}}/>
</div>)
}
PERFMAN.start();
render(<Performance />, document.body)