mirror of
https://github.com/cpvalente/ontime.git
synced 2026-08-06 16:03:52 +00:00
115 lines
2.9 KiB
TypeScript
115 lines
2.9 KiB
TypeScript
import { timerConfig } from '../setup/config.js';
|
|
import * as runtimeState from '../stores/runtimeState.js';
|
|
import type { UpdateResult } from '../stores/runtimeState.js';
|
|
|
|
type UpdateCallbackFn = (updateResult: UpdateResult) => void;
|
|
|
|
/**
|
|
* Manages Ontime's main timer
|
|
*/
|
|
export class EventTimer {
|
|
private readonly _interval: NodeJS.Timeout;
|
|
/** how often we recalculate */
|
|
static _refreshInterval: number;
|
|
|
|
/** when timer will be finished */
|
|
private endCallback: NodeJS.Timeout | undefined = undefined;
|
|
|
|
private onUpdateCallback: UpdateCallbackFn | undefined = undefined;
|
|
|
|
/**
|
|
* @constructor
|
|
* @param {number} [timerConfig.refresh] how often we recalculate
|
|
* @param {number} [timerConfig.updateInterval] how often we update the socket
|
|
* @param {function} [timerConfig.onUpdateCallback] how often we update the socket
|
|
*/
|
|
constructor(timerConfig: { refresh: number; updateInterval: number }) {
|
|
EventTimer._refreshInterval = timerConfig.refresh;
|
|
this._interval = setInterval(() => {
|
|
this.update();
|
|
}, EventTimer._refreshInterval);
|
|
}
|
|
|
|
/**
|
|
* Allows setting a callback for when the timer updates
|
|
*/
|
|
setOnUpdateCallback(callback: (updateResult: UpdateResult) => void) {
|
|
this.onUpdateCallback = callback;
|
|
}
|
|
|
|
start() {
|
|
if (!runtimeState.start()) {
|
|
return false;
|
|
}
|
|
|
|
const state = runtimeState.getState();
|
|
|
|
// eslint-disable-next-line no-unused-labels -- dev code path
|
|
DEV: {
|
|
if (state.timer.current === null) {
|
|
throw new Error('EventTimer.start: invalid state received');
|
|
}
|
|
}
|
|
|
|
// register a callback for the scheduled end
|
|
const endTime = state.timer.current - timerConfig.triggerAhead;
|
|
this.endCallback = setTimeout(() => this.update(), endTime);
|
|
return true;
|
|
}
|
|
|
|
pause() {
|
|
if (!runtimeState.pause()) {
|
|
return false;
|
|
}
|
|
|
|
// cancel end callback
|
|
clearTimeout(this.endCallback);
|
|
return true;
|
|
}
|
|
|
|
stop() {
|
|
if (!runtimeState.stop()) {
|
|
return false;
|
|
}
|
|
|
|
// cancel end callback
|
|
clearTimeout(this.endCallback);
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Adds time to running timer by given amount
|
|
*/
|
|
addTime(amount: number): boolean {
|
|
if (!runtimeState.addTime(amount)) {
|
|
return false;
|
|
}
|
|
|
|
// renew end callback
|
|
clearTimeout(this.endCallback);
|
|
const state = runtimeState.getState();
|
|
// eslint-disable-next-line no-unused-labels -- dev code path
|
|
DEV: {
|
|
if (state.timer.expectedFinish === null) {
|
|
throw new Error('TimerService.addTime: expectedFinish is negative');
|
|
}
|
|
}
|
|
this.endCallback = setTimeout(() => this.update(), state.timer.expectedFinish);
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Update the app at regular intervals
|
|
*/
|
|
update() {
|
|
const updateResult = runtimeState.update();
|
|
// pass the result to the parent
|
|
this.onUpdateCallback?.(updateResult);
|
|
}
|
|
|
|
shutdown() {
|
|
clearInterval(this._interval);
|
|
clearTimeout(this.endCallback);
|
|
}
|
|
}
|