All files / app/codeCharta/ui/codeMap/threeViewer threeStats.service.ts

100% Statements 48/48
87.5% Branches 7/8
100% Functions 8/8
100% Lines 47/47

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 8922x 22x 22x   22x             22x             104x   104x   104x 20x 15x   15x 15x 15x   15x   15x   15x       104x 23x     104x 16x 16x 16x 16x   16x     104x 4x 3x 3x 2x 2x 2x 2x 2x 2x 2x   3x       104x 2x 1x 4x 4x           104x 9x 9x     104x 2x 1x        
import Stats from "three/examples/jsm/libs/stats.module"
import { ThreeRendererService } from "./threeRenderer.service"
import { Injectable, isDevMode } from "@angular/core"
 
const ONE_SECOND = 1000
export interface CustomPanel {
    panel: Stats.Panel
    maxHeight: number
}
 
@Injectable({ providedIn: "root" })
export class ThreeStatsService {
    stats: Stats
    trianglesPanel: CustomPanel
    glCallsPanel: CustomPanel
    geometryMemoryPanel: CustomPanel
    textureMemoryPanel: CustomPanel
    prevTime: number
    isDevelopmentMode = isDevMode()
 
    constructor(private threeRendererService: ThreeRendererService) {}
 
    init = (canvasElement: Element) => {
        if (this.isDevelopmentMode) {
            this.stats = new Stats()
 
            this.stats.dom.style.position = "absolute"
            this.stats.dom.style.left = "0"
            this.stats.dom.style.top = "0"
 
            canvasElement.append(this.stats.dom)
 
            this.generateStatPanels()
 
            this.prevTime = this.getTimeFunctor().now()
        }
    }
 
    private getTimeFunctor = () => {
        return typeof performance === "undefined" ? Date : performance
    }
 
    private generateStatPanels = () => {
        this.trianglesPanel = { panel: this.stats.addPanel(new Stats.Panel("triangles", "#ff8", "#221")), maxHeight: 0 }
        this.glCallsPanel = { panel: this.stats.addPanel(new Stats.Panel("calls", "#f8f", "#212")), maxHeight: 0 }
        this.geometryMemoryPanel = { panel: this.stats.addPanel(new Stats.Panel("geo. mem", "#f08", "#221")), maxHeight: 0 }
        this.textureMemoryPanel = { panel: this.stats.addPanel(new Stats.Panel("tex. mem", "#0f8", "#221")), maxHeight: 0 }
 
        this.stats.showPanel(3)
    }
 
    updateStats = () => {
        if (this.isDevelopmentMode) {
            const time = this.getTimeFunctor().now()
            if (time >= this.prevTime + ONE_SECOND) {
                this.prevTime = time
                const webGLInfo = this.threeRendererService.getInfo()
                const threeJsInfo = this.threeRendererService.getMemoryInfo()
                this.processPanel(this.trianglesPanel, webGLInfo.triangles)
                this.processPanel(this.glCallsPanel, webGLInfo.calls)
                this.processPanel(this.geometryMemoryPanel, threeJsInfo.geometries)
                this.processPanel(this.textureMemoryPanel, threeJsInfo.textures)
            }
            this.stats.update()
        }
    }
 
    resetPanels = () => {
        if (this.isDevelopmentMode) {
            for (const panel of [this.trianglesPanel, this.glCallsPanel, this.geometryMemoryPanel, this.textureMemoryPanel]) {
                if (panel !== undefined) {
                    panel.maxHeight = 0
                }
            }
        }
    }
 
    private processPanel = (customPanel: CustomPanel, value: number) => {
        customPanel.maxHeight = Math.max(customPanel.maxHeight, value)
        customPanel.panel.update(value, customPanel.maxHeight * 1.3)
    }
 
    destroy = () => {
        if (this.isDevelopmentMode) {
            this.stats.dom.remove()
        }
    }
}