@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
129 lines (107 loc) • 3.27 kB
JavaScript
import { assert } from "../assert.js";
/**
* A watchdog timer that executes a callback function if `kick()` is not called within a specified timeout period.
*/
export class WatchDog {
/**
* @private
* @type {number}
*/
timeoutId = -1;
/**
* Timeout duration in milliseconds
* @type {number}
*/
timeout = 0;
/**
*
* @type {number}
* @private
*/
__timeLastKicked = 0;
/**
*
* @param {function} action Callback function to execute on timeout
* @param {*} [actionContext] `this` context for the callback function.
* @constructor
*/
constructor(action, actionContext) {
assert.isFunction(action,'action');
/**
* Callback function to be executed when the watchdog timer expires.
* @type {function}
*/
this.action = action;
/**
* The context (`this` value) for the {@link action} callback.
* @type {*}
*/
this.actionContext = actionContext;
}
/**
* @private
* Executes the callback function and clears the timer. Called when the watchdog timer expires.
*/
bark() {
console.warn('WatchDog.bark');
this.action.call(this.actionContext);
this.timeoutId = -1;
}
/**
* Starts the watchdog timer.
* If the timer is already running, this does nothing.
*/
start() {
//console.warn(`WatchDog.start`);
if (this.isActive()) {
//do nothing
} else {
this.timeoutId = setTimeout(this.bark.bind(this), this.timeout);
this.__timeLastKicked = Date.now();
}
}
/**
* Stops the watchdog timer.
* If the timer is not running, this does nothing.
*/
stop() {
//console.warn(`WatchDog.stop`);
if (this.isActive()) {
clearTimeout(this.timeoutId);
this.timeoutId = -1;
} else {
//do nothing, no active timeout
}
}
/**
* Checks if the watchdog timer is currently active.
* @returns {boolean} `true` if the timer is running, `false` otherwise.
*/
isActive() {
return this.timeoutId !== -1;
}
/**
* Resets the watchdog timer. Throws an error if the timer is not active.
* @throws {Error} If the watchdog is not active.
*/
kick() {
// const timeLastKicked = this.__timeLastKicked;
this.__timeLastKicked = Date.now();
// const delta = timeNow - timeLastKicked;
//TODO: remember callstack
// console.warn(`WatchDog.kick. ${delta}ms since last`);
if (this.isActive()) {
clearTimeout(this.timeoutId);
this.timeoutId = setTimeout(this.bark.bind(this), this.timeout);
} else {
throw new Error(`WatchDog is not active`);
}
}
/**
* Sets the timeout duration. Does not start or restart the timer.
* @param {number} delay Timeout duration in milliseconds.
*/
setTimeout(delay) {
this.timeout = delay;
}
}