hjs-message
Version:
Messaging API
428 lines (398 loc) • 14.3 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.MessageQueue = exports.IdleHandler = undefined;
var _getIterator2 = require("babel-runtime/core-js/get-iterator");
var _getIterator3 = _interopRequireDefault(_getIterator2);
var _map = require("babel-runtime/core-js/map");
var _map2 = _interopRequireDefault(_map);
var _classCallCheck2 = require("babel-runtime/helpers/classCallCheck");
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _createClass2 = require("babel-runtime/helpers/createClass");
var _createClass3 = _interopRequireDefault(_createClass2);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/** @babel */
var IdleHandler = exports.IdleHandler = function () {
function IdleHandler() {
var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
queue = _ref.queue;
(0, _classCallCheck3.default)(this, IdleHandler);
this.id = -1;
this.when = 0;
this.queue = queue;
}
(0, _createClass3.default)(IdleHandler, [{
key: "idle",
value: function idle() {
var _this = this;
var when = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
var delay = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
this.queue.addIdleHandler(this, this.when = when);
this.id = setTimeout(function () {
_this.unIdle();
}, delay);
}
}, {
key: "queueIdle",
value: function queueIdle() {
return this.id !== -1;
}
}, {
key: "unIdle",
value: function unIdle() {
var id = this.id;
if (id) {
this.id = -1;
this.queue.removeIdleHandler(this.when);
if (!this.queue.isInLoop()) {
this.queue.dispatchMessage();
}
clearTimeout(id);
}
}
}]);
return IdleHandler;
}();
var MessageQueue = exports.MessageQueue = function () {
function MessageQueue() {
var quitAllowed = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
(0, _classCallCheck3.default)(this, MessageQueue);
this.mLooper = null;
this.mMessages = null;
this.mQuitting = false;
this.mIdleHandlers = new _map2.default();
this.mQuitAllowed = quitAllowed;
this.mLastMessage = null;
}
(0, _createClass3.default)(MessageQueue, [{
key: "addIdleHandler",
value: function addIdleHandler() {
var idleHandler = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
var when = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
if (!idleHandler) {
throw new ReferenceError("Can't add a null IdleHandler");
}
if (!this.mIdleHandlers.has(when)) {
this.mIdleHandlers.set(when, idleHandler);
}
}
}, {
key: "dispatchMessage",
value: function dispatchMessage() {
var msg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
var handled = false;
if (!msg) {
msg = this.nextMessage();
}
if (msg) {
var target = msg.target;
if (!target) {
return handled;
}
this.mLastMessage = msg;
handled = target.dispatchMessage(msg);
if (!handled) {
target.unHandleMessage(msg);
}
msg.recycle();
}
return handled;
}
}, {
key: "dispose",
value: function dispose() {
this.mIdleHandlers = null;
this.mLooper = null;
}
}, {
key: "enqueueMessage",
value: function enqueueMessage(msg) {
var when = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
if (msg.when !== 0) {
throw new ReferenceError(msg + " This message is already in use.");
}
if (!msg.target && !this.mQuitAllowed) {
throw new Error("Queue not allowed to quit");
}
if (this.mQuiting) {
var e = new ReferenceError(msg.getTarget() + " sending message to a Handler on a dead queue");
console.error(e);
msg.recycle();
return false;
} else if (!msg.target) {
this.mQuiting = true;
}
var handled = false;
msg.markInUse();
msg.when = when;
if (!msg.isAsynchronous()) {
handled = this.dispatchMessage(msg);
} else {
var p = this.mMessages;
if (!p || when === 0 || when < p.when) {
msg.next = p;
this.mMessages = msg;
if (!this.isInLoop()) {
handled = this.dispatchMessage();
}
} else {
var prev = null;
while (p && p.when <= when) {
prev = p;
p = p.next;
}
msg.next = prev.next;
prev.next = msg;
if (!this.isInLoop()) {
handled = this.dispatchMessage();
}
}
}
return handled;
}
}, {
key: "hasMessages",
value: function hasMessages(h) {
var val = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : NaN;
var object = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
if (!h) {
return false;
}
var p = this.mMessages || this.mLastMessage;
if (!isNaN(val)) {
while (p) {
if (p.target === h && p.what === val && (!object || p.obj === object)) {
return true;
}
p = p.next;
}
return false;
}
while (p) {
if (p.target === h && p.callback === val && (!object || p.obj === object)) {
return true;
}
p = p.next;
}
return false;
}
}, {
key: "hasHidleHandler",
value: function hasHidleHandler() {
var when = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
return this.mIdleHandlers.has(when);
}
}, {
key: "isIdle",
value: function isIdle() {
return !this.mMessages || Date.now() < this.mMessages.when;
}
}, {
key: "isInLoop",
value: function isInLoop() {
return this.mLooper && this.mLooper.isRunning();
}
}, {
key: "nextMessage",
value: function nextMessage() {
if (this.mQuiting) {
return null;
}
var msg = void 0;
var now = Date.now();
if (msg = this.pullNextLocked(now)) {
msg.markInUse();
return msg;
} else {
var idleHandlers = this.mIdleHandlers.values();
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = (0, _getIterator3.default)(idleHandlers), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var idleHandler = _step.value;
if (!idleHandler.queueIdle()) {
idleHandler.unIdle();
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
}
return null;
}
}, {
key: "pullNextLocked",
value: function pullNextLocked() {
var now = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
var p = this.mMessages;
if (p) {
while (p) {
if (now >= p.when) {
this.mMessages = p.next;
return p;
}
var when = p.when;
var delay = when - now;
if (!this.hasHidleHandler(when)) {
var idleHandler = new IdleHandler({ queue: this });
idleHandler.idle(when, delay);
}
p = p.next;
}
}
return p;
}
}, {
key: "quit",
value: function quit(safe) {
if (!this.mQuitAllowed) {
throw new Error("IllegalStateException queue not allowed to quit.");
}
if (this.mQuitting) {
return;
}
this.mQuitting = true;
if (safe) {
this.removeFuturMessages();
} else {
this.removeMessages();
}
this.dispose();
}
}, {
key: "removeCallbacksAndMessages",
value: function removeCallbacksAndMessages(h) {
var object = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
if (!h) {
return;
}
var p = this.mMessages || this.mLastMessage;
var nn = null;
var n = null;
while (p && p.target === h && (!object || p.obj === object)) {
n = p.next;
if (n && n.target === h && (!object || n.obj === object)) {
nn = n.next;
n.recycle();
p.next = nn;
}
p = n;
}
}
}, {
key: "removeIdleHandler",
value: function removeIdleHandler() {
var when = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
var idleHandler = this.mIdleHandlers[when];
if (this.mIdleHandlers.has(when)) {
this.mIdleHandlers.delete(when);
}
}
}, {
key: "removeFuturMessages",
value: function removeFuturMessages() {
var now = Date.now();
var p = this.mMessages || this.mLastMessage;
if (p) {
if (p.when > now) {
this.removeMessages();
} else {
var n = void 0;
for (;;) {
n = p.next;
if (!n) {
return;
}
if (n.when > now) {
break;
}
p = n;
}
p.next = null;
do {
p = n;
n = p.next;
p.recycle();
} while (n);
}
}
}
}, {
key: "removeMessages",
value: function removeMessages(h, val) {
var object = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
var doRemove = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
if (!h) {
return false;
}
var p = this.mMessages || this.mLastMessage;
var nn = null;
var n = null;
if (typeof val === "number") {
var found = false;
while (p && p.target === h && p.what === val && (!object || p.obj === object)) {
if (!doRemove) {
return true;
}
found = true;
n = p.next;
this.mMessages = n;
p.recycle();
p = n;
}
while (p) {
n = p.next;
if (n && n.target === h && (!object || n.obj === object)) {
if (!doRemove) {
return true;
}
found = true;
nn = n.next;
n.recycle();
p.next = nn;
}
p = n;
}
return found;
}
var r = val;
if (!r) {
return false;
}
p = this.mMessages || this.mLastMessage;
while (p && p.target === h && p.callback === r && (!object || p.obj === object)) {
n = p.next;
this.mMessages = n;
p.recycle();
p = n;
}
if (!p) {
return false;
}
while (p) {
n = p.next;
if (n && n.target === h && n.callback === r && (!object || p.obj === object)) {
nn = n.next;
n.recycle();
p.next = nn;
}
p = n;
}
return true;
}
}]);
return MessageQueue;
}();