VR-Forces Developer's Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
Interface Messages

Table of Contents

An interface message, implemented by the class DtSimInterfaceMessage, is used to communicate with a VR-Forces application, such as the sim engine, GUI, or any application using the Remote Control API.

Interface messages are most commonly sent between the sim and the GUI to exchange information related to object management, object organization, plan messages, session management, and more.

The DtVrfMessageInterface is responsible for sending and receiving interface messages. All VR-Forces have an instance of DtVrfMessageInterface. In the sim engine it is maintained by the DtSimManager and can be accessed through the Simulation Services. In applications using the Remote Control API, including the GUI, it is maintained by the DtVrfRemoteController. The DtVrfMessageInterface is initialized with a pointer to the DtExerciseConnection and a simulation address. The actual DtSimInterfaceMessages are wrapped inside of VR-Link DtDataInteractions. Through this mechanism, VR-Forces effectively extends the DIS and HLA RPR FOM protocols to support additional application-specific messages.

Sending Interface Messages

An interface message is always sent on the network using a Data interaction. To send an interface message from a sim plugin, the easiest way is to use the DtSimulationServices::createAndDeliverMessage method. This method takes the address of the application you wish to send the message to as well as the interface content you wish to send. It then packages that interface content in a DtSimInterfaceMessage and sends it using the DtVrfMessageInterface.

// Address of the VR-Forces application to send the create message
DtSimulationAddress backendAddr;
. . .
DtVector start(0., 0., 0.);
DtVector end(0., 100., 0.);
DtIfCreateVrfObject phaseLineContent;
// Set the address of the back-end we want to have simulate the object.
phaseLineContent.setVrfProcessAddress(backendAddr);
phaseLineContent.setObjectName("Phase Line Alpha");
phaseLineContent.addVertex(start);
phaseLineContent.addVertex(end);
simulationServices()->createAndDeliverMessage(backendAddr, phaseLineContent);
Addressing Messages

The recipient portion of a DtSimInterfaceMessage directs the message to a particular VR-Forces application. Specific objects within a VR-Forces application receive messages by registering callbacks for them. Interface messages are addressed to a VR-Forces application by its DtSimulationAddress. The simulation address is the site ID:application number pair that uniquely identifies an application participating in a simulation exercise.

You can broadcast an interface message to all VR-Forces applications by specifying the address DtSimSendToAll. It represents the simulation address (site ID: -1 application number: -1), indicating all VR-Forces applications on the network.

In a VR-Forces application, you can get your own simulation address through the Simulation Services, for example:

DtSimulationAddress* address = simulationServices()->messageAddress();
DtInfo("My simulation address site Id: %d application Id: %d\n",
address->siteId(), address->applicationId());

In an application using the Remote Control API (such as a GUI), you can get the simulation address of all VR-Forces applications currently participating in an exercise through the DtVrfRemoteController. The DtVrfRemoteController class has a backend() member function that returns a DtList of simulation addresses of all of the VR-Forces applications on the network in the same session. For example, to print out the addresses of all of the VR-Forces applications currently participating in an exercise:

DtListItem* item;
for(item = remoteController->backends().first(); item; item = item->next())
{
DtSimulationAddress* addr = (DtSimulationAddress*)item->data();
DtInfo("VR-Forces application address %s\n", addr->string());
}

Receiving Interface messages

Messages are received by registering callback functions for the interface message content types of interest.

Objects can register a callback to be fired upon receipt of a given kind of interface message through the DtVrfMessageInterface. Message callback functions are specified as:

static void messageCallback(DtSimMessage * msg, void * usrData);

The callback receives a pointer to a DtSimMessage, which is the base class from which DtSimInterfaceMessage is derived. (This is because the radio message callback mechanism uses the same kind of callback - but with a different derived type of DtSimMessage, a DtVrfObjectMessage.) The message received can be cast to a DtSimInterfaceMessage so that its contents can be retrieved. A callback must not delete the messages it receives. The specification for the DtVrfMessageInterface member function for adding a callback is:

virtual void addMessageCallback(int type, DtMessageCallbackFcn fcn, void* usrData);

where:

The following example shows a callback being registered for a DtIfDeleteVrfObject with an instance of a DtSimManager pointed to by mySimManager. It provides its "this" pointer as usrData.

simulationServices()->messageInterface()->addMessageCallback(
DtIfDeleteVrfObjectType, MyClass::deleteObjectCallback, this);
void deleteObjectCallback(DtSimMessage* msg, void * usrData)
{
// We know the type of DtSimMesssage is a DtSimInterfaceMessage.
// We know that the content of the incoming message will be of type
// DtIfDeleteVrfObject.
DtIfDeleteVrfObject * deleteVrfObjectInfo =
DtInfo("Received delete object message for object %s\n",
deleteVrfObjectInfo->markingText().string());
}

Simulation Commands

One of the types of interface messages is the Simulation Command. Simulation commands represent an operation for the simulation to perform, such as creating a new simulation object or printing a console message.

You can send simulation commands from the GUI or use them in plans. Simulation commands can also be sent directly to a simulation engine using the DtIfExecuteSimCommand interface content message. All simulation commands are subclassed from DtSimCommand and are registered with the DtSimCommandFactory.

Each simulation command includes a type identifier and a set of arguments that are used when executing the command. Some of the simulation commands are executed differently depending on whether they are executed by a global plan or by an individual plan. When simulation commands are sent directly to a simulation engine, they are executed as if they are part of a global plan.

Some of the simulation commands that are part of VR-Forces include:

You can add new simulation commands through the VR-Forces API. The Add Simulation Command (addSimCommandGui) and Add Simulation Command (addSimCommandSim) examples shows how to add a new simulation command to the front-end and back-end.

Simulation Command Execution

Each DtSimCommand subclass has a corresponding subclass of DtSimCommandExecutor that carries out the execution of that specific command type. This separates the representation of the command and the logic that executes the command. The command executor is responsible for processing the command and the arguments provided and making the appropriate calls into the VR-Forces API to execute the command. Command executes are registered with the DtSimCommandExecutorFactory and must be registered using the same type identifier that was used for the corresponding DtSimCommand subclass.

Creating New Interface Content

The interfaceContent example demonstrates how to create a new type of interface content and use it within VR-Forces. Interface Content (interfaceContentSim) (./examples/interfaceContent/interfaceContentSim) provides plugin code for the sim engine, while Interface Content (interfaceContentGui) (./examples/interfaceContent/interfaceContentGui) provides plugin code for the GUI.


Document ID: Generated on Thu Oct 23 22:29:17 EDT 2025 from SVN revision 280951
Copyright © 2005-2024 MAK Technologies. All Rights Reserved (www.mak.com)