![]() |
VR-Link API Documentation for HLA 1.3
|
The testObj example is an HLA-specific example that shows how to add a new object class to a FOM.
You must extend the VR-Link top-level API by adding a new kind of state repository, publisher, reflected object, and reflected object list. You also need to create mappings between the new FOM class and the API extensions.
This example adds an object class called Test to the FED file VrlExtend.fed. It has two attributes:
To add this class:
While this may seem like a lot of classes to create, most of them are fairly trivial because they inherit most of their behavior from base classes, and you can use the files in ./examples/testObj as templates from which to create your own classes.
We first create a new subclass of DtStateRepository called TestStateRepository, in testSR.h and testSR.cxx. This class is used to store the state of both local and reflected objects of our Test class. To this class, we add the two new parameters, Number and Vector, we want to add to the FOM.
The class definition is listed below. We provide inspector and mutator functions to access the state data, an override of the virtual printData() function that prints the current state data, and an override of the virtual clone() function that returned a new instance of this class. We represent state data in the same way as in the FOM, but this is not strictly necessary. We could perform a non-trivial conversion in FOM mapping code instead.
Next, we need to create subclasses of DtObjectPublisher, DtReflectedObject, and DtReflectedObjectList for our Test objects.
Technically, these classes are not strictly necessary. We can do just about everything we need to using the base classes, but then we would need to configure each instance of those base classes with the appropriate FOM classes, state repositories, encoders, and decoders every time we create one. By subclassing, we encapsulate the configuration of each base class for our new object type into one place. In addition, we hide the casting from base DtStateRepositories to the derived TestStateRepository, so that application code that uses our derived classes will be able to automatically obtain pointers to TestStateRepositories.
Definitions of functions in these classes are very straightforward, and rely mostly on the base class versions. TestPublisher, ReflectedTest, and ReflectedTestList hard-code their own FOM mapping information, rather than relying on the default behavior, which is to obtain it from the FOM Mapper. This makes things simpler, by saving the step of configuring the FOM Mapper with mappings for the new class. But this choice means that it would be more difficult to change the way this kind of interaction is represented in the FOM.
Specifically, the TestPublisher and ReflectedTest constructors tell their base classes what kinds of encoders and decoders to use. The TestPublisher constructor chooses its own class to use to represent its objects, and the ReflectedTestList constructor chooses what FOM classes to manage.
We derive TestPublisher from DtObjectPublisher in testPub.h and testPub.cxx. As you can see, this class just configures its base class properly in its constructor, and provides type safety in accessing its state repository.
ReflectedTest performs similar tasks for incoming objects. In addition to the testStateRep() and tsr() functions, the class provides type-specific versions of the list management functions next(), prev(), wrapNext(), and wrapPrev(), and of the post update callback registration functions.
This class is derived from DtReflectedObject in refTest.h and refTest.cxx. The implementations of these functions are trivial, in most cases calling down to base class versions, and performing a cast between a specific and a general type.
After we create a ReflectedTest class, we need to create a ReflectedTestList class that knows how to create and manage ReflectedTests. This class is derived from DtReflectedObjectList in refTestList.h and refTestList.cxx.
The TestEncoder class (in testEnc.h and testEnc.cxx) is implemented similarly to the decoder class, but it also contains checking functions in addition to encoding functions.
TestDecoder is defined in testDec.h and testDec.cxx. Macros help out in the declaration and definition of decoding functions, which are implemented as static member functions of TestDecoder. The TestDecoder constructor self-registers its decoding functions.
Once all of these classes are set up, they can be used in applications just like VR-Link's normal publishers, reflected object lists, and reflected objects, as in testObj.cxx.
After you build the testObj example, run two copies of it. You should see each print out state data that it receives from the other.