UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

129 lines (107 loc) 3.27 kB
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; } }