Переглянути джерело

Improve the typings of AR Events

customisations
alemart 2 місяці тому
джерело
коміт
8e7f99690f

+ 1
- 1
src/core/session.ts Переглянути файл

@@ -93,7 +93,7 @@ const DEFAULT_OPTIONS: Readonly<Required<SessionOptions>> = {
93 93
  * A Session represents an intent to display AR content
94 94
  * and encapsulates the main loop (update-render cycle)
95 95
  */
96
-export class Session extends AREventTarget<SessionEventType>
96
+export class Session extends AREventTarget<SessionEvent>
97 97
 {
98 98
     /** Number of active sessions */
99 99
     private static _count = 0;

+ 5
- 7
src/core/viewport.ts Переглянути файл

@@ -46,13 +46,10 @@ type ViewportSizeGetter = () => SpeedySize;
46 46
 type ViewportEventType = 'resize' | 'fullscreenchange';
47 47
 
48 48
 /** An event emitted by a Viewport */
49
-class ViewportEvent extends AREvent<ViewportEventType> { }
50
-
51
-/** Viewport event target */
52
-class ViewportEventTarget extends AREventTarget<ViewportEventType> { }
49
+export class ViewportEvent extends AREvent<ViewportEventType> { }
53 50
 
54 51
 /** Viewport style (immersive mode) */
55
-type ViewportStyle = 'best-fit' | 'stretch' | 'crop' | 'inline';
52
+export type ViewportStyle = 'best-fit' | 'stretch' | 'crop' | 'inline';
56 53
 
57 54
 
58 55
 
@@ -704,8 +701,9 @@ class ViewportResizer
704 701
 
705 702
     /**
706 703
      * Called when the viewport receives a 'resize' event
704
+     * @param event
707 705
      */
708
-    private _onViewportResize(): void
706
+    private _onViewportResize(event: ViewportEvent): void
709 707
     {
710 708
         const viewport = this._viewport;
711 709
 
@@ -948,7 +946,7 @@ class CropResizeStrategy extends ImmersiveResizeStrategy
948 946
 /**
949 947
  * Viewport
950 948
  */
951
-export class Viewport extends ViewportEventTarget
949
+export class Viewport extends AREventTarget<ViewportEvent>
952 950
 {
953 951
     /** Viewport resolution (controls the size of the drawing buffer of the foreground canvas) */
954 952
     private readonly _resolution: Resolution;

+ 1
- 1
src/trackers/image-tracker/image-tracker.ts Переглянути файл

@@ -119,7 +119,7 @@ const DEFAULT_OPTIONS: Readonly<ImageTrackerOptions> = {
119 119
 /**
120 120
  * The ImageTracker tracks an image (one at a time)
121 121
  */
122
-export class ImageTracker extends AREventTarget<ImageTrackerEventType> implements Tracker
122
+export class ImageTracker extends AREventTarget<ImageTrackerEvent> implements Tracker
123 123
 {
124 124
     /** session */
125 125
     private _session: Nullable<Session>;

+ 5
- 7
src/ui/fullscreen-button.ts Переглянути файл

@@ -20,7 +20,7 @@
20 20
  * A built-in fullscreen button introduced as a convenience
21 21
  */
22 22
 
23
-import { Viewport } from '../core/viewport';
23
+import { Viewport, ViewportEvent } from '../core/viewport';
24 24
 
25 25
 /** Button icon to be displayed when the fullscreen mode is disabled */
26 26
 const BUTTON_ICON_OFF = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAbUlEQVRYR+2WOQ4AIAgE5f+PVhobDZANBZAsraAwXMoqFil+f9GBj8BW8dIiKt45at/XgShStHgvmfdekwAdIIEyAmh1Z/U5ikmABPoRsLZWtt+5DUlgHgGr6qM1Pf9XnO131L7fJEQjyOqXEzjP1YAhNmUTrgAAAABJRU5ErkJggg==';
@@ -47,8 +47,6 @@ export class FullscreenButton
47 47
     /** The HTML element of the button */
48 48
     private readonly _button: HTMLButtonElement;
49 49
 
50
-    /** Bound event handler */
51
-    private readonly _boundEventHandler: EventListener;
52 50
 
53 51
 
54 52
 
@@ -60,7 +58,7 @@ export class FullscreenButton
60 58
     {
61 59
         this._viewport = viewport;
62 60
         this._button = this._createButton();
63
-        this._boundEventHandler = this._handleFullscreenEvent.bind(this);
61
+        this._handleFullscreenEvent = this._handleFullscreenEvent.bind(this);
64 62
     }
65 63
 
66 64
     /**
@@ -72,7 +70,7 @@ export class FullscreenButton
72 70
     {
73 71
         parent.appendChild(this._button);
74 72
         this._button.hidden = !isVisible;
75
-        this._viewport.addEventListener('fullscreenchange', this._boundEventHandler);
73
+        this._viewport.addEventListener('fullscreenchange', this._handleFullscreenEvent);
76 74
     }
77 75
 
78 76
     /**
@@ -80,7 +78,7 @@ export class FullscreenButton
80 78
      */
81 79
     release(): void
82 80
     {
83
-        this._viewport.removeEventListener('fullscreenchange', this._boundEventHandler);
81
+        this._viewport.removeEventListener('fullscreenchange', this._handleFullscreenEvent);
84 82
         this._button.remove();
85 83
     }
86 84
 
@@ -145,7 +143,7 @@ export class FullscreenButton
145 143
     /**
146 144
      * Handle a fullscreenchange event
147 145
      */
148
-    private _handleFullscreenEvent(event: Event): void
146
+    private _handleFullscreenEvent(event: ViewportEvent): void
149 147
     {
150 148
         const img = this._viewport.fullscreen ? BUTTON_ICON_ON : BUTTON_ICON_OFF;
151 149
         this._button.style.backgroundImage = 'url(' + img + ')';

+ 22
- 11
src/utils/ar-events.ts Переглянути файл

@@ -22,15 +22,11 @@
22 22
 
23 23
 /**
24 24
  * AR Event Type
25
+ * @internal
25 26
  */
26 27
 type AREventType = string;
27 28
 
28 29
 /**
29
- * AR Event Listener (callback)
30
- */
31
-export type AREventListener = EventListener;
32
-
33
-/**
34 30
  * AR Event
35 31
  */
36 32
 export class AREvent<T extends AREventType> extends Event
@@ -54,9 +50,24 @@ export class AREvent<T extends AREventType> extends Event
54 50
 }
55 51
 
56 52
 /**
53
+ * Extract the AREventType from an AREvent
54
+ * @internal
55
+ */
56
+type AREventTypeOf<T> = T extends AREvent<infer U> ? U : never;
57
+
58
+/**
59
+ * AR Event Listener (a callback)
60
+ * @internal
61
+ */
62
+interface AREventListener<T>
63
+{
64
+    (evt: T extends AREvent<infer U> ? T : never): void;
65
+}
66
+
67
+/**
57 68
  * AR Event Target
58 69
  */
59
-export class AREventTarget<T extends AREventType> implements EventTarget
70
+export class AREventTarget<T>
60 71
 {
61 72
     /** event target delegate */
62 73
     private readonly _delegate: EventTarget;
@@ -76,9 +87,9 @@ export class AREventTarget<T extends AREventType> implements EventTarget
76 87
      * @param type event type
77 88
      * @param callback
78 89
      */
79
-    addEventListener(type: T, callback: AREventListener): void
90
+    addEventListener(type: AREventTypeOf<T>, callback: AREventListener<T>): void
80 91
     {
81
-        this._delegate.addEventListener(type, callback);
92
+        this._delegate.addEventListener(type, callback as EventListener);
82 93
     }
83 94
 
84 95
     /**
@@ -86,9 +97,9 @@ export class AREventTarget<T extends AREventType> implements EventTarget
86 97
      * @param type event type
87 98
      * @param callback
88 99
      */
89
-    removeEventListener(type: T, callback: AREventListener): void
100
+    removeEventListener(type: AREventTypeOf<T>, callback: AREventListener<T>): void
90 101
     {
91
-        this._delegate.removeEventListener(type, callback);
102
+        this._delegate.removeEventListener(type, callback as EventListener);
92 103
     }
93 104
 
94 105
     /**
@@ -97,7 +108,7 @@ export class AREventTarget<T extends AREventType> implements EventTarget
97 108
      * @returns same value as a standard event target
98 109
      * @internal
99 110
      */
100
-    dispatchEvent(event: AREvent<T>): boolean
111
+    dispatchEvent(event: T extends AREvent<infer U> ? T : never): boolean
101 112
     {
102 113
         return this._delegate.dispatchEvent(event);
103 114
     }

Завантаження…
Відмінити
Зберегти