UNPKG

@awayjs/stage

Version:
146 lines (121 loc) 4.74 kB
import { EventDispatcher, ArgumentError } from '@awayjs/core'; import { ContextMode } from '../base/ContextMode'; import { ContextGLProfile } from '../base/ContextGLProfile'; import { StageEvent } from '../events/StageEvent'; import { Stage } from '../Stage'; /** * The StageManager class provides a multiton object that handles management for Stage objects. * * @see away.base.Stage */ export class StageManager extends EventDispatcher { private static STAGE_MAX_QUANTITY: number = 8; private _stages: Array<Stage>; public static htmlCanvas: HTMLCanvasElement = null; private static _instance: StageManager; private static _numStages: number = 0; private _onContextCreatedDelegate: (event: StageEvent) => void; /** * Creates a new StageManager class. * @param stage The Stage object that contains the Stage objects to be managed. * @private */ constructor() { super(); this._stages = new Array<Stage>(StageManager.STAGE_MAX_QUANTITY); this._onContextCreatedDelegate = (event: StageEvent) => this.onContextCreated(event); } /** * Gets a StageManager instance for the given Stage object. * @param stage The Stage object that contains the Stage objects to be managed. * @return The StageManager instance for the given Stage object. */ public static getInstance(): StageManager { if (this._instance == null) this._instance = new StageManager(); return this._instance; } /** * Requests the Stage for the given index. * * @param index The index of the requested Stage. * @param forceSoftware Whether to force software mode even if hardware acceleration is available. * @param profile The compatibility profile, an enumeration of ContextProfile * @return The Stage for the given index. */ public getStageAt(index: number, forceSoftware: boolean = false, profile: ContextGLProfile = ContextGLProfile.BASELINE, mode: ContextMode = ContextMode.AUTO, alpha: boolean = false): Stage { if (index < 0 || index >= StageManager.STAGE_MAX_QUANTITY) throw new ArgumentError('Index is out of bounds [0..' + StageManager.STAGE_MAX_QUANTITY + ']'); if (!this._stages[index]) { StageManager._numStages++; if (document && StageManager.htmlCanvas == null) { var canvas: HTMLCanvasElement = document.createElement('canvas'); canvas.id = 'stage' + index; document.body.appendChild(canvas); } else if (StageManager.htmlCanvas) { var canvas: HTMLCanvasElement = StageManager.htmlCanvas; } const stage: Stage = this._stages[index] = new Stage(canvas, index, this, forceSoftware, profile); stage.addEventListener(StageEvent.CONTEXT_CREATED, this._onContextCreatedDelegate); stage.requestContext(forceSoftware, profile, mode, alpha); } return this._stages[index]; } /** * Removes a Stage from the manager. * @param stage * @private */ public iRemoveStage(stage: Stage): void { StageManager._numStages--; stage.removeEventListener(StageEvent.CONTEXT_CREATED, this._onContextCreatedDelegate); this._stages[stage.stageIndex] = null; } /** * Get the next available stage. An error is thrown if there are no StageProxies available * @param forceSoftware Whether to force software mode even if hardware acceleration is available. * @param profile The compatibility profile, an enumeration of ContextProfile * @return The allocated stage */ public getFreeStage(forceSoftware: boolean = false, profile: ContextGLProfile = ContextGLProfile.BASELINE, mode: ContextMode = ContextMode.AUTO, alpha: boolean = false): Stage { let i: number = 0; const len: number = this._stages.length; while (i < len) { if (!this._stages[i]) return this.getStageAt(i, forceSoftware, profile, mode, alpha); ++i; } return null; } /** * Checks if a new stage can be created and managed by the class. * @return true if there is one slot free for a new stage */ public get hasFreeStage(): boolean { return StageManager._numStages < StageManager.STAGE_MAX_QUANTITY ? true : false; } /** * Returns the amount of stage objects that can be created and managed by the class * @return the amount of free slots */ public get numSlotsFree(): number { return StageManager.STAGE_MAX_QUANTITY - StageManager._numStages; } /** * Returns the amount of Stage objects currently managed by the class. * @return the amount of slots used */ public get numSlotsUsed(): number { return StageManager._numStages; } /** * The maximum amount of Stage objects that can be managed by the class */ public get numSlotsTotal(): number { return this._stages.length; } private onContextCreated(event: StageEvent): void { //var stage:Stage = <Stage> e.target; //document.body.appendChild(stage.canvas) } }