@yuebai008/cli
Version:
Command line interface for rapid qg-minigame development
1 lines • 3.23 kB
JavaScript
import*as Common from"../common/common.js";import{RuntimeModel}from"./RuntimeModel.js";import{TargetManager}from"./TargetManager.js";let isolateManagerInstance;export class IsolateManager extends Common.ObjectWrapper.ObjectWrapper{#e;#s;#t;#n;constructor(){super(),this.#e=new Map,this.#s=new Map,this.#t=new Set,TargetManager.instance().observeModels(RuntimeModel,this),this.#n=0}static instance({forceNew:e}={forceNew:!1}){return isolateManagerInstance&&!e||(isolateManagerInstance=new IsolateManager),isolateManagerInstance}observeIsolates(e){if(this.#t.has(e))throw new Error("Observer can only be registered once");this.#t.size||this.poll(),this.#t.add(e);for(const s of this.#e.values())e.isolateAdded(s)}unobserveIsolates(e){this.#t.delete(e),this.#t.size||++this.#n}modelAdded(e){this.modelAddedInternal(e)}async modelAddedInternal(e){this.#s.set(e,null);const s=await e.isolateId();if(!this.#s.has(e))return;if(!s)return void this.#s.delete(e);this.#s.set(e,s);let t=this.#e.get(s);if(t||(t=new Isolate(s),this.#e.set(s,t)),t.modelsInternal.add(e),1===t.modelsInternal.size)for(const e of this.#t)e.isolateAdded(t);else for(const e of this.#t)e.isolateChanged(t)}modelRemoved(e){const s=this.#s.get(e);if(this.#s.delete(e),!s)return;const t=this.#e.get(s);if(t)if(t.modelsInternal.delete(e),t.modelsInternal.size)for(const e of this.#t)e.isolateChanged(t);else{for(const e of this.#t)e.isolateRemoved(t);this.#e.delete(s)}}isolateByModel(e){return this.#e.get(this.#s.get(e)||"")||null}isolates(){return this.#e.values()}async poll(){const e=this.#n;for(;e===this.#n;)await Promise.all(Array.from(this.isolates(),(e=>e.update()))),await new Promise((e=>window.setTimeout(e,PollIntervalMs)))}}export var Events;!function(e){e.MemoryChanged="MemoryChanged"}(Events||(Events={}));export const MemoryTrendWindowMs=12e4;const PollIntervalMs=2e3;export class Isolate{#o;modelsInternal;#i;#r;constructor(e){this.#o=e,this.modelsInternal=new Set,this.#i=0;const s=12e4/PollIntervalMs;this.#r=new MemoryTrend(s)}id(){return this.#o}models(){return this.modelsInternal}runtimeModel(){return this.modelsInternal.values().next().value||null}heapProfilerModel(){const e=this.runtimeModel();return e&&e.heapProfilerModel()}async update(){const e=this.runtimeModel(),s=e&&await e.heapUsage();s&&(this.#i=s.usedSize,this.#r.add(this.#i),IsolateManager.instance().dispatchEventToListeners(Events.MemoryChanged,this))}samplesCount(){return this.#r.count()}usedHeapSize(){return this.#i}usedHeapSizeGrowRate(){return this.#r.fitSlope()}isMainThread(){const e=this.runtimeModel();return!!e&&"main"===e.target().id()}}export class MemoryTrend{#a;#l;#d;#h;#m;#u;#I;#c;#x;constructor(e){this.#a=0|e,this.reset()}reset(){this.#l=Date.now(),this.#d=0,this.#h=[],this.#m=[],this.#u=0,this.#I=0,this.#c=0,this.#x=0}count(){return this.#h.length}add(e,s){const t="number"==typeof s?s:Date.now()-this.#l,n=e;if(this.#h.length===this.#a){const e=this.#h[this.#d],s=this.#m[this.#d];this.#u-=e,this.#I-=s,this.#c-=e*e,this.#x-=e*s}this.#u+=t,this.#I+=n,this.#c+=t*t,this.#x+=t*n,this.#h[this.#d]=t,this.#m[this.#d]=n,this.#d=(this.#d+1)%this.#a}fitSlope(){const e=this.count();return e<2?0:(this.#x-this.#u*this.#I/e)/(this.#c-this.#u*this.#u/e)}}