UNPKG

timer-shim

Version:

Test-friendly timer function replacements.

306 lines (267 loc) 7.97 kB
// Generated by CoffeeScript 1.6.3 var __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; module.exports = (function() { var ALIASES, CLEAN_THRESHOLD, INITIAL_THRESHOLD, IntervalTask, LinkedList, Task, TimeoutTask, Timer, alias, aliases, bindAll, key, taskFactoryFor, timer, validate, _ref, _ref1; INITIAL_THRESHOLD = 10; CLEAN_THRESHOLD = 1.10; LinkedList = require('linkedlist'); LinkedList.prototype.remove = function(ll, item) { ll.resetCursor(); while (ll.next() && item !== ll.current) {} if (ll.current !== item) { return false; } ll.removeCurrent(); return true; }; alias = function(Klass, action, names) { var name, _i, _len, _results; _results = []; for (_i = 0, _len = names.length; _i < _len; _i++) { name = names[_i]; _results.push(Klass.prototype[name] = function() { return Klass.prototype[action].apply(this, arguments); }); } return _results; }; bindAll = function(obj, klass) { var key, _results; _results = []; for (key in klass.prototype) { if (typeof klass.prototype[key] === 'function' && !obj.hasOwnProperty(key)) { _results.push((function(key) { return obj[key] = function() { return klass.prototype[key].apply(obj, arguments); }; })(key)); } else { _results.push(void 0); } } return _results; }; validate = function(timeout, action) { var _ref; if (typeof action === 'number') { _ref = [timeout, action], action = _ref[0], timeout = _ref[1]; } if (!isFinite(timeout)) { throw new Error('timeout is not a valid number'); } if (typeof action !== 'function') { throw new Error('action is not a function'); } return [timeout, action]; }; Task = (function() { function Task(time, action) { this.id = null; this.time = time; this.action = action; this.paused = true; this.canceled = false; this.windedTime = 0; } Task.prototype.cancel = function() { this.canceled = true; return this._pause(); }; Task.prototype.pause = function() { if (this.canceled || this.paused) { return; } this._pause(); this.id = null; this.paused = true; return this.windedTime = 0; }; Task.prototype.resume = function() { if (this.canceled || !this.paused) { return; } this.id = this._resume(this.windedTime); this.paused = false; return this.windedTime = 0; }; Task.prototype.wind = function(time) { if (this.canceled || !this.paused) { return; } this.windedTime += time; return this.windedTime = this._wind(this.windedTime); }; Task.prototype.unref = function() { if (!(this.id && typeof this.id.unref === 'function')) { return; } return this.id.unref(); }; Task.prototype.ref = function() { if (!(this.id && typeof this.id.ref === 'function')) { return; } return this.id.ref(); }; Task.prototype._pause = function() { throw new Error('must be overridden'); }; Task.prototype._resume = function() { throw new Error('must be overridden'); }; return Task; })(); IntervalTask = (function(_super) { __extends(IntervalTask, _super); function IntervalTask() { _ref = IntervalTask.__super__.constructor.apply(this, arguments); return _ref; } IntervalTask.prototype._pause = function() { return clearInterval(this.id); }; IntervalTask.prototype._resume = function(time) { var _this = this; if (!time) { return setInterval(this.action, this.time); } else { return setTimeout(function() { _this.action(); return _this.id = setInterval(_this.action, _this.time); }, this.time - time); } }; IntervalTask.prototype._wind = function(time) { while (time >= this.time) { time -= this.time; this.action(); } return time; }; return IntervalTask; })(Task); TimeoutTask = (function(_super) { __extends(TimeoutTask, _super); function TimeoutTask() { _ref1 = TimeoutTask.__super__.constructor.apply(this, arguments); return _ref1; } TimeoutTask.prototype._pause = function() { return clearTimeout(this.id); }; TimeoutTask.prototype._resume = function(time) { return setTimeout(this.action, this.time - time); }; TimeoutTask.prototype._wind = function(time) { if (time < this.time) { return time; } this.action(); this.canceled = true; return 0; }; return TimeoutTask; })(Task); taskFactoryFor = function(Klass) { return function(timeout, action) { var task, _ref2; _ref2 = validate(timeout, action), timeout = _ref2[0], action = _ref2[1]; task = new Klass(timeout, action); this.tasks.push(task); if (!this.paused) { task.resume(); } this._checkAndClean(); return task; }; }; Timer = (function() { Timer.prototype.paused = false; Timer.prototype.tasks = null; Timer.prototype._lastCleanedLength = 0; function Timer() { this.tasks = new LinkedList; this._lastCleanedLength = INITIAL_THRESHOLD; bindAll(this, Timer); } Timer.prototype.timeout = taskFactoryFor(TimeoutTask); Timer.prototype.interval = taskFactoryFor(IntervalTask); Timer.prototype.clear = function(task) { return task.cancel(); }; Timer.prototype.clearAll = function() { this.tasks.resetCursor(); while (this.tasks.next()) { this.clear(this.tasks.current); } return this.tasks = new LinkedList; }; Timer.prototype.pause = function() { this.tasks.resetCursor(); while (this.tasks.next()) { this.tasks.current.pause(); } return this.paused = true; }; Timer.prototype.resume = function() { this.tasks.resetCursor(); while (this.tasks.next()) { this.tasks.current.resume(); } return this.paused = false; }; Timer.prototype.wind = function(time) { var _results; this.tasks.resetCursor(); _results = []; while (this.tasks.next()) { _results.push(this.tasks.current.wind(time)); } return _results; }; Timer.prototype.unref = function() { var _results; this.tasks.resetCursor(); _results = []; while (this.tasks.next()) { _results.push(this.tasks.current.unref()); } return _results; }; Timer.prototype.ref = function() { var _results; this.tasks.resetCursor(); _results = []; while (this.tasks.next()) { _results.push(this.tasks.current.ref()); } return _results; }; Timer.prototype._checkAndClean = function() { if (!(this.tasks.length > this._lastCleanedLength * CLEAN_THRESHOLD)) { return; } this.tasks.resetCursor(); while (this.tasks.next()) { if (this.tasks.current.canceled) { this.tasks.removeCurrent(); } } return this._lastCleanedLength = this.tasks.length; }; return Timer; })(); ALIASES = { 'timeout': 't,to,setTimeout', 'clear': 'c,ct,cto,clearTimeout,clearInterval', 'interval': 'i,in,iv,inv,setInterval' }; for (key in ALIASES) { aliases = ALIASES[key]; alias(Timer, key, aliases.split(',')); } timer = new Timer(); Timer.prototype.Timer = Timer; return timer; })();