VR-Link API Documentation for HLA Evolved
Test Simple Interaction

This file contains the TestSimpleInteraction class, which extends DtInteraction and holds the Number and Vector data.


/*********************************************************************
** Copyright (c) 1992-2010 VT MAK
** All rights reserved.
*********************************************************************/


#ifndef TestInteraction_H_
#define TestInteraction_H_

#if DtHLA

#include <vl/hInteraction.h>
#include <matrix/vlVector.h>
#include <vl/hExerciseConn.h>

class TestSimpleInteraction;

typedef void (*TestSimpleInteractionCb)(TestSimpleInteraction* inter, void* usr);

class TestSimpleInteraction : public DtInteraction
{
public:

   TestSimpleInteraction();

   virtual ~TestSimpleInteraction();

   TestSimpleInteraction(const TestSimpleInteraction& orig);

   TestSimpleInteraction& operator=(const TestSimpleInteraction& orig);

#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 char* interactionClassToUse(DtExerciseConn* exConn) const;

protected:
   
   int myNum;
   DtVector myVec;
};

#endif
#endif

/*********************************************************************
** Copyright (c) 1992-2010 VT MAK
** All rights reserved.
*********************************************************************/


#if DtHLA

#include "testSimpInter.h"
#include <vl/hInterFactory.h>
#include <vlutil/vlPrint.h>

// Constructor - just initialize the base class, and local data holders.
TestSimpleInteraction::TestSimpleInteraction() :
   DtInteraction(),
   myNum(0),
   myVec()
{
}

// Destructor - nothing to do.
TestSimpleInteraction::~TestSimpleInteraction()
{
}

// Copy constructor
TestSimpleInteraction::TestSimpleInteraction(const TestSimpleInteraction& orig) :
   DtInteraction(orig)
{
   myNum = orig.number();
   myVec = orig.vector();
}

// Assignment operator
TestSimpleInteraction& TestSimpleInteraction::operator=(const TestSimpleInteraction& orig)
{
   // Guard against assignment to yourself.
   if (this == &orig)
   {
      return *this;
   }

   DtInteraction::operator=(orig);
   
   myNum = orig.number();
   myVec = orig.vector();

   return *this;
}

const char* TestSimpleInteraction::name() const
{
   // Return the name of this C++ class.
   return "TestSimpleInteraction";
}

void TestSimpleInteraction::printData() const
{
   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
void TestSimpleInteraction::setFromPhvps(
   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.

void TestSimpleInteraction::setNumber(int num)
{
   myNum = num;
}

int TestSimpleInteraction::number() const
{
   return myNum;
}

void TestSimpleInteraction::setVector(const DtVector& vec)
{
   myVec = vec;
}

const DtVector& TestSimpleInteraction::vector() const
{
   return myVec;
}

DtInteraction* TestSimpleInteraction::create()
{
   return new TestSimpleInteraction();
}

void TestSimpleInteraction::addCallback(DtExerciseConn* conn,
   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.
   conn->addInteractionCallbackByName(
      "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.
   conn->interactionFactory()->addCreator(
#if DtHLA_1516
      conn->rtiAmb()->getInteractionClassHandle(L"Test"), 
#else
      conn->rtiAmb()->getInteractionClassHandle("Test"), 
#endif
      TestSimpleInteraction::create);
}

void TestSimpleInteraction::removeCallback(DtExerciseConn* conn,
   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.
   conn->removeInteractionCallbackByName(
      "Test", (DtReceiveInteractionCb) cb, usr);
}

char* TestSimpleInteraction::interactionClassToUse(DtExerciseConn* exConn) const
{
   return "Test";
}

#endif

Document ID: Generated on Mon May 14 08:06:18 EDT 2012 from SVN revision 114750
Copyright © 2005-2012 VT MÄK Inc. All Rights Reserved (www.mak.com)