UNPKG

incheon

Version:

A Node.js based real-time game server

70 lines (61 loc) 2.08 kB
'use strict'; /** * Scheduler class * */ class Scheduler { /** * schedule a function to be called * * @param {Object} options the options * @param {Function} options.tick the function to be called * @param {Number} options.period number of milliseconds between each invocation, not including the function's execution time * @param {Number} options.delay number of milliseconds to add when delaying or hurrying the execution */ constructor(options) { this.options = options; this.nextExecTime = null; this.requestedDelay = 0; } // in same cases, setTimeout is ignored by the browser, // this is known to happen during the first 100ms of a touch event // on android chrome. Double-check the game loop using requestAnimationFrame nextTickChecker() { let currentTime = (new Date()).getTime(); if (currentTime > this.nextExecTime) { this.options.tick(); this.nextExecTime = currentTime + this.options.stepPeriod; } window.requestAnimationFrame(this.nextTickChecker.bind(this)); } nextTick() { let stepStartTime = (new Date()).getTime(); this.options.tick(); this.nextExecTime = stepStartTime + this.options.period + this.requestedDelay; this.requestedDelay = 0; setTimeout(this.nextTick.bind(this), this.nextExecTime - (new Date()).getTime()); } /** * start the schedule * @return {Scheduler} returns this scheduler instance */ start() { setTimeout(this.nextTick.bind(this)); if (typeof window === 'object' && typeof window.requestAnimationFrame === 'function') window.requestAnimationFrame(this.nextTickChecker.bind(this)); return this; } /** * delay next execution */ delayTick() { this.requestedDelay += this.options.delay; } /** * hurry the next execution */ hurryTick() { this.requestedDelay -= this.options.delay; } } module.exports = Scheduler;