![]() |
VR-Link API Documentation for HLA Evolved
|
The testInter example is an HLA-specific example that shows how to add a new interaction class to a FOM.
We need to extend the VR-Link top-level API by adding a new kind of DtInteraction. Then we create mappings between the new FOM class and the new DtInteraction subclass.
This example adds an interaction class called Test to the VrlExtend.fed FED File. It has two parameters:
To add a new interaction class:
The files testInter.h and testInter.cxx contain definitions for a new class called TestInteraction, and its member functions. Like all interaction classes in VR-Link, it is derived from DtInteractionWithEncDec, rather than directly from DtInteraction. DtInteraction is rather general, and allows for a wide variety of subclass implementations, including those that do not involve our concept of encoders and decoders. DtInteractionWithEncDec is set up to deal with encoders and decoders, and we will be taking advantage of this.
TestInteraction includes inspector and mutator functions to access the values of the Number and Parameter parameters. We represent them 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.
The TestInteraction class hard-codes its own FOM mapping information, rather than relying on the default behavior, which is to obtain it from the FOM Mapper. We do this here, because it make things simpler, by saving us the step of configuring the FOM Mapper with mappings for our 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.
This choice manifests itself in the fact that we override the virtual functions interactionClassToUse(), createEncoder() and createDecoder(). The base class implementation of interactionClassToUse() asks the FOM Mapper for the name of a FOM class to use. But TestInteraction's implementation just returns the class name Test. The base versions of createEncoder() and createDecoder() ask the FOM Mapper for instances of the kind of encoder and decoder that have been registered with it for use with the Test interaction class. But TestInteraction's implementations of these functions just return a new'ed TestEncoder and TestDecoder instance respectively.
In addition, within TestInteraction::addCallback(), we inform the DtExerciseConn's interaction factory that it should create an instance of the TestInteraction class to represent incoming interactions of FOM class Test. This is achieved using DtInteractionFactory's addCreator() member function.
Notice that the TestInteraction has decided that it will use instances of the classes TestEncoder and TestDecoder to map between its representation of its parameters, and the FOM representation.
TestEncoder, defined in testEnc.cxx, is derived from DtInteractionEncoder. Macros help out in the declaration and definition of the encoding functions for individual parameters. (Again, encoding functions are provided as static members of the TestEncoder class.)
The "simple" implementation provided by the macros for an encoding function is to obtain a value from a particular interaction class inspector function, cast it to the appropriate "Net" type, which performs byte swapping if necessary, and adds the value to an RTI::ParameterHandleValuePairSet for sending.
The TestEncoder constructor just adds its encoding functions to the base class's table using addEncoder().
TestDecoder, defined in testDec.cxx, is derived from DtInteractionDecoder. Macros help out in the declaration and definition of the decoding functions for individual parameters. The "simple" implementation provided by the macros for a decoding function is to get a pointer to the parameter data from an RTI::ParameterHandleValuePairSet, cast it to a pointer to an appropriate "Net" type, then pass it to one of the interaction class's mutator functions. The implicit cast from the "Net" type to the type expected by the mutator functions will perform byte swapping if necessary.
The TestDecoder constructor just adds its decoding functions to the base class's table using addDecoder().
Once we build the TestInteraction class, and outfit it with a TestEncoder and TestDecoder, we can use it in an application just like any other DtInteraction subclass. In testInterMain.cxx, we create a TestInteraction, fill it out, and send it. We also register a callback on incoming TestInteractions, and print their contents using the virtual printDataToStream() function.
After you build the testInter example, run two copies of it. You should see them communicating with each other. Each should print TestInteractions received from the other.