All files / ts engineCanvas.ts

100% Statements 44/44
100% Branches 18/18
100% Functions 7/7
100% Lines 44/44

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 781x 1x 1x 1x 1x 1x           1x           18x 18x 18x       5x 5x 5x       23x 21x   2x 2x 2x       1x 1x       2x 2x       1x 1x 1x 1x 1x 1x 1x 1x 1x       4x 4x 4x 1x   3x 2x 2x 2x 1x 1x 1x 1x     2x    
import { SurfaceSettings } from "./controller/surface/surfaceSettings.js";
import { EngineCore, IEngineCore } from "./engineCore.js";
import { FactoryContext } from "./factories/factoryContext.js";
import { FactoryInput } from "./factories/factoryInput.js";
import { FactorySurface } from "./factories/factorySurface.js";
import { IVector2, Vector2 } from "./models/vector2.js";
 
export interface IEngineCanvas extends HTMLElement {
    connectedCallback(): void;
    disconnectedCallback(): void;
}
export class EngineCanvas extends HTMLElement implements IEngineCanvas {
 
    private static _window: Window;
    private _engineCore?: IEngineCore;
 
    public static getCanvas(canvasId: string, window: Window): EngineCanvas | undefined {
        this.connectCanvas(window);
        const document = this._window.document;
        return <EngineCanvas>document.getElementById(canvasId);
    }
 
    public static getEngine(canvasId: string, window: Window): IEngineCore | undefined {
        this.connectCanvas(window);
        const engineCanvas = EngineCanvas.getCanvas(canvasId, window);
        return engineCanvas?._engineCore;
    }
 
    private static connectCanvas(window: Window): void {
        if (!window || this._window === window)
            return;
 
        this._window = window;
        const customElements = window.customElements;
        customElements.define("engine-canvas", this);
    }
 
    public connectedCallback(): void {
        const window = EngineCanvas._window;
        this.initializeEngine(window);
    }
 
    public disconnectedCallback(): void {
        this._engineCore?.destroy();
        this.replaceChildren();
    }
 
    private initializeEngine(window: Window): void {
        const targetFrameRate = this.getAttributeValue<number>("target-frame-rate", 60);
        const targetFrameLimit = this.getAttributeValue<number>("target-frame-limit", 0);
        const targetResolution = this.getAttributeValue<IVector2>("target-resolution", new Vector2(1920, 1080));
        const maxResolution = this.getAttributeValue<IVector2>("max-resolution", new Vector2());
        const inputFactory = new FactoryInput(this);
        const contextFactory = new FactoryContext(this, window.document);
        const surfaceSettings = new SurfaceSettings(targetFrameRate, targetFrameLimit, targetResolution, maxResolution);
        const surfaceFactory = new FactorySurface(surfaceSettings, window);
        this._engineCore = new EngineCore(surfaceSettings, surfaceFactory, contextFactory, inputFactory, window);
    }
 
    private getAttributeValue<T>(attributeName: string, defaultValue: T): T {
        let attributeValue = defaultValue;
        const attribute = this.getAttribute(attributeName);
        if (!attribute) {
            return attributeValue;
        }
        if (defaultValue instanceof Vector2) {
            const resolutionLowerCase = attribute.toLowerCase();
            const resolutionArray = resolutionLowerCase.split("x");
            if (resolutionArray.length > 1) {
                const resolution = new Vector2();
                resolution.x = parseInt(<string>resolutionArray[0]);
                resolution.y = parseInt(<string>resolutionArray[1]);
                return <T>resolution;
            }
        }
        return <T>parseInt(attribute);
    }
}