VR-Link API Documentation for HLA 1.3
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Simple Test Interaction Example

Table of Contents

Test Simple Interaction

The TestSimpleInteraction example demonstrates how a new interaction can be added to a FOM and supported by a VR-Link DtInteraction. Unlike the Test Interaction example, the encoding/decoding is embedded within the Test Interaction.

A new interaction, Test, is added to the RPR FOM, which contains two attributes:

A VR-Link interaction and an application that sends/receives the new Test interaction are contained in this example.

Implementation of Classes

The TestSimpleInteraction example is composed of one major class, TestSimpleInteraction, which extends DtInteraction and holds the Number and Vector data.

Test Simple Interaction Example Code

Main Application

This file contains the Simple Test Interaction application, which sends and receives Simple Test Interactions.

/****************************************************************************
* Copyright (c) 2014 MAK Technologies, Inc
* All rights reserved.
****************************************************************************/
#include "testSimpInter.h"
#include <iostream>
static int keybrdTick();
// Callback function to be called when a TestSimpleInteraction is received.
void testCb( TestSimpleInteraction* inter, void* )
{
std::cout << "Received Test Interaction!" << std::endl;
inter->print();
std::cout << std::endl;
}
int main( int argc, char* argv[] )
{
// Used for error handling
DtINIT_MINIDUMPER( "SimpleInterTest" );
DtExerciseConn conn("example-vrlExtend", "TestInter", new DtEmptyFomMapper());
DtClock* clock = conn.clock();
// Register the callback on incoming TestInteractions.
TestSimpleInteraction::addCallback(&conn, testCb, NULL);
while (1)
{
clock->setSimTime(clock->absRealTime());
conn.drainInput();
if (input.keybrdTick() == -1) break;
// Send a TestSimpleInteraction.
inter.setNumber(10);
inter.setVector(DtVector(1.0, 2.0, 3.0));
conn.sendStamped(inter);
DtSleep(1.0);
}
return 0;
}

Test Simple Interaction Header

/*********************************************************************
** Copyright (c) 1992-2010 MAK Technologies, Inc
** All rights reserved.
*********************************************************************/
#ifndef TestInteraction_H_
#define TestInteraction_H_
#if DtHLA
typedef void (*TestSimpleInteractionCb)(TestSimpleInteraction* inter, void* usr);
{
public:
#if DtHLA_1516
virtual const RTI::ParameterHandleValueMap& phvm() const;
#else
virtual const RTI::ParameterHandleValuePairSet& phvps() const;
#endif
#if DtHLA_1516
virtual void setFromPhvm(const RTI::ParameterHandleValueMap& pvMap);
#else
virtual void setFromPhvps(const RTI::ParameterHandleValuePairSet& pvSet);
#endif
virtual const char* name() const;
virtual void printData() const;
virtual void setNumber(int num);
virtual int number() const;
virtual void setVector(const DtVector& vec);
virtual const DtVector& vector() const;
public:
static DtInteraction* create();
static void addCallback(DtExerciseConn* conn,
TestSimpleInteractionCb cb, void* usr);
static void removeCallback(DtExerciseConn* conn,
TestSimpleInteractionCb cb, void* usr);
protected:
virtual const char* interactionClassToUse(DtExerciseConn* exConn) const;
protected:
int myNum;
};
#endif
#endif

Test Simple Interaction Source

/*********************************************************************
** Copyright (c) 1992-2010 MAK Technologies, Inc
** All rights reserved.
*********************************************************************/
#if DtHLA
#include "testSimpInter.h"
#include <vlutil/vlPrint.h>
// Constructor - just initialize the base class, and local data holders.
myNum(0),
myVec()
{
}
// Destructor - nothing to do.
{
}
// Copy constructor
{
myNum = orig.number();
myVec = orig.vector();
}
// Assignment operator
{
// Guard against assignment to yourself.
if (this == &orig)
{
return *this;
}
myNum = orig.number();
myVec = orig.vector();
return *this;
}
const char* TestSimpleInteraction::name() const
{
// Return the name of this C++ class.
return "TestSimpleInteraction";
}
{
DtInfo << "Number: " << number() << '\n';
// DtVector has a string() member function to get a printable string.
// Since it returns a DtString, we need to force it to const char* with a
// cast.
DtInfo << "Vector: " << vector().string() << std::endl;
}
#if DtHLA_1516
const RTI::ParameterHandleValueMap& TestSimpleInteraction::phvm() const
#else
const RTI::ParameterHandleValuePairSet& TestSimpleInteraction::phvps() const
#endif
{
#if DtHLA_1516
// Create the object that we will fill out and return, if it has never been
// created yet. Store it in a static variable called thePvMap. Note that
// it will get overwritten each time this function is called.
static RTI::ParameterHandleValueMap thePvMap;
// Empty the list.
thePvMap.clear();
if (!exerciseConn())
{
// This function is not useful until the object has been told what
// exerciseConn it is associated with, using setExConn. This is usually
// automatically called by VR-Link for outgoing interactions from within
// DtExerciseConn::send, immediately before we call this function.
DtInfo << "Illegal call to TestSimpleInteraction::phvps.\n"
<< "Must call setExConn first." << std::endl;
return thePvMap;
}
// Get parameter handles
RTI::ParameterHandle numberHandle =
exerciseConn()->rtiAmb()->getParameterHandle(
interactionClassHandle(), L"Number");
RTI::ParameterHandle vectorHandle =
exerciseConn()->rtiAmb()->getParameterHandle(
interactionClassHandle(), L"Vector");
DtNetInt32 netNum = number();
DtNet64Vector netVec = vector();
thePvMap[numberHandle].setData((char *) &netNum, sizeof(netNum));
thePvMap[vectorHandle].setData((char *) &netVec, sizeof(netVec));
return thePvMap;
#else
// Create the object that we will fill out and return, if it has never been
// created yet. Store it in a static variable called thePvSet. Note that
// it will get overwritten each time this function is called.
static RTI::ParameterHandleValuePairSet* thePvSet = NULL;
if (!thePvSet)
{
thePvSet = RTI::ParameterSetFactory::create(numParameters());
}
// Empty the list.
thePvSet->empty();
if (!exerciseConn())
{
// This function is not useful until the object has been told what
// exerciseConn it is associated with, using setExConn. This is usually
// automatically called by VR-Link for outgoing interactions from within
// DtExerciseConn::send, immediately before we call this function.
DtInfo << "Illegal call to TestSimpleInteraction::phvps.\n"
<< "Must call setExConn first." << std::endl;
return *thePvSet;
}
// Get parameter handles
RTI::ParameterHandle numberHandle =
exerciseConn()->rtiAmb()->getParameterHandle("Number",
interactionClassHandle());
RTI::ParameterHandle vectorHandle =
exerciseConn()->rtiAmb()->getParameterHandle("Vector",
interactionClassHandle());
// Add the current values to the list. Implicitly casting to VR-Link "net"
// types causes byte swapping to occur automatically when necessary.
DtNetInt32 netNum = number();
thePvSet->add(numberHandle, (char*) &netNum, sizeof(netNum));
DtNet64Vector netVec = vector();
thePvSet->add(vectorHandle, (char*) &netVec, sizeof(netVec));
return *thePvSet;
#endif
}
#if DtHLA_1516
void TestSimpleInteraction::setFromPhvm(
const RTI::ParameterHandleValueMap& pvMap)
#else
const RTI::ParameterHandleValuePairSet& pvSet)
#endif
{
if (!exerciseConn())
{
// This function is not useful until the object has been told what
// exerciseConn it is associated with, using setExConn. This is usually
// automatically called by VR-Link for incoming interactions immediately
// after we create the object instance.
DtInfo << "Illegal call to TestSimpleInteraction::setFromPhvps.\n"
<< "Must call setExConn first." << std::endl;
return;
}
#if DtHLA_1516
// Get parameter handles
RTI::ParameterHandle numberHandle =
exerciseConn()->rtiAmb()->getParameterHandle(
interactionClassHandle(), L"Number");
RTI::ParameterHandle vectorHandle =
exerciseConn()->rtiAmb()->getParameterHandle(
interactionClassHandle(), L"Vector");
RTI::ParameterHandleValueMap::const_iterator pos = pvMap.find(numberHandle);
if (pos != pvMap.end())
{
DtNetInt32 *netNum = (DtNetInt32*)pos->second.data();
setNumber((int)*netNum);
}
pos = pvMap.find(vectorHandle);
if (pos != pvMap.end())
{
DtNet64Vector *netVec = (DtNet64Vector *)pos->second.data();
setVector((DtVector) *netVec);
}
#else
// Get parameter handles
RTI::ParameterHandle numberHandle =
exerciseConn()->rtiAmb()->getParameterHandle("Number",
interactionClassHandle());
RTI::ParameterHandle vectorHandle =
exerciseConn()->rtiAmb()->getParameterHandle("Vector",
interactionClassHandle());
RTI::ULong index = 0;
for (index = 0; index < pvSet.size(); index++)
{
RTI::ParameterHandle currentHandle = pvSet.getHandle(index);
if (currentHandle == numberHandle)
{
RTI::ULong length = 0;
DtNetInt32 netNum = 0;
// Copy the value of the Number parameters into netNum, and the size
// of the parameter into length.
pvSet.getValue(index, (char*) &netNum, length);
// Call the mutator function to set the value. By using VR-Link
// "net" types, such as DtNetInt32, byte swapping happens
// automatically when necessary when we cast to a native type.
setNumber((int)netNum);
}
else if (currentHandle == vectorHandle)
{
// Similar to the block above, but for the "Vector" parameter.
RTI::ULong length = 0;
DtNet64Vector netVec;
pvSet.getValue(index, (char*) &netVec, length);
setVector((DtVector) netVec);
}
}
#endif
}
// Accessor functions are typically pretty straightforward.
{
myNum = num;
}
{
return myNum;
}
{
myVec = vec;
}
{
return myVec;
}
{
return new TestSimpleInteraction();
}
TestSimpleInteractionCb cb, void* usr)
{
// Cast the TestSimpleInteractionCb to the more general DtReceiveInteractionCb
// and pass it along with the FOM class name to the DtExerciseConn who
// actually maintains the callback lists for all interaction classes.
"Test", (DtReceiveInteractionCb) cb, usr);
// In addition, we choose to register the TestSimpleInteraction class with
// VR-Link here, by associating TestSimpleInteraction's create function with the
// right FOM class. By doing this here, we avoid making the user perform
// this registration step.
#if DtHLA_1516
conn->rtiAmb()->getInteractionClassHandle(L"Test"),
#else
conn->rtiAmb()->getInteractionClassHandle("Test"),
#endif
}
TestSimpleInteractionCb cb, void* usr)
{
// Cast the TestSimpleInteractionCb to the more general DtReceiveInteractionCb
// and pass it along with the FOM class name to the DtExerciseConn who
// actually maintains the callback lists for all interaction classes.
"Test", (DtReceiveInteractionCb) cb, usr);
}
{
return "Test";
}
#endif

Document ID: Generated on Thu Sep 19 02:12:35 EDT 2024 from SVN revision 269601
Copyright © 2005-2024 MAK Technologies. All Rights Reserved (www.mak.com)