Browse Source

Refactoring. Make Session._media private

customisations
alemart 10 months ago
parent
commit
e14cf3f1dd
2 changed files with 61 additions and 23 deletions
  1. 40
    22
      src/core/session.ts
  2. 21
    1
      src/trackers/image-tracker/image-tracker.ts

+ 40
- 22
src/core/session.ts View File

35
 import { Tracker } from '../trackers/tracker';
35
 import { Tracker } from '../trackers/tracker';
36
 import { Time } from './time';
36
 import { Time } from './time';
37
 import { Source } from '../sources/source';
37
 import { Source } from '../sources/source';
38
+import { VideoSource } from '../sources/video-source';
39
+import { CanvasSource } from '../sources/canvas-source';
38
 import { asap } from '../utils/asap';
40
 import { asap } from '../utils/asap';
39
 
41
 
40
 /** Session mode */
42
 /** Session mode */
107
     /** Rendering viewport */
109
     /** Rendering viewport */
108
     private readonly _viewport: Viewport;
110
     private readonly _viewport: Viewport;
109
 
111
 
112
+    /** Primary source of data */
113
+    private readonly _primarySource: VideoSource | CanvasSource;
114
+
110
     /** Time Manager */
115
     /** Time Manager */
111
     private _time: Time;
116
     private _time: Time;
112
 
117
 
161
         if(mode != 'immersive' && mode != 'inline')
166
         if(mode != 'immersive' && mode != 'inline')
162
             throw new IllegalArgumentError(`Invalid session mode "${mode}"`);
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
         // setup the viewport
172
         // setup the viewport
165
         this._viewport = viewport;
173
         this._viewport = viewport;
166
-        this._viewport._init(() => this.media.size, mode);
174
+        this._viewport._init(() => this._media.size, mode);
167
 
175
 
168
         // setup the main loop
176
         // setup the main loop
169
         this._setupUpdateLoop();
177
         this._setupUpdateLoop();
283
         }).then(() => {
291
         }).then(() => {
284
 
292
 
285
             // validate sources of data
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
             for(let i = sources.length - 1; i >= 0; i--) {
294
             for(let i = sources.length - 1; i >= 0; i--) {
291
                 if(sources.indexOf(sources[i]) < i)
295
                 if(sources.indexOf(sources[i]) < i)
292
                     throw new IllegalArgumentError(`Found repeated sources of data`);
296
                     throw new IllegalArgumentError(`Found repeated sources of data`);
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
      * Session mode
431
      * Session mode
443
      */
432
      */
444
     get mode(): SessionMode
433
     get mode(): SessionMode
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
      * Attach a tracker to the session
516
      * Attach a tracker to the session
499
      * @param tracker
517
      * @param tracker
500
      */
518
      */
517
         const canvas = this._viewport._backgroundCanvas;
535
         const canvas = this._viewport._backgroundCanvas;
518
         const ctx = canvas.getContext('2d', { alpha: false });
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
             ctx.imageSmoothingEnabled = false;
539
             ctx.imageSmoothingEnabled = false;
522
 
540
 
523
             // draw user media
541
             // draw user media
524
-            const image = this.media.source as CanvasImageSource;
542
+            const image = this._media.source as CanvasImageSource;
525
             ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
543
             ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
526
 
544
 
527
             // render output image(s)
545
             // render output image(s)

+ 21
- 1
src/trackers/image-tracker/image-tracker.ts View File

31
 import { SpeedyPipelineNodeResize } from 'speedy-vision/types/core/pipeline/nodes/transforms/resize';
31
 import { SpeedyPipelineNodeResize } from 'speedy-vision/types/core/pipeline/nodes/transforms/resize';
32
 import { SpeedyPipelineNodeFASTKeypointDetector } from 'speedy-vision/types/core/pipeline/nodes/keypoints/detectors/fast';
32
 import { SpeedyPipelineNodeFASTKeypointDetector } from 'speedy-vision/types/core/pipeline/nodes/keypoints/detectors/fast';
33
 import { SpeedyKeypoint } from 'speedy-vision/types/core/speedy-keypoint';
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
 import { Tracker, TrackerOutput, TrackerResult, Trackable } from '../tracker';
36
 import { Tracker, TrackerOutput, TrackerResult, Trackable } from '../tracker';
35
 import { Session } from '../../core/session';
37
 import { Session } from '../../core/session';
36
 import { IllegalOperationError, IllegalArgumentError } from '../../utils/errors';
38
 import { IllegalOperationError, IllegalArgumentError } from '../../utils/errors';
129
     /** session */
131
     /** session */
130
     private _session: Nullable<Session>;
132
     private _session: Nullable<Session>;
131
 
133
 
134
+    /** source of data */
135
+    private _source: Nullable<VideoSource | CanvasSource>;
136
+
132
     /** all states */
137
     /** all states */
133
     private readonly _state: Record<ImageTrackerStateName, ImageTrackerState>;
138
     private readonly _state: Record<ImageTrackerStateName, ImageTrackerState>;
134
 
139
 
164
 
169
 
165
         // initial setup
170
         // initial setup
166
         this._session = null;
171
         this._session = null;
172
+        this._source = null;
167
         this._activeStateName = 'initial';
173
         this._activeStateName = 'initial';
168
         this._lastOutput = { };
174
         this._lastOutput = { };
169
         this._database = new ReferenceImageDatabase();
175
         this._database = new ReferenceImageDatabase();
251
         // store the session
257
         // store the session
252
         this._session = session;
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
         // initialize states
274
         // initialize states
255
         for(const state of Object.values(this._state))
275
         for(const state of Object.values(this._state))
256
             state.init();
276
             state.init();
290
 
310
 
291
         // compute the screen size for image processing purposes
311
         // compute the screen size for image processing purposes
292
         // note: this may change over time...!
312
         // note: this may change over time...!
293
-        const media = this._session.media;
313
+        const media = this._source!._data;
294
         const aspectRatio = media.width / media.height;
314
         const aspectRatio = media.width / media.height;
295
         const screenSize = Utils.resolution(this._resolution, aspectRatio);
315
         const screenSize = Utils.resolution(this._resolution, aspectRatio);
296
 
316
 

Loading…
Cancel
Save