diff --git a/MessageManager.class.nut b/MessageManager.class.nut index e26f8b9..a482b99 100644 --- a/MessageManager.class.nut +++ b/MessageManager.class.nut @@ -109,9 +109,21 @@ class MessageManager { // Global handler to be called when a message is acknowledged _onAck = null; + // Global handler to be called prior to the onAck handler(s) being called + _beforeOnAck = null; + // Global handler to be called when a message is replied _onReply = null; + // Global handler to be called prior to the onReply handler(s) being called + _beforeOnReply = null; + + // Global handler to be called when any data message is received + _beforeOnData = null; + + // Global handler to be called when before the reply is sent + _beforeReply = null; + // User defined callback to generate next message id _nextIdGenerator = null; @@ -442,6 +454,19 @@ class MessageManager { _onAck = handler; } + // Sets the handler to be called before caling the onAck handler(s) + // + // Parameters: + // handler The handler to be called. It has signature: + // handler(message) + // Paremeters: + // message The message that was acked + // + // Returns: Nothing + function beforeOnAck(handler) { + _beforeOnAck = handler; + } + // Sets the handler to be called when the message is replied // // Parameters: @@ -455,6 +480,44 @@ class MessageManager { _onReply = handler; } + // Sets the handler to be called before calling the onReply handler(s) + // + // Parameters: + // handler The handler to be called. It has signature: + // handler(message, payload), where + // message The message that received a reply + // payload Full response payload + // + // Returns: Nothing + function beforeOnReply(handler) { + _beforeOnReply = handler; + } + + // Sets the handler to be called before calling "on" handlers + // + // Parameters: + // handler The handler to be called. It has signature: + // handler(name, payload), where + // name The message name + // payload The full data payload + // + // Returns: Nothing + function beforeOnData(handler) { + _beforeOnData = handler; + } + + // Sets the handler to be called before sending a reply + // + // Parameters: + // handler The handler to be called. It has signature: + // handler(payload), where + // payload The reply playload + // + // Returns: Nothing + function beforeReply(handler) { + _beforeReply = handler; + } + // Returns the overall number of pending messages // (either waiting for acknowledgement or hanging in the retry queue) // @@ -742,17 +805,23 @@ class MessageManager { local handlerFound = false; local error = 0; + _isFunc(_beforeOnData) && _beforeOnData(name, payload); + if (name in _on) { local handler = _on[name]; if (_isFunc(handler)) { handlerFound = true; handler(payload, function/*reply*/(data = null) { replied = true; - error = _partner.send(MM_MESSAGE_TYPE_REPLY, { - "id" : payload["id"], - "data" : data - }); - }); + + local replyPayload = { + "id" : payload["id"], + "data" : data + } + + _isFunc(_beforeReply) && _beforeReply(replyPayload); + error = _partner.send(MM_MESSAGE_TYPE_REPLY, replyPayload); + }.bindenv(this)); } } @@ -787,11 +856,14 @@ class MessageManager { if (id in _sentQueue) { local msg = _sentQueue[id]; + _isFunc(_beforeOnAck) && msg._beforeOnAck(msg); _isFunc(msg._onAck) && msg._onAck(msg); _isFunc(_onAck) && _onAck(msg); - // Delete the acked message from the queue - delete _sentQueue[id]; + // Delete the acked message from the queue if there is no _onReply handler set (either global or message-specific) + if (!_isFunc(msg._onReply) && !_isFunc(_onReply)) { + delete _sentQueue[id] + } } } @@ -857,6 +929,7 @@ class MessageManager { _isFunc(_onAck) && _onAck(msg); // Then call the global handlers + _isFunc(_beforeOnReply) && _beforeOnReply(msg, payload); _isFunc(msg._onReply) && msg._onReply(msg, payload["data"]); _isFunc(_onReply) && _onReply(msg, payload["data"]);