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

Refactoring. Make Session._media private

customisations
alemart 10 місяці тому
джерело
коміт
e14cf3f1dd
2 змінених файлів з 61 додано та 23 видалено
  1. 40
    22
      src/core/session.ts
  2. 21
    1
      src/trackers/image-tracker/image-tracker.ts

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

@@ -35,6 +35,8 @@ import { Frame } from './frame';
35 35
 import { Tracker } from '../trackers/tracker';
36 36
 import { Time } from './time';
37 37
 import { Source } from '../sources/source';
38
+import { VideoSource } from '../sources/video-source';
39
+import { CanvasSource } from '../sources/canvas-source';
38 40
 import { asap } from '../utils/asap';
39 41
 
40 42
 /** Session mode */
@@ -107,6 +109,9 @@ export class Session extends AREventTarget<SessionEventType>
107 109
     /** Rendering viewport */
108 110
     private readonly _viewport: Viewport;
109 111
 
112
+    /** Primary source of data */
113
+    private readonly _primarySource: VideoSource | CanvasSource;
114
+
110 115
     /** Time Manager */
111 116
     private _time: Time;
112 117
 
@@ -161,9 +166,12 @@ export class Session extends AREventTarget<SessionEventType>
161 166
         if(mode != 'immersive' && mode != 'inline')
162 167
             throw new IllegalArgumentError(`Invalid session mode "${mode}"`);
163 168
 
169
+        // find the primary source of data
170
+        this._primarySource = this._findPrimarySource(sources);
171
+
164 172
         // setup the viewport
165 173
         this._viewport = viewport;
166
-        this._viewport._init(() => this.media.size, mode);
174
+        this._viewport._init(() => this._media.size, mode);
167 175
 
168 176
         // setup the main loop
169 177
         this._setupUpdateLoop();
@@ -283,10 +291,6 @@ export class Session extends AREventTarget<SessionEventType>
283 291
         }).then(() => {
284 292
 
285 293
             // validate sources of data
286
-            const videoSources = sources.filter(source => source._type == 'video');
287
-            if(videoSources.length != 1)
288
-                throw new IllegalArgumentError(`One video source of data must be provided`);
289
-
290 294
             for(let i = sources.length - 1; i >= 0; i--) {
291 295
                 if(sources.indexOf(sources[i]) < i)
292 296
                     throw new IllegalArgumentError(`Found repeated sources of data`);
@@ -424,21 +428,6 @@ export class Session extends AREventTarget<SessionEventType>
424 428
     }
425 429
 
426 430
     /**
427
-     * The underlying media (generally a camera stream)
428
-     * @internal
429
-     */
430
-    get media(): SpeedyMedia
431
-    {
432
-        for(let i = this._sources.length - 1; i >= 0; i--) {
433
-            if(this._sources[i]._type == 'video')
434
-                return this._sources[i]._data as SpeedyMedia;
435
-        }
436
-
437
-        // this shouldn't happen
438
-        throw new IllegalOperationError(`Invalid input source`);
439
-    }
440
-
441
-    /**
442 431
      * Session mode
443 432
      */
444 433
     get mode(): SessionMode
@@ -495,6 +484,35 @@ export class Session extends AREventTarget<SessionEventType>
495 484
     }
496 485
 
497 486
     /**
487
+     * Find the primary source of data (generally a camera stream)
488
+     * @param sources
489
+     * @returns the primary source
490
+     */
491
+    private _findPrimarySource(sources: Source[]): VideoSource | CanvasSource
492
+    {
493
+        // prefer video sources
494
+        for(let i = 0; i < sources.length; i++) {
495
+            if(sources[i]._type == 'video')
496
+                return sources[i] as VideoSource;
497
+        }
498
+        for(let i = 0; i < sources.length; i++) {
499
+            if(sources[i]._type == 'canvas')
500
+                return sources[i] as CanvasSource;
501
+        }
502
+
503
+        // this shouldn't happen
504
+        throw new IllegalOperationError(`No primary source of data was found!`);
505
+    }
506
+
507
+    /**
508
+     * The media of the primary source of data
509
+     */
510
+    private get _media(): SpeedyMedia
511
+    {
512
+        return this._primarySource._data;
513
+    }
514
+
515
+    /**
498 516
      * Attach a tracker to the session
499 517
      * @param tracker
500 518
      */
@@ -517,11 +535,11 @@ export class Session extends AREventTarget<SessionEventType>
517 535
         const canvas = this._viewport._backgroundCanvas;
518 536
         const ctx = canvas.getContext('2d', { alpha: false });
519 537
         
520
-        if(ctx && this.media.type != 'data') {
538
+        if(ctx && this._media.type != 'data') {
521 539
             ctx.imageSmoothingEnabled = false;
522 540
 
523 541
             // draw user media
524
-            const image = this.media.source as CanvasImageSource;
542
+            const image = this._media.source as CanvasImageSource;
525 543
             ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
526 544
 
527 545
             // render output image(s)

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

@@ -31,6 +31,8 @@ import { SpeedyPipelineNodeImageSource } from 'speedy-vision/types/core/pipeline
31 31
 import { SpeedyPipelineNodeResize } from 'speedy-vision/types/core/pipeline/nodes/transforms/resize';
32 32
 import { SpeedyPipelineNodeFASTKeypointDetector } from 'speedy-vision/types/core/pipeline/nodes/keypoints/detectors/fast';
33 33
 import { SpeedyKeypoint } from 'speedy-vision/types/core/speedy-keypoint';
34
+import { VideoSource } from '../../sources/video-source';
35
+import { CanvasSource } from '../../sources/canvas-source';
34 36
 import { Tracker, TrackerOutput, TrackerResult, Trackable } from '../tracker';
35 37
 import { Session } from '../../core/session';
36 38
 import { IllegalOperationError, IllegalArgumentError } from '../../utils/errors';
@@ -129,6 +131,9 @@ export class ImageTracker extends AREventTarget<ImageTrackerEventType> implement
129 131
     /** session */
130 132
     private _session: Nullable<Session>;
131 133
 
134
+    /** source of data */
135
+    private _source: Nullable<VideoSource | CanvasSource>;
136
+
132 137
     /** all states */
133 138
     private readonly _state: Record<ImageTrackerStateName, ImageTrackerState>;
134 139
 
@@ -164,6 +169,7 @@ export class ImageTracker extends AREventTarget<ImageTrackerEventType> implement
164 169
 
165 170
         // initial setup
166 171
         this._session = null;
172
+        this._source = null;
167 173
         this._activeStateName = 'initial';
168 174
         this._lastOutput = { };
169 175
         this._database = new ReferenceImageDatabase();
@@ -251,6 +257,20 @@ export class ImageTracker extends AREventTarget<ImageTrackerEventType> implement
251 257
         // store the session
252 258
         this._session = session;
253 259
 
260
+        // find a suitable source of data
261
+        // XXX also let the user specify a source manually?
262
+        for(const source of session.sources) {
263
+            // prefer video sources
264
+            if(source._type == 'video') {
265
+                this._source = source as VideoSource;
266
+                break;
267
+            }
268
+            else if(source._type == 'canvas')
269
+                this._source = source as CanvasSource;
270
+        }
271
+        if(this._source === null)
272
+            throw new IllegalOperationError('The image tracker requires a suitable source of data');
273
+
254 274
         // initialize states
255 275
         for(const state of Object.values(this._state))
256 276
             state.init();
@@ -290,7 +310,7 @@ export class ImageTracker extends AREventTarget<ImageTrackerEventType> implement
290 310
 
291 311
         // compute the screen size for image processing purposes
292 312
         // note: this may change over time...!
293
-        const media = this._session.media;
313
+        const media = this._source!._data;
294 314
         const aspectRatio = media.width / media.height;
295 315
         const screenSize = Utils.resolution(this._resolution, aspectRatio);
296 316
 

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