VR-Forces 5.2 Lua Function Documentation

msgUtil

(For high level concepts about how to use Lua to write scripted tasks, please see VR-Forces User's Guide.)

Message Util is a collection of functions that maintain queues of object or text messages that the entity receives.

Background

Scripts that receive messages as they control complex behavior can generally operate one of two ways: 1) in a periodic tick function, all sensing, computation, and action is performed; this includes processing messages received since the last tick. 2) all sensing, computation and action takes place only in response to asynchronous events such as message receipts. The first option is more common, with behaviors using FSMs or the behavior engine to express behavior. In the first option, messages that arrive between ticks need to be queued and then processed during the tick. This module provides support functions for queing and processing.
The module processes text messages and object messages, which use structures to hold message data. The functions in the module use, or are related to, vrf:registerForObjectMessage, receiveObjectMessage, receiveTextMessage, etc.
To use this utility, the script must include
require "msgUtil" 

Note also that the package includes a definition of the receiveObjectMessage and receiveTextMessage functions, so these functions MUST NOT BE DEFINED IN THE SCRIPT.

Use Case 1 -- Single Message Type

Suppose the script wants to process "refuel-request" messages. It can set itself up to receive and queue them this way:
 require "msgUtil" 
msgQueue = newMessageQueue("refuel-request")
This call sets up a queue and also registers the script to receive refuel-request object messages. Later, in the script tick function, the queue can be checked and the message processed:
 newMsg = msgQueue.getFirstMessage() -- pops message off queue
while newMsg ~= nil do
process(newMsg)
newMsg = msgQueue.getFirstMessage()
end

Use Case 2 -- Queue for Multiple Message Types

Here a single queue is used for all message types. In this case the type of message in the queue is not pre-defined, but the script has to register for the desired messages (except text messages).
 require "msgUtil" 
msgQueue = newMessageQueue()
...
function init()
vrf:registerForObjectMessage("refuel-request")
vrf:registerForObjectMessage("refuel-position-request")
vrf:registerForObjectMessage("request-air-refuel-initial-point")
...
end
The queue is checked in the tick function as in Use Case 1, but the process function now tests the message type:
 newMsg, sender, msgType = msgQueue.getFirstMessage() -- pops message off queue
while newMsg ~= nil do
process(newMsg, sender, msgType)
newMsg, sender, msgType = msgQueue.getFirstMessage()
end
...
function process(messageData, sender, messageType)
if messageType == "refuel-request" then ...
elseif messageType == "refuel-position-request" then ...
elseif messageType == "text" then ...
...
end

Use Case 3 -- Filtered Generic Messages

Generic-table messages all have the same object message type ("generic-table"), but this utility allows a script to set a filter on a queue so that only certain generic-table messages get put on the queue. For example, suppose the messages have a "type" field which can have a value of SITREP, SPOTREP, FRAGO, OPORD, etc. A script can get just SITREPs like this:
 require "msgUtil" 
rptQueue = newMessageQueue("generic-table")
...
function init()
rptQueue.addFilter({type = "SITREP"})
...
end

Use Case 4 -- Callback Function

This package defines the receiveObjectFunction. If the script would like a callback for some object message types, in addition to using queues for some message types, a callback can be registered. For example, suppose the script defines a queue as in Use Case 2 AND a queue as in Use Case 3. The script needs to print a message when ANY message (that the script has registered for) is received. This can be accomplished by creating another queue that receives all messages (messages can be put on multiple queues):
 allMsgsQueue = newMessageQueue() 
function printRcvMsg(message, sender, type)
printInfo("Received message of type "..type)
end
...
function init()
allMsgsQueue.addCallback(printRcvMsg)
...
end

Function List

messageQueue.addCallback (callback, rmMsgAfterCall) Set the callback function.
messageQueue.addFilter (filter) Add a filter to the queue to indicate which subset of messages should be queued.
messageQueue.addType (type) Add an object message type to receive in this queue.
messageQueue.clearMessages () Clears all messages from the queue
messageQueue.copyAllMessages () Returns a list of all messages (but not the whole queue structure).
messageQueue.deleteMessage (messageData) Delete the message after the given one.
messageQueue.getFirstMessage () Get the first (oldest) message on the queue.
messageQueue.peekAtFirstMessage () Same as getFirstMessage, but does not remove the message from the queue.
messageQueue.peekAtNextMessage (messageData) Get the message after the given one.
messageQueue.stateCopy () Provides a state that can be saved with a scenario and later used to restore this queue and its information.
newMessageQueue (msgType) Create a new message queue for the given vrf object message type.
removeMessageQueue (queue) Deletes the queue, thus avoiding the copying of incoming messages to this queue.
restoreMessageQueue (savedQueue) Restore a message queue from saved state.


Functions

messageQueue.addCallback (callback, rmMsgAfterCall)
Set the callback function. This function is called when a message is received that matches the filters in the queue.

Parameters:

  • callback: A function that takes as arguments message data, the message sender (simObject), and the vrf object message type (string).
  • rmMsgAfterCall: (optional; Boolean) If true, message is removed from the queue after the callback function returns. Default true.

Usage:

     myQueue = newMessageQueue("generic-table") 
    function myCallback(message, sender, type) ... end
    ...
    myQueue.addCallback(myCallback)
messageQueue.addFilter (filter)
Add a filter to the queue to indicate which subset of messages should be queued. This filter will be "OR'ed" with other filters, such that if a message matches this OR any other filter, it will be accepted into the queue. If the input message is not a table, it will not pass any filter. If the input message is missing a field that is in the filter, it will not pass.

Parameters:

  • filter: A table with key words and value words.
messageQueue.addType (type)
Add an object message type to receive in this queue. The function also calls vrf:registerForObjectType to start receiving messages of this type. Note that if the queue type was originally nil -- meaning all message types are received -- this function will restrict the message types received to the given type.

Parameters:

  • type: String An object message type. The value "text" causes the queue to receive text messages.
messageQueue.clearMessages ()
Clears all messages from the queue
messageQueue.copyAllMessages ()
Returns a list of all messages (but not the whole queue structure).
messageQueue.deleteMessage (messageData)
Delete the message after the given one.

Parameters:

  • messageData: (table) The message data of a message, for example the messageData returned by a peekAtFirstMessage call. This must be the same table that is stored in the queue; i.e. the function will delete the given message if it finds a table in the queue with the same address.
messageQueue.getFirstMessage ()
Get the first (oldest) message on the queue. Returns nil if the queue is empty.

Return values:

  1. Message data
  2. Sender (simObject)
  3. VRF object message type (string)
  4. Time of receipt (number), simulation time.
messageQueue.peekAtFirstMessage ()
Same as getFirstMessage, but does not remove the message from the queue.
messageQueue.peekAtNextMessage (messageData)
Get the message after the given one.

Parameters:

  • messageData: (table) The message data returned by a peekAtFirstMessage call. This must be the same table; i.e. the function will find the given message by finding one in the queue with the same address.

Return value:

    Same as getFirstMessage.
messageQueue.stateCopy ()
Provides a state that can be saved with a scenario and later used to restore this queue and its information.

Usage:

     myQueue = newMessageQueue("refuel-request") 
    function myCallbackFn(messageData, sender, msgType) ...
    myQueue.addCallback(myCallbackFn)
    ...
    function saveState()
    -- Save a copy of all message queue information except
    -- the callback function:
    checkpointState.myQueue = myQueue.stateCopy()
    ...
    end
newMessageQueue (msgType)
Create a new message queue for the given vrf object message type. The registerForObjectMessage function will be called for this type. If msgType is nil, the queue will get messages of all types, but the user of the queue must call registerForObjectMessage for each type of message of interest.

Parameters:

  • msgType: string The name of the vrf object message type to queue messages for; use nil to queue all received object messages. The value "text" causes the queue to receive text messages.

Return value:

    A message queue.
removeMessageQueue (queue)
Deletes the queue, thus avoiding the copying of incoming messages to this queue. The queue cannot be used again and must be recreated if more message need to be processed.

Parameters:

  • queue:
restoreMessageQueue (savedQueue)
Restore a message queue from saved state. Note that callback functions are not saved in the state and must be restored in loadState. However, this function will re-register for all message types this queue receives.

Parameters:

  • savedQueue: A table of queue information generated by a call to queue.stateCopy() (and saved in checkpointState during a scenario save).

Usage:

    Assume the state of the queue has been saved as shown in stateCopy() above. 
     function loadState() 
    myQueue = restoreQueue(checkpointState.myQueue)
    myQueue.addCallback(myCallbackFn)
    ...
    end

Copyright© 2025 MAK Technologies, Inc. All rights reserved.