87 lines
2.0 KiB
TypeScript
87 lines
2.0 KiB
TypeScript
import * as plugins from './smarttime.plugins.js';
|
|
|
|
import { TimeStamp } from './smarttime.classes.timestamp.js';
|
|
|
|
export type TimerState = 'initiated' | 'started' | 'paused' | 'completed';
|
|
|
|
export class Timer {
|
|
/**
|
|
* the original amount of milliseconds for this Timer
|
|
*/
|
|
public timeInMilliseconds: number;
|
|
|
|
/**
|
|
* the state of the timer
|
|
*/
|
|
public state: TimerState = 'initiated';
|
|
|
|
/**
|
|
* completed Promise
|
|
*/
|
|
public completed: Promise<void>;
|
|
|
|
/**
|
|
* a reference to when the Timeout started
|
|
*/
|
|
public startedAt: TimeStamp;
|
|
|
|
/**
|
|
* a reference to when a Timer has been potentially paused
|
|
*/
|
|
public pausedAt: TimeStamp;
|
|
|
|
get timeLeft(): number {
|
|
return this.timeInMilliseconds - this.pausedAt.change;
|
|
}
|
|
/**
|
|
* the current timeout the needs to be canceled when this Timer is stopped
|
|
*/
|
|
private currentTimeout: NodeJS.Timeout;
|
|
|
|
// a deferred triggeted when Timer has completed
|
|
private completedDeferred = plugins.smartpromise.defer<void>();
|
|
|
|
constructor(timeInMillisecondsArg: number) {
|
|
this.timeInMilliseconds = timeInMillisecondsArg;
|
|
this.completed = this.completedDeferred.promise;
|
|
}
|
|
|
|
/**
|
|
* starts the timer
|
|
*/
|
|
public start() {
|
|
if (!this.startedAt) {
|
|
this.currentTimeout = setTimeout(() => {
|
|
this.completedDeferred.resolve();
|
|
}, this.timeInMilliseconds);
|
|
this.startedAt = new TimeStamp();
|
|
} else {
|
|
throw new Error('timer has been started before. Please use resume instead');
|
|
}
|
|
}
|
|
|
|
public pause() {
|
|
if (this.startedAt) {
|
|
clearTimeout(this.currentTimeout);
|
|
this.currentTimeout = null;
|
|
this.pausedAt = TimeStamp.fromTimeStamp(this.startedAt);
|
|
}
|
|
}
|
|
|
|
public resume() {
|
|
if (this.startedAt) {
|
|
this.currentTimeout = setTimeout(() => {
|
|
this.completedDeferred.resolve();
|
|
}, this.timeLeft);
|
|
} else {
|
|
throw new Error('timer has NOT been started before. Please use .start() instead');
|
|
}
|
|
}
|
|
|
|
public reset() {
|
|
this.pause();
|
|
this.startedAt = null;
|
|
this.pausedAt = null;
|
|
}
|
|
}
|