@awayjs/stage
Version:
Stage for AwayJS
146 lines (121 loc) • 4.74 kB
text/typescript
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)
}
}