minesweeper/src/main/js/Timer.ts

99 lines
2.3 KiB
TypeScript

/**
* Keeps track of time.
*/
export class Timer {
private readonly startTimes: number[] = [];
private readonly endTimes: number[] = [];
/**
* Constructs a new timer.
*
* @param start whether the timer should start running right away
*/
constructor(start: boolean = false) {
if (start) this.start();
}
/**
* Creates an exact copy of this timer.
*
* @returns an exact copy of this timer
*/
copy(): Timer {
const copy = new Timer();
copy.startTimes.concat(this.startTimes);
copy.endTimes.concat(this.endTimes);
return copy;
}
/**
* Returns true if the timer is currently running.
*/
get isRunning(): boolean {
return this.startTimes.length > this.endTimes.length;
}
/**
* Returns the amount of milliseconds that the timer has been running.
*/
get elapsedTime(): number {
return this.endTimes
.map((_, i) => this.endTimes[i] - this.startTimes[i])
.reduce((sum, diff) => sum + diff, 0)
+ (this.isRunning ? (Date.now() - this.startTimes[this.startTimes.length - 1]) : 0);
}
/**
* Starts or resumes the timer.
*/
start(): void {
if (this.isRunning) return;
this.startTimes.push(Date.now());
}
/**
* Stops or pauses the timer.
*/
stop(): void {
if (!this.isRunning) return;
this.endTimes.push(Date.now());
}
/**
* Resets the timer.
*/
clear(): void {
this.startTimes.length = 0;
this.endTimes.length = 0;
}
/**
* Runs the given callback and adds its execution time to this timer.
*
* @param callback the callback to time the execution of
*/
time(callback: () => void): void {
this.start();
callback();
this.stop();
}
/**
* Runs the given callback and returns the number of milliseconds it took to execute.
*
* @param callback the function to time the execution of
* @returns the number of milliseconds the callback took to execute
*/
static time(callback: () => void): number {
const timer = new Timer();
timer.time(callback);
return timer.elapsedTime;
}
}