diff options
author | Michael Foiani <sotech117@michaels-mbp-3.devices.brown.edu> | 2022-05-02 15:48:11 -0400 |
---|---|---|
committer | Michael Foiani <sotech117@michaels-mbp-3.devices.brown.edu> | 2022-05-02 15:48:11 -0400 |
commit | 77fe2c80a5843333f9e8828d4ebc0db41a43ba22 (patch) | |
tree | 8337f420c1d9b1bb9d47ec384e6b1b2aff31fe5d /src | |
parent | 813ac366831c95f3fa11e01b9588cf18cbe466bc (diff) |
Add timers that can be paused and resumed for followingMovements
Diffstat (limited to 'src')
-rw-r--r-- | src/client/apis/recording/recordingApi.ts (renamed from src/client/apis/recording/recordingApi.tsx) | 99 |
1 files changed, 95 insertions, 4 deletions
diff --git a/src/client/apis/recording/recordingApi.tsx b/src/client/apis/recording/recordingApi.ts index cce19deec..2fd1d37a7 100644 --- a/src/client/apis/recording/recordingApi.tsx +++ b/src/client/apis/recording/recordingApi.ts @@ -32,7 +32,7 @@ export class RecordingApi { // create static instance and getter for global use @observable static _instance: RecordingApi; public static get instance(): RecordingApi { return RecordingApi._instance } - constructor() { + public constructor() { // init the global instance RecordingApi._instance = this; @@ -46,6 +46,7 @@ export class RecordingApi { // for now, set playFFView this.playFFView = null; + this.timers = null; } // little helper :) @@ -172,6 +173,7 @@ export class RecordingApi { // TODO: extract this into different class with pause and resume recording private playFFView: CollectionFreeFormView | null; + private timers: Timer[] | null; public followMovements = (presentation: Presentation): undefined | Error => { if (presentation.startDate === null || this.playFFView === null) { @@ -180,16 +182,46 @@ export class RecordingApi { const document = this.playFFView.Document const { movements } = presentation - movements.forEach(movement => { + this.timers = movements.map(movement => { const { panX, panY, time } = movement - // set the pan to what was stored - setTimeout(() => { + return new Timer(() => { document._panX = panX; document._panY = panY; + // TODO: consider cleaning this array to null or some state }, time) }) } + public pauseMovements = (): undefined | Error => { + if (this.playFFView === null) { + return new Error('[recordingApi.ts] pauseMovements() failed: no view') + } + this.timers?.forEach(timer => timer.pause()) + } + + public resumeMovements = (): undefined | Error => { + if (this.playFFView === null) { + return new Error('[recordingApi.ts] resumeMovements() failed: no view') + } + this.timers?.forEach(timer => timer.resume()) + } + + // public followMovements = (presentation: Presentation): undefined | Error => { + // if (presentation.startDate === null || this.playFFView === null) { + // return new Error('[recordingApi.ts] followMovements() failed: no presentation data or no view') + // } + + // const document = this.playFFView.Document + // const { movements } = presentation + // movements.forEach(movement => { + // const { panX, panY, time } = movement + // // set the pan to what was stored + // setTimeout(() => { + // document._panX = panX; + // document._panY = panY; + // }, time) + // }) + // } // Unfinished code for tracing multiple free form views // export let pres: Map<CollectionFreeFormView, IReactionDisposer> = new Map() @@ -205,4 +237,63 @@ export class RecordingApi { // disposer?.(); // pres.delete(ffView) // } +} + +/** Represents the `setTimeout` with an ability to perform pause/resume actions + * citation: https://stackoverflow.com/questions/3969475/javascript-pause-settimeout + */ +export class Timer { + private _start: Date; + private _remaining: number; + private _durationTimeoutId?: NodeJS.Timeout; + private _callback: (...args: any[]) => void; + private _done = false; + get done () { + return this._done; + } + + public constructor(callback: (...args: any[]) => void, ms = 0) { + this._callback = () => { + callback(); + this._done = true; + }; + this._remaining = ms; + this.resume(); + } + + /** pauses the timer */ + public pause(): Timer { + if (this._durationTimeoutId && !this._done) { + this._clearTimeoutRef(); + this._remaining -= new Date().getTime() - this._start.getTime(); + } + return this; + } + + /** resumes the timer */ + public resume(): Timer { + if (!this._durationTimeoutId && !this._done) { + this._start = new Date; + this._durationTimeoutId = setTimeout(this._callback, this._remaining); + } + return this; + } + + /** + * clears the timeout and marks it as done. + * + * After called, the timeout will not resume + */ + public clearTimeout() { + this._clearTimeoutRef(); + this._done = true; + } + + private _clearTimeoutRef() { + if (this._durationTimeoutId) { + clearTimeout(this._durationTimeoutId); + this._durationTimeoutId = undefined; + } + } + }
\ No newline at end of file |