UNPKG

libtimer

Version:
414 lines (380 loc) 14.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Timer = exports.TimerHeap = exports.TimerTask = exports.getTime = undefined; var _getPrototypeOf = require("babel-runtime/core-js/object/get-prototype-of"); var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf); var _possibleConstructorReturn2 = require("babel-runtime/helpers/possibleConstructorReturn"); var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2); var _inherits2 = require("babel-runtime/helpers/inherits"); var _inherits3 = _interopRequireDefault(_inherits2); var _classCallCheck2 = require("babel-runtime/helpers/classCallCheck"); var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); var _createClass2 = require("babel-runtime/helpers/createClass"); var _createClass3 = _interopRequireDefault(_createClass2); var _obs = require("libobs/lib/obs"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var getTime = exports.getTime = function getTime() { return Date.now(); }; /** @babel */ var TimerTask = exports.TimerTask = function () { function TimerTask() { var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref$run = _ref.run, run = _ref$run === undefined ? null : _ref$run; (0, _classCallCheck3.default)(this, TimerTask); this.when = 0; this.period = 0; this.fixedRate = false; this.cancelled = false; this.scheduledTime = 0; if (run) { this.run = run; } } (0, _createClass3.default)(TimerTask, [{ key: "cancel", value: function cancel() { var willRun = !this.cancelled && this.when > 0; this.cancelled = true; return willRun; } }, { key: "getWhen", value: function getWhen() { return this.when; } }, { key: "isScheduled", value: function isScheduled() { return this.when > 0 || this.scheduledTime > 0; } }, { key: "run", value: function run() {} }, { key: "scheduledExecutionTime", value: function scheduledExecutionTime() { return this.scheduledTime; } }, { key: "setScheduledTime", value: function setScheduledTime(time) { this.scheduledTime = time; } }]); return TimerTask; }(); var DEFAULT_HEAP_SIZE = 256; var TimerHeap = exports.TimerHeap = function (_Observable) { (0, _inherits3.default)(TimerHeap, _Observable); function TimerHeap() { var heapSize = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : DEFAULT_HEAP_SIZE; (0, _classCallCheck3.default)(this, TimerHeap); var _this = (0, _possibleConstructorReturn3.default)(this, (TimerHeap.__proto__ || (0, _getPrototypeOf2.default)(TimerHeap)).call(this)); _this.deletedCancelledNumber = _this.size = 0; _this.heapSize = heapSize; _this.timers = new Array(_this.heapSize); return _this; } (0, _createClass3.default)(TimerHeap, [{ key: "adjustMinimum", value: function adjustMinimum() { this.downHeap(0); } }, { key: "deleteIfCancelled", value: function deleteIfCancelled() { for (var i = 0; i < this.size; i++) { var timer = this.timers[i]; if (timer.cancelled) { this.deletedCancelledNumber++; this.remove(i); i--; } } } }, { key: "downHeap", value: function downHeap() { var pos = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; var current = pos; var child = 2 * current + 1; while (child < this.size && this.size > 0) { if (child + 1 < this.size && this.timers[child + 1].when < this.timers[child].when) { child++; } if (this.timers[current].when < this.timers[child].when) { break; } var tmp = this.timers[current]; this.timers[current] = this.timers[child]; this.timers[child] = tmp; current = child; child = 2 * current + 1; } } }, { key: "getTask", value: function getTask(task) { for (var i = 0; i < this.timers.length; i++) { var timer = this.timers[i]; if (timer === task) { return i; } } return -1; } }, { key: "insert", value: function insert(task) { this.timers[this.size++] = task; this.upHeap(); this.setChanged(); this.notifyObservers(this.size); } }, { key: "isEmpty", value: function isEmpty() { return this.size === 0; } }, { key: "minimum", value: function minimum() { return this.timers[0]; } }, { key: "remove", value: function remove(pos) { if (pos >= 0 && pos < this.size) { this.timers[pos] = this.timers[--this.size]; this.timers[this.size] = null; this.downHeap(pos); this.setChanged(); this.notifyObservers(pos); } } }, { key: "reset", value: function reset() { this.timers = new Array(this.heapSize); this.size = 0; } }, { key: "upHeap", value: function upHeap() { var current = this.size - 1; var parent = (current - 1) / 2; if (current >= 0 && parent >= 0) { while (this.timers[current].when < this.timers[parent].when) { var tmp = this.timers[current]; this.timers[current] = this.timers[parent]; this.timers[parent] = tmp; current = parent; parent = (current - 1) / 2; } } } }]); return TimerHeap; }(_obs.Observable); var Timer = exports.Timer = function (_Observer) { (0, _inherits3.default)(Timer, _Observer); function Timer() { var heapSize = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : DEFAULT_HEAP_SIZE; (0, _classCallCheck3.default)(this, Timer); var _this2 = (0, _possibleConstructorReturn3.default)(this, (Timer.__proto__ || (0, _getPrototypeOf2.default)(Timer)).call(this)); _this2.cancelled = _this2.finished = false; _this2.tasks = new TimerHeap(heapSize); _this2.tasks.addObserver(_this2); return _this2; } (0, _createClass3.default)(Timer, [{ key: "cancel", value: function cancel() { this.cancelled = true; this.tasks.reset(); } }, { key: "insertTask", value: function insertTask(newTask) { this.tasks.insert(newTask); } }, { key: "purge", value: function purge() { if (this.tasks.isEmpty()) { return 0; } this.tasks.deletedCancelledNumber = 0; this.tasks.deleteIfCancelled(); return this.tasks.deletedCancelledNumber; } }, { key: "run", value: function run() { if (this.cancelled) { return; } if (this.tasks.isEmpty()) { if (this.finished) { return; } } else { var currentTime = getTime(); var task = this.tasks.minimum(); if (task.cancelled) { this.tasks.remove(0); return; } var timeToSleep = task.when - currentTime; if (timeToSleep > 0) { this.wait(timeToSleep); } else { var pos = 0; if (this.tasks.minimum().when !== task.when) { pos = this.tasks.getTask(task); } if (task.cancelled) { this.tasks.remove(this.tasks.getTask(task)); return; } task.setScheduledTime(task.when); this.tasks.remove(pos); if (task.period >= 0) { if (task.fixedRate) { task.when = task.when + task.period; } else { task.when = getTime() + task.period; } this.insertTask(task); } else { task.when = 0; } var taskCompletedNormally = false; try { task.run(); taskCompletedNormally = true; } catch (e) { console.error(e); } finally { if (!taskCompletedNormally) { this.cancelled = true; } } } } } }, { key: "schedule", value: function schedule() { var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, task = _ref2.task, _ref2$when = _ref2.when, when = _ref2$when === undefined ? null : _ref2$when, _ref2$period = _ref2.period, period = _ref2$period === undefined ? -1 : _ref2$period, _ref2$delay = _ref2.delay, delay = _ref2$delay === undefined ? -1 : _ref2$delay; if (!task) { throw new ReferenceError("NullPointerException task is null"); } if (when && period) { if (when.getTime() < 0 || period <= 0) { throw new RangeError("IllegalArgumentException when < 0: " + when + " || period < 0 " + period); } var _delay = when.getTime() - getTime(); this.scheduleImpl({ task: task, delay: _delay < 0 ? 0 : _delay, period: period, fixed: false }); } else if (when) { if (when.getTime() < 0) { throw new RangeError("IllegalArgumentException when < 0: " + when.getTime()); } var _delay2 = when.getTime() - getTime(); this.scheduleImpl({ task: task, delay: _delay2 < 0 ? 0 : _delay2, period: -1, fixed: false }); } else if (delay && period) { if (delay < 0 || period <= 0) { throw new RangeError("IllegalArgumentException delay < 0: " + delay + " || period < 0 " + period); } this.scheduleImpl({ task: task, delay: delay, period: period, fixed: false }); } else if (delay) { if (delay < 0) { throw new RangeError("IllegalArgumentException delay < 0: " + delay); } this.scheduleImpl({ task: task, delay: delay, period: -1, fixed: false }); } } }, { key: "scheduleAtFixedRate", value: function scheduleAtFixedRate() { var _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, task = _ref3.task, _ref3$when = _ref3.when, when = _ref3$when === undefined ? null : _ref3$when, _ref3$period = _ref3.period, period = _ref3$period === undefined ? -1 : _ref3$period, _ref3$delay = _ref3.delay, delay = _ref3$delay === undefined ? -1 : _ref3$delay; if (!task) { throw new ReferenceError("NullPointerException task is null"); } if (when && period) { if (when.getTime() < 0 || period <= 0) { throw new RangeError("IllegalArgumentException when < 0: " + when + " || period < 0 " + period); } var _delay3 = when.getTime() - getTime(); this.scheduleImpl({ task: task, delay: _delay3 < 0 ? 0 : _delay3, period: period, fixed: true }); } else if (delay && period) { if (delay < 0 || period <= 0) { throw new RangeError("IllegalArgumentException delay < 0: " + delay + " || period < 0 " + period); } this.scheduleImpl({ task: task, delay: delay, period: period, fixed: true }); } } }, { key: "scheduleImpl", value: function scheduleImpl() { var _ref4 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, task = _ref4.task, _ref4$period = _ref4.period, period = _ref4$period === undefined ? -1 : _ref4$period, _ref4$delay = _ref4.delay, delay = _ref4$delay === undefined ? -1 : _ref4$delay, _ref4$fixed = _ref4.fixed, fixed = _ref4$fixed === undefined ? false : _ref4$fixed; if (this.cancelled) { throw new Error("IllegalStateException Timer was canceled"); } var when = delay + getTime(); if (when < 0) { throw new RangeError("IllegalArgumentException Illegal delay to start the TimerTask: " + when); } if (task.isScheduled()) { throw new Error("IllegalStateException TimerTask is scheduled already"); } if (task.cancelled) { throw new Error("IllegalStateException TimerTask is canceled"); } task.when = when; task.period = period; task.fixedRate = fixed; this.insertTask(task); } }, { key: "update", value: function update(timerHeap, pos) { this.run(); } }, { key: "wait", value: function wait(time) { var _this3 = this; var tid = setTimeout(function () { clearTimeout(tid); tid = -1; _this3.run(); }, time); } }]); return Timer; }(_obs.Observer);