WebXRAbstractFeature.ts 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. import { IWebXRFeature } from '../webXRFeaturesManager';
  2. import { Observer, Observable, EventState } from '../../../Misc/observable';
  3. import { Nullable } from '../../../types';
  4. import { WebXRSessionManager } from '../webXRSessionManager';
  5. /**
  6. * This is the base class for all WebXR features.
  7. * Since most features require almost the same resources and callbacks, this class can be used to simplify the development
  8. * Note that since the features manager is using the `IWebXRFeature` you are in no way obligated to use this class
  9. */
  10. export abstract class WebXRAbstractFeature implements IWebXRFeature {
  11. /**
  12. * Construct a new (abstract) webxr feature
  13. * @param _xrSessionManager the xr session manager for this feature
  14. */
  15. constructor(protected _xrSessionManager: WebXRSessionManager) {
  16. }
  17. private _attached: boolean = false;
  18. private _removeOnDetach: {
  19. observer: Nullable<Observer<any>>;
  20. observable: Observable<any>;
  21. }[] = [];
  22. /**
  23. * Is this feature attached
  24. */
  25. public get attached() {
  26. return this._attached;
  27. }
  28. /**
  29. * attach this feature
  30. *
  31. * @returns true if successful, false is failed or already attached
  32. */
  33. public attach(): boolean {
  34. if (this.attached) {
  35. return false;
  36. }
  37. this._attached = true;
  38. this._addNewAttachObserver(this._xrSessionManager.onXRFrameObservable, (frame) => this._onXRFrame(frame));
  39. return true;
  40. }
  41. /**
  42. * detach this feature.
  43. *
  44. * @returns true if successful, false if failed or already detached
  45. */
  46. public detach(): boolean {
  47. if (!this._attached) {
  48. return false;
  49. }
  50. this._attached = false;
  51. this._removeOnDetach.forEach((toRemove) => {
  52. toRemove.observable.remove(toRemove.observer);
  53. });
  54. return true;
  55. }
  56. /**
  57. * Dispose this feature and all of the resources attached
  58. */
  59. public dispose(): void {
  60. this.detach();
  61. }
  62. /**
  63. * Code in this function will be executed on each xrFrame received from the browser.
  64. * This function will not execute after the feature is detached.
  65. * @param _xrFrame the current frame
  66. */
  67. protected _onXRFrame(_xrFrame: XRFrame): void {
  68. // no-op
  69. }
  70. /**
  71. * This is used to register callbacks that will automatically be removed when detach is called.
  72. * @param observable the observable to which the observer will be attached
  73. * @param callback the callback to register
  74. */
  75. protected _addNewAttachObserver<T>(observable: Observable<T>, callback: (eventData: T, eventState: EventState) => void) {
  76. this._removeOnDetach.push({
  77. observable,
  78. observer: observable.add(callback)
  79. });
  80. }
  81. }