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

Interface messages use DtSimInterfaceContent objects to store the message data. This example shows how to create a new subclass of DtSimInterfaceContent, MyInterfaceContent, to send a new type of message. The general procedure for creating a new interface message is the following:

  1. Derive a class from DtSimInterfaceContent.
  2. Give it a unique type() string and a clone() function.
  3. Set pertinent parameters.
  4. Create a network representation for the class.
  5. Implement netRepSize(), setFromNet(), and setToNet() to send and retrieve the network representation.
  6. Register the new DtSimInterfaceContent with the DtInterfaceContentFactory. If NewType is an integer constant that corresponds to your type() function, and NewContentClass::creator is a pointer to your creator function, you can change the main.cxx of your GUI and sim engine to register the new content as follows:

    // GUI:
    DtVrfGuiAppEventController::appController()->remoteController()->vrfMessageInterface()->factory()->addCreatorFcn(NewType, NewContentClass::creator);
    // Sim engine:
    app.cgf()->factoryManager()->interfaceContentFactory()->addCreatorFcn(NewType, NewContentClass::creator);

  7. Insert it into a DtSimInterfaceMessage.
Implementing the type() and clone() Member Functions

DtSimInterfaceContent is an abstract class. Any derived class must include a type() member function that returns the type of interface message this content is used for. The type() member function has the following specification:

virtual int type() const;

A class derived from DtSimInterfaceContent needs to provide this type() member function, and should provide mutators and accessors for the information (if any) it will convey. A class derived from DtSimInterfaceContent must also provide a clone() member function. The clone() member function is specified as:

virtual DtSimInterface* clone() const;

Clone functions are typically implemented by calling the class’s copy constructor, for example,

Setting Parameters

If your new message has additional parameters, add class member variables to represent the data. Make sure the clone() function that you define handles the copying of any new member data. Any member variables that you add are copied to or from a network representation for transmission over the network.

Creating the Network Representation

To make the new message capable of being sent over the network, you must provide a network representation for your class. To do this you must serialize all parameters of your message into a character buffer, and then be able to unserialize them back into the class data members.

You may do this in a number of ways, including making a C-style structure using the MAK "Net" types, such as DtNetInt32 (defined in vlNetTypes.h). These types manage byte order swapping when necessary to ensure platform independence.

VR-Forces also supplies a number of functions in the DtBufferSerialize namespace for serializing data. This is the recommended way of creating the network representation for your new messages, and this is the technique used in this example.

Note
If you use a structure, make sure its size is a multiple of 8 bytes to prevent misalignment. You do not need to do this when using DtBufferSerialize.
Implementing netRepSize()

The netRepSize() member function of your class must return the total number of bytes that will be needed to serialize your class in its current state. This may vary depending on the current values of arguments. For example, if you class has a string argument, the size needed to serialize your class will vary depending on the length of the string value.

{
size += getSize(myMessage);
size += getSize(myNumber);
size += getSize(myAck);
return size;
}
Implementing setFromNet()

The setFromNet() function sets class member data from a network buffer. Using the DtBufferSerialize utility member functions, your member function would look something like this:

bool MyInterfaceContent::setFromNet(const char* contentBuffer,
unsigned contentSize)
{
if (!contentBuffer)
{
return false;
}
DtSimInterfaceContent::setFromNet(contentBuffer, contentSize);
contentBuffer = decode(myMessage, contentBuffer);
contentBuffer = decode(myNumber, contentBuffer);
contentBuffer = decode(myAck, contentBuffer);
return true;
}
Implementing setToNet()

The setToNet() function fills in the network representation of the interface content class from the content arguments. This function must call netRep() at the start to allocate the network buffer (myNetRep), if it has not already been created. Using the DtBufferSerialize utility functions, your member function would look like this:

{
char* bufferOffset = myNetRep + DtSimInterfaceContent::netRepSize();
bufferOffset = encode(myMessage, bufferOffset);
bufferOffset = encode(myNumber, bufferOffset);
bufferOffset = encode(myAck, bufferOffset);
return true;
}
Note
It is important that the encode and decode calls be made in the same order in the setFromNet() and setToNet() functions.

Header file:

/*******************************************************************************
** Copyright (c) 2004 MAK Technologies, Inc.
** All rights reserved.
*******************************************************************************/
/*******************************************************************************
** $RCSfile: myInterfaceContent.h,v $ $Revision: 1.7 $ $State: Exp $
*******************************************************************************/
#ifndef MyInterfaceContent_H_
#define MyInterfaceContent_H_
//VR-Forces includes
//VR-Link includes
#include <vlutil/vlString.h>
#include <vlutil/vlNetTypes.h>
//Class MyInterfaceContent
//This is an example of a DtSimInterfaceContent subclass which can be
//used to send a message from one DtVrfMessageInterface to another
//which consists of a string and a number.
//8 bytes total
//To prevent conflicts with existing VR-Forces messages, increment custom
//messages starting at MIN_USER_INTERFACE_MESSAGE_TYPE as defined in
//msgTypes.h.
{
public:
//default constructor
//destructor
virtual ~MyInterfaceContent() override;
//copy constructor
//assignment operator
//Returns the type of interface content (MyInterfaceContentType as defined
//above).
virtual int type() const override;
//Calls the copy constructor to create a clone
virtual DtSimInterfaceContent * clone() const override;
//Set the message string
virtual const DtString & message() const;
//Get the message string
virtual void setMessage(const DtString & message);
//Set the number
virtual unsigned int number() const;
//Get the number
virtual void setNumber(unsigned int number);
//See if this is an acknowledgement
virtual bool ack() const;
//Set if this is an acknowledgement
virtual void setAck(bool);
//Returns the size of the full network representation padded to an 8-byte
//boundary.
virtual int netRepSize() const override;
//Fills in the message from the network buffer
virtual bool setFromNet(const char* contentBuffer, unsigned contentSize) override;
//Fills in the network buffer with the message contents
virtual bool setToNet() override;
//Prints the formatted contents of the message into the given string
virtual void printDataToString(DtString& str) override;
//Static creator function which gets registered with the
//DtInterfaceContentFactory
protected:
DtU32 myNumber;
bool myAck;
};
#endif


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)