123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- import { WebXRSessionManager } from './webXRSessionManager';
- import { IDisposable } from '../../scene';
- export interface WebXRFeature extends IDisposable {
- attach(): boolean;
- detach(): boolean;
- }
- export type WebXRFeatureConstructor = (xrSessionManager: WebXRSessionManager, options?: any) => (() => WebXRFeature);
- export class WebXRFeaturesManager implements IDisposable {
- private static readonly _AvailableFeatures: { [name: string]: WebXRFeatureConstructor } = {};
- public static AddWebXRFeature(featureName: string, constructorFunction: WebXRFeatureConstructor) {
- this._AvailableFeatures[featureName] = constructorFunction;
- }
- public static ConstructFeature(featureName: string, xrSessionManager: WebXRSessionManager, options?: any) {
- const constructorFunction = this._AvailableFeatures[featureName];
- if (!constructorFunction) {
- // throw an error? return nothing?
- return;
- }
- return constructorFunction(xrSessionManager, options);
- }
- public static GetAvailableFeatures() {
- return Object.keys(this._AvailableFeatures);
- }
- private features: {
- [name: string]: {
- featureImplementation: WebXRFeature,
- enabled: boolean,
- attached: boolean
- }
- } = {};
- constructor(private xrSessionManager: WebXRSessionManager) {
- this.xrSessionManager.onXRSessionInit.add(() => {
- this.getEnabledFeatures().forEach((featureName) => {
- const feature = this.features[featureName];
- if (feature.enabled && !feature.attached) {
- this.attachFeature(featureName);
- }
- });
- });
- this.xrSessionManager.onXRSessionEnded.add(() => {
- this.getEnabledFeatures().forEach((featureName) => {
- const feature = this.features[featureName];
- if (feature.enabled && feature.attached) {
- // detach, but don't disable!
- this.detachFeature(featureName);
- }
- });
- });
- }
- public enableFeature(featureName: string | { Name: string }, options: any = {}, attachIfPossible: boolean = true): WebXRFeature {
- const name = typeof featureName === 'string' ? featureName : featureName.Name;
- const feature = this.features[name];
- if (!feature || !feature.featureImplementation) {
- const constructFunction = WebXRFeaturesManager.ConstructFeature(name, this.xrSessionManager, options);
- if (!constructFunction) {
- // report error?
- throw new Error(`feature not found - ${name}`);
- }
- this.features[name] = {
- featureImplementation: constructFunction(),
- attached: false,
- enabled: true
- };
- } else {
- // make sure it is enabled now:
- feature.enabled = true;
- }
- // if session started already, request and enable
- if (this.xrSessionManager.session && !feature.attached && attachIfPossible) {
- // enable feature
- this.attachFeature(name);
- }
- return this.features[name].featureImplementation;
- }
- public disableFeature(featureName: string | { Name: string }) {
- const name = typeof featureName === 'string' ? featureName : featureName.Name;
- const feature = this.features[name];
- if (feature && feature.enabled) {
- feature.enabled = false;
- this.detachFeature(name);
- }
- }
- public attachFeature(featureName: string) {
- const feature = this.features[featureName];
- if (feature && feature.enabled && !feature.attached) {
- feature.featureImplementation.attach();
- feature.attached = true;
- }
- }
- public detachFeature(featureName: string) {
- const feature = this.features[featureName];
- if (feature && feature.attached) {
- feature.featureImplementation.detach();
- feature.attached = false;
- }
- }
- public getEnabledFeatures() {
- return Object.keys(this.features);
- }
- public getEnabledFeature(featureName: string) {
- return this.features[featureName] && this.features[featureName].featureImplementation;
- }
- dispose(): void {
- this.getEnabledFeatures().forEach((feature) => this.features[feature].featureImplementation.dispose());
- }
- }
|