MAK RTIspy API Documentation for HLA Evolved
simpleDDM Example Code for HLA 1516

simpleDDMSimple1516.cxx and simpleDDMFedAmb1516.cxx (simpleDDMFedAmb1516.h) have the RTI calls and federate ambassador calls for the HLA 1516 version of rtisimple.

This page has the code for the following files:


simpleDDMSimple1516.cxx

/******************************************************************************
** Copyright (c) 2006 MaK Technologies, Inc.
** All rights reserved.
******************************************************************************/
/******************************************************************************
** $RCSfile: simpleDDMSimple1516.cxx,v $ $Revision: 1.3 $ $State: Exp $
******************************************************************************/

#ifdef DtHLA1516

#ifdef WIN32
#pragma warning(disable: 4786)
#pragma warning(disable: 4290)
#include <winsock2.h>
#include <process.h>
#include <windows.h>

#else
#include <unistd.h>
#include <stdio.h>
#endif
#include "simpleDDMSimple1516.h"
#include <cstdlib>
using namespace rti1516;
using namespace std;

simpleDDMFederate1516::simpleDDMFederate1516( )
:
   myHourlyInteraction(L"hourlyChime"),
   myQuarterlyInteraction(L"quarterlyChime"),
   mySecondsDimensionName(L"seconds"),
   myUTCDimensionName(L"UTCn"),
   myInterClassName(L"Chimes"),
   myClassName(L"BaseEntity"),
   myAttrName(L"clockPosition"),
   myRTIamb(0),
   myFedAmb(0)
{
   theAmbData.position = 0;
   myFederationName = L"MAKsimpleDDM";
   myFederationFile = L"MAKsimpleDDM.xml";
   myFederateType = L"rtisimple1516";
}

simpleDDMFederate1516::~simpleDDMFederate1516()
{
   if(myRTIamb)
   {
      delete myRTIamb;
   }
   if(myFedAmb)
   {
      delete myFedAmb;
   }
}

simpleDDMFederate1516::simpleDDMFederate1516(simpleDDMFederate1516& data)
:
   myHourlyInteraction(data.myHourlyInteraction),
   myQuarterlyInteraction(data.myQuarterlyInteraction),
   mySecondsDimensionName(data.mySecondsDimensionName),
   myUTCDimensionName(data.myUTCDimensionName),
   myInterClassName(data.myInterClassName),
   myClassName(data.myClassName),
   myAttrName(data.myAttrName)
{
}

void simpleDDMFederate1516::initializeRTI()
{
   vector< wstring > args;

   // rti1516 and Federate Ambassadors
   RTIambassadorFactory* rtiAmbFactory = new RTIambassadorFactory();
   auto_ptr < RTIambassador > rtiAmbAP =
               rtiAmbFactory->createRTIambassador(args);
   myRTIamb = rtiAmbAP.release();
   myFedAmb = new MyFederateAmbassador(theAmbData);
}


// Create the federation execution
bool simpleDDMFederate1516::createFedEx()
{
   wcout << L"createFederationExecution "
      << myFederationName.c_str() << L" "
      << myFederationFile.c_str() << endl;
   try
   {
      myRTIamb->createFederationExecution(myFederationName.c_str(), myFederationFile.c_str());
   }
   catch(FederationExecutionAlreadyExists& ex)
   {
      cout << "Could not create Federation Execution: "
         << "FederationExecutionAlreadyExists: "
         << DtToString(ex.what()) << endl;
      return false;
   }
   catch(rti1516::Exception& ex)
   {
      cout << "rti1516 Exception: "
         << DtToString(ex.what()) << endl
         << "Could not create Federation Execution: " << endl;
      exit(0);
   }

   myRTIamb->evokeMultipleCallbacks(0.1, 0.2);

   wcout << L"Federation Created." << endl;
   return true;
}

// Join the federation execution
bool simpleDDMFederate1516::joinFedEx()
{
   bool joined=false;
   const int maxTry  = 10;
   int numTries = 0;
   wcout << L"joinFederationExecution "
      << myFederateType.c_str() << L" "
      << myFederationName.c_str() << endl;

   while (!joined && numTries++ < maxTry)
   {
      try
      {
         myRTIamb->joinFederationExecution(myFederateType,
                                           myFederationName,
                                          (*myFedAmb));
         joined = true;
      }
      catch(FederationExecutionDoesNotExist)
      {
         wcout << L"FederationExecutionDoesNotExist, try "
            << numTries << L" out of "
            << maxTry << endl;
         continue;
      }
      catch(rti1516::Exception& ex)
      {
         cout << "rti1516 Exception: "
            << DtToString(ex.what()) << endl;
         return false;
      }
      myRTIamb->evokeMultipleCallbacks(0.1, 0.2);

   }
   if (joined)
   {
      wcout << L"Joined Federation." << endl;
      return true;   
   }
   else
   {
      wcout << L"Giving up." << endl;
      myRTIamb->destroyFederationExecution(myFederationName);
      exit(0);
   }
}

// Resign and destroy the federation execution
void simpleDDMFederate1516::resignAndDestroy()
{
   myRegionValid = false;
   myRTIamb->resignFederationExecution(rti1516::DELETE_OBJECTS);
   myRTIamb->destroyFederationExecution(myFederationName);
}

// Create the Region and initialize its bounds
bool simpleDDMFederate1516::createAndInitializeRegions()
{
   try
   {
      // Get the dimension handles
      mySecondsDim = myRTIamb->getDimensionHandle(mySecondsDimensionName);
      myUTCDim = myRTIamb->getDimensionHandle(myUTCDimensionName);
   }
   catch (rti1516::Exception& ex)
   {
      cout << "Caught Exception getting DimensionHandle \n"
         << DtToString(ex.what()) << " " << endl;
      return false;
   }
   myDimHandleSet.insert(mySecondsDim);
   myDimHandleSet.insert(myUTCDim);

   try
   {
      // Create a region
      if ( myIsPublisher )
      {
         // Create the send region
         mySendRegion = myRTIamb->createRegion(myDimHandleSet);
         myRegions.insert(mySendRegion);
         myRegionHandleSet.push_back(make_pair
                                    ( myAttrHandles, myRegions ));
      }
      else
      {
         // Create the listen region
         myListenRegion = myRTIamb->createRegion(myDimHandleSet);
         myRegions.insert(myListenRegion);
         myRegionHandleSet.push_back(make_pair( myAttrHandles, myRegions ));
      }
   }
   catch (rti1516::Exception& ex)
   {
      cout << "rti1516 Exception: " << DtToString(ex.what()) << endl
         << "Could not create Region" << endl;
      return false;           
   }

   // Set region range bounds and commit
   if (myIsPublisher)
   {
      RangeBounds secondsRangeBounds;
      RangeBounds UTCRangeBounds;

      secondsRangeBounds.setLowerBound(mySendLowerBound);
      secondsRangeBounds.setUpperBound(mySendUpperBound);
      UTCRangeBounds.setLowerBound(myUTCZone);
      UTCRangeBounds.setUpperBound(myUTCZone + 1);
      try
      {
         myRTIamb->setRangeBounds(mySendRegion, mySecondsDim, secondsRangeBounds);
         myRTIamb->setRangeBounds(mySendRegion, myUTCDim, UTCRangeBounds);
         myRTIamb->commitRegionModifications(myRegions);
      }
      catch (rti1516::Exception& ex)
      {
         cout << "rti1516 Exception: "
            << DtToString(ex.what()) << endl
            << "Could not changeBounds " << endl;
      }

      theAmbData.lowerSend = mySendLowerBound;
      theAmbData.upperSend = mySendUpperBound;
   }
   else
   {
      RangeBounds secondsRangeBounds;
      RangeBounds UTCRangeBounds;

      secondsRangeBounds.setUpperBound(myListenUpperBound);
      secondsRangeBounds.setLowerBound(myListenLowerBound);
      UTCRangeBounds.setLowerBound(myUTCZone);
      UTCRangeBounds.setUpperBound(myUTCZone + 1);
      try
      {
         myRTIamb->setRangeBounds(myListenRegion, mySecondsDim, secondsRangeBounds);
         myRTIamb->setRangeBounds(myListenRegion, myUTCDim, UTCRangeBounds);
         myRTIamb->commitRegionModifications(myRegions);
      }
      catch (rti1516::Exception& ex)
      {
         cout << "rti1516 Exception: "
            << DtToString(ex.what()) << endl
            << "Could not notify about region mods" << endl;
         return false;           
      }

      myListenUpperBound = secondsRangeBounds.getUpperBound();
      myListenLowerBound = secondsRangeBounds.getLowerBound();
      theAmbData.lowerListen = myListenLowerBound;
      theAmbData.upperListen = myListenUpperBound;
   }

   if (!myIsPublisher)
   {
      theAmbData.lowerListen = myListenLowerBound;
      theAmbData.upperListen = myListenUpperBound;
   }

   myRegionValid = true;

   return true;
}

// Publish and subscribe the object class attributes.
// Register an object instance of the class.
bool simpleDDMFederate1516::publishSubscribeAndRegisterObject()
{
   try
   {
      // Get the object class handle
      myClassHandle = myRTIamb->getObjectClassHandle(myClassName);
      theAmbData.objectClassMap[myClassHandle] = myClassName;
   }
   catch (rti1516::Exception& ex)
   {
      cout << "rti1516 Exception: "
         << DtToString(ex.what()) << endl;
      cout << "Could not get object class handle: "
         << DtToString( myClassName ) << endl;
      return false;
   }

   try
   {
      // Get the attribute handles and construct the name-handle map and
      // attribute set
      theAmbData.myPositionHandle =
         myRTIamb->getAttributeHandle(myClassHandle, myAttrName);
      myAttrNameHandleMap.insert(make_pair(myAttrName, theAmbData.myPositionHandle));
      myAttrHandles.insert(theAmbData.myPositionHandle);
   }
   catch (rti1516::Exception& ex)
   {
      cout << "rti1516 Exception: "
         << DtToString(ex.what()) << endl;
      cout << "Could not get attribute handle "
         << DtToString( myAttrName ) << endl;
      return false;
   }

   // Initialize attribute handle Value Map.
   string initialPosition("0");
   myAttrValues.insert(make_pair(myAttrNameHandleMap[myAttrName],
         VariableLengthData(initialPosition.c_str(), initialPosition.length()+1)));
   myMapsInitialized = true;


   // Initialize the Region
   if (  !createAndInitializeRegions() )
   {
      return false;
   }

   try
   {
      // Publish or subscribe
      if (myIsPublisher)
      {
         myRTIamb->publishObjectClassAttributes(myClassHandle, myAttrHandles);
      }
      else
      {
         myRTIamb->subscribeObjectClassAttributesWithRegions(
                                                         myClassHandle,
                                                         myRegionHandleSet);
      }
      myRTIamb->evokeMultipleCallbacks(0.1, 0.2);
   }
   catch (rti1516::Exception& ex)
   {
      cout << "rti1516 Exception: "
         << DtToString(ex.what()) << endl;
      cout << "Could not "
         << (myIsPublisher ? L"publish" : L"subscribe") << endl;
      return false;
   }

   if (myIsPublisher)
   {
      wstring objectName(L"UTC_publisher_");
      wstringstream zoneID;
      zoneID << myUTCZone;
      objectName += zoneID.str();

      // Reserve object name and register the object instance
      try
      {
         theAmbData.myNameReservationReturned =
            theAmbData.myNameReservationSucceeded = false;
         myRTIamb->reserveObjectInstanceName(objectName);
         int count = 0;
         while (count++ < 100 && !theAmbData.myNameReservationReturned)
         {
            myRTIamb->evokeMultipleCallbacks(0.001, 0.2);
         }

         if (!theAmbData.myNameReservationReturned)
         {
            wcout << L"Failed waiting for reserve object name "
               << objectName.c_str() << endl;
            return false;
         }
         else
         {
#if 0
            // The following two lines are one way of registering an object
               // with no region and then ascribing region qualifiers to the
               // object.
            // It is possible to also call associateRegionsForUpdates for
               // more than one region.  Note: these region associations are
               // additive not substitutive.
            myObjectInstanceHandle =
               myRTIamb->registerObjectInstance(myClassHandle, objectName);
            myRTIamb->associateRegionsForUpdates(myObjectInstanceHandle,
                                                 myRegionHandleSet);
#endif
            // Alternatively, this registers the object with the region
               // qualifiers already specified. In this way, the object
               // will not be discovered if a subscriber does not overlap
               myObjectInstanceHandle =
                  myRTIamb->registerObjectInstanceWithRegions(myClassHandle,
                                                myRegionHandleSet,
                                                objectName);

            // Add object name-handle to map
            theAmbData.objectInstanceMap[myObjectInstanceHandle] = objectName;
               myRTIamb->getObjectInstanceName(myObjectInstanceHandle);
         }
         myRTIamb->evokeMultipleCallbacks(0.1, 0.2);
      }
      catch (rti1516::Exception& ex)
      {
         cout << "rti1516 Exception: "
            << DtToString(ex.what()) << endl
            << "Could not  Register Object "
            << DtToString( objectName)
            << " with class "
            << DtToString( myClassName ) << endl;
         return false;
      }
      cout << "Registered object "
         << DtToString( objectName )
         << " with class name "
         << DtToString( myClassName ) << endl;
   }
   return true;
}

// Publish and Subscribe to an interaction class
bool simpleDDMFederate1516::publishAndSubscribeInteraction()
{
   try
   {
      // Get the interaction class handle
      myInterClassHandle =
         myRTIamb->getInteractionClassHandle(myInterClassName);
      theAmbData.interactionClassMap[myInterClassHandle] = myInterClassName;
   }
   catch (rti1516::Exception& ex)
   {
      cout << "rti1516 Exception: "
         << DtToString(ex.what()) << endl;
      cout << "Could not get interaction class handle: "
         << DtToString(myInterClassName) << endl;
      return false;
   }

   wstring paramName;
   try
   {
      // Get the parameter handles and construct the name-handle map
      myHourlyHandle =
         myRTIamb->getParameterHandle(myInterClassHandle, myHourlyInteraction);
      myParamNameHandleMap[myHourlyInteraction] = myHourlyHandle;
      myQuarterlyHandle = myRTIamb->getParameterHandle(
                                   myInterClassHandle, myQuarterlyInteraction);
      myParamNameHandleMap[myQuarterlyInteraction] = myQuarterlyHandle;
   }
   catch (rti1516::Exception& ex)
   {
      cout << "rti1516 Exception: "
         << DtToString(ex.what()) << endl;
      cout << "Could not get parameter handle "
         << DtToString(myHourlyInteraction)
         <<  " or " << DtToString(myQuarterlyInteraction) << endl;
      return false;
   }

   try
   {
      // Publish and subscribe
      if (myIsPublisher)
      {
         myRTIamb->publishInteractionClass(myInterClassHandle);
         myRTIamb->evokeMultipleCallbacks(0.1, 0.2);
      }
      else
      {
         myRTIamb->subscribeInteractionClassWithRegions(
                                           myInterClassHandle, myRegions);
         myRTIamb->evokeMultipleCallbacks(0.1, 0.2);
      }
   }
   catch (rti1516::Exception& ex)
   {
      cout << "rti1516 Exception: "
         << DtToString(ex.what()) << endl;
      cout << "Could not "
         << (myIsPublisher ? L"publish" : L"subscribe")
         << " to interaction class." << endl;
      return false;
   }

   if (!myIsPublisher)
   {
      wcout
         << L"Subscribed to interaction class: "
         << myInterClassName.c_str()
         << endl;
   }
   return true;
}



void simpleDDMFederate1516::sendUpdate( int currentPosition )
{
   stringstream ss;
   ss << "1516-" << myUpdateCount++;
   string tagForThisUpdate(ss.str());

   // myAttrHandleMap contains AttributeHandles indexed by attributeNames
   // myAttrValues contains values (VariableLengthData) indexed by attributeHandles

   setPosition(currentPosition);
   try
   {
      myRTIamb->updateAttributeValues(
                                 myObjectInstanceHandle,
                                 myAttrValues,
                                 VariableLengthData(tagForThisUpdate.c_str(),
                                 tagForThisUpdate.size()+1));
   }
   catch (rti1516::Exception& ex)
   {
      cout << "Caught Exception in update Attribute Values\n"
         << DtToString(ex.what()) << endl;
   }
}


// Parameter values will be constructed when the sender generates an
   //   interaction and emptied after the interaction is sent.
   // Format is narrow string representation to remain
   //   compatible with 1.3 simple federate

void simpleDDMFederate1516::sendInteraction_hourly()
{
   stringstream ss;
   ss << "1516-" << myUpdateCount++;
   string tagForThisUpdate(ss.str());

   try
   {
      myParamValues.insert(make_pair(
                     myHourlyHandle,
                     VariableLengthData(
                     DtToString(myHourlyInteraction).c_str(),
                     DtToString(myHourlyInteraction).size() + 1)));


      myRTIamb->sendInteractionWithRegions(
                        myInterClassHandle,
                        myParamValues,
                        myRegions,
                        VariableLengthData(tagForThisUpdate.c_str(),
                        tagForThisUpdate.size() + 1) );
   }
   catch (rti1516::Exception& ex)
   {
      cout << "Caught Exception in send Interaction With Regions\n"
         << DtToString(ex.what()) << endl;
   }
    myParamValues.erase(myHourlyHandle);
}

void simpleDDMFederate1516::sendInteraction_quarterly()
{
   stringstream ss;
   ss << "1516-" << myUpdateCount++;
   string tagForThisUpdate(ss.str());

   try
   {
      myParamValues.insert(make_pair(myQuarterlyHandle,
                     VariableLengthData(
                     DtToString(myQuarterlyInteraction).c_str(),
                     DtToString(myQuarterlyInteraction).size() + 1)));

      myRTIamb->sendInteractionWithRegions(
                        myInterClassHandle,
                        myParamValues,
                        myRegions,
                        VariableLengthData(tagForThisUpdate.c_str(),
                        tagForThisUpdate.size() + 1) );
   }
   catch (rti1516::Exception& ex)
   {
      cout << "Caught Exception in send Interaction With Regions\n"
         << DtToString(ex.what()) << endl;
   }
   myParamValues.erase(myQuarterlyHandle);
}


void simpleDDMFederate1516::changeBounds(int lowerSeconds, int upperSeconds, int newUTC )
{
   if ( !myRegionValid )
   {
      // Region has not be created yet, just set up the range values
      myUTCZone = newUTC;
      if (myIsPublisher)
      {
         mySendLowerBound = lowerSeconds;
         mySendUpperBound = upperSeconds;
      }
      else
      {
         myListenLowerBound = lowerSeconds;
         myListenUpperBound = upperSeconds;
      }
   }
   else if (myIsPublisher)
   {
      try
      {
         RangeBounds secondsRangeBounds;
         RangeBounds UTCRangeBounds;

         // Put the values into range bounds
         UTCRangeBounds.setUpperBound(newUTC + 1);
         UTCRangeBounds.setLowerBound(newUTC);
         secondsRangeBounds.setUpperBound(upperSeconds);
         secondsRangeBounds.setLowerBound(lowerSeconds);

         // Pass the bounds to the RTI
         myRTIamb->setRangeBounds( mySendRegion,
                                       mySecondsDim, secondsRangeBounds);
         myRTIamb->setRangeBounds( mySendRegion, myUTCDim, UTCRangeBounds);

         // Commit the changes
         myRTIamb->commitRegionModifications(myRegions);

         // Commit was successful, get the ranges back
         secondsRangeBounds =
            myRTIamb->getRangeBounds(mySendRegion, mySecondsDim);
         UTCRangeBounds = myRTIamb->getRangeBounds(mySendRegion, myUTCDim);
         mySendUpperBound = secondsRangeBounds.getUpperBound();
         mySendLowerBound = secondsRangeBounds.getLowerBound();
         myUTCZone = UTCRangeBounds.getLowerBound();
      }
      catch (rti1516::Exception& ex)
      {
         cout << "Caught Exception\n"
              << DtToString(ex.what())
              << " " << endl;
      }
   }
   else
   {
      try
      {
         RangeBounds secondsRangeBounds;
         RangeBounds UTCRangeBounds;

         // Put the values into range bounds
         UTCRangeBounds.setUpperBound(newUTC + 1);
         UTCRangeBounds.setLowerBound(newUTC);
         secondsRangeBounds.setUpperBound(upperSeconds);
         secondsRangeBounds.setLowerBound(lowerSeconds);

         // Pass the bounds to the RTI
         myRTIamb->setRangeBounds((myListenRegion),
            mySecondsDim, secondsRangeBounds);
         myRTIamb->setRangeBounds(myListenRegion, myUTCDim, UTCRangeBounds );

         // Commit the changes
         myRTIamb->commitRegionModifications(myRegions);

         // Commit was successful, get the ranges back
         secondsRangeBounds =
            myRTIamb->getRangeBounds(myListenRegion, mySecondsDim);
         UTCRangeBounds = myRTIamb->getRangeBounds(myListenRegion, myUTCDim);
         myListenUpperBound = secondsRangeBounds.getUpperBound();
         myListenLowerBound = secondsRangeBounds.getLowerBound();
         myUTCZone = UTCRangeBounds.getLowerBound();
      }
      catch (rti1516::Exception& ex)
      {
         cout << "Caught Exception when changing bounds\n"
              << DtToString(ex.what()) << " " << endl;
      }
   }
}

void simpleDDMFederate1516::tick(double atMost)
{
   try
   {
      myRTIamb->evokeCallback(atMost);
   }
   catch(rti1516::Exception& ex)
   {
      cout << "rti1516 Exception (during evoke Multiple Callbacks): "
         << DtToString(ex.what()) << endl;
   }
}

void simpleDDMFederate1516::tick(double atLeast, double atMost)
{
   try
   {
      myRTIamb->evokeMultipleCallbacks(atLeast, atMost);
   }
   catch(rti1516::Exception& ex)
   {
      cout << "rti1516 Exception (during evoke Multiple Callbacks): "
         << DtToString(ex.what()) << endl;
   }
}

void simpleDDMFederate1516::setPosition(int pos)
{
   // Attribute maps are initialized in publishSubscribeAndRegisterObject
      // which sets myMapsInitialized.
   if (myMapsInitialized)
   {
      // Attribute value will be the current position
      // represented as a string.
      // Format is narrow string representation to remain
      // compatible with the 1.3 federate
      string pos_string;
      ostringstream oss ;
      oss << pos;
      pos_string = oss.str();


      AttributeHandleValueMap::iterator iter =
                        myAttrValues.find(myAttrNameHandleMap[myAttrName]);
      iter->second.setData(pos_string.c_str(), pos_string.length()+1);
   }
   else
   {
      cout << "You must initialize the maps before calling this function.";
   }
}

#endif

simpleDDMFedAmb1516.cxx

/******************************************************************************
** Copyright (c) 2006 MaK Technologies, Inc.
** All rights reserved.
******************************************************************************/
/******************************************************************************
** $RCSfile: simpleDDMFedAmb1516.cxx,v $ $Revision: 1.1 $ $State: Exp $
******************************************************************************/

#ifdef WIN32
#pragma warning(disable: 4786)
#pragma warning(disable: 4290)
#endif


#include <stdio.h>
#include <iomanip>
#include <iostream>
#include "simpleDDMFedAmb1516.h"
#include <cstdlib>

using namespace std;
using namespace rti1516;

void printAttributes(const AttributeHandleValueMap& attributes,
                     const DtTalkAmbData& data)
{
   AttributeHandleValueMap::const_iterator iter = attributes.begin();
   AttributeHandleValueMap::const_iterator theEnd = attributes.end();
   for (; iter != theEnd; iter++)
   {      
      wcout << iter->first.toString().c_str() << L" "
            << DtToWString((char*)iter->second.data()).c_str() << endl;
   }
}

void printParamValues(ParameterHandleValueMap const& paramVals)
{
   ParameterHandleValueMap::const_iterator iter;

   for (iter = paramVals.begin(); iter != paramVals.end(); iter++)
   {
      wcout << iter->first.toString().c_str() << L" "
            << DtToWString((char*)iter->second.data()).c_str() << endl;
   }
}

MyFederateAmbassador::MyFederateAmbassador(DtTalkAmbData & data) :
   NullFederateAmbassador(),
   myData(data)
{
}

MyFederateAmbassador::~MyFederateAmbassador()
   throw ()
{
}

void MyFederateAmbassador::objectInstanceNameReservationSucceeded(
   std::wstring const & theObjectInstanceName)
   throw (
      UnknownName,
      FederateInternalError)
{
   wcout << L"objectInstanceNameReservationSucceeded: "
         << theObjectInstanceName.c_str() << endl;
   myData.myNameReservationReturned =
   myData.myNameReservationSucceeded = true;
}

void MyFederateAmbassador::objectInstanceNameReservationFailed(
   std::wstring const & theObjectInstanceName)
   throw (
      UnknownName,
      FederateInternalError)
{
   wcout << L"objectInstanceNameReservationFailed: "
         << theObjectInstanceName.c_str() << endl;
   myData.myNameReservationReturned = true;
   myData.myNameReservationSucceeded = false;
}

void MyFederateAmbassador::discoverObjectInstance (
   ObjectInstanceHandle theObject,
   ObjectClassHandle theObjectClass,
   std::wstring const & theObjectInstanceName)
   throw (
      CouldNotDiscover,
      ObjectClassNotKnown,
      FederateInternalError)
{
   wcout << L"discoverObjectInstance: "
         << theObjectInstanceName.c_str() << L"("
         << theObject.toString().c_str() << L") of class "
         << myData.objectClassMap[theObjectClass].c_str() << L"( "
         << theObjectClass.toString().c_str() << L")" << endl;

   myData.objectInstanceMap[theObject] = theObjectInstanceName;
}

void MyFederateAmbassador::reflectAttributeValues (
   ObjectInstanceHandle theObject,
   AttributeHandleValueMap const & theAttributeValues,
   VariableLengthData const & theUserSuppliedTag,
   OrderType sentOrder,
   TransportationType theType)
   throw (
      ObjectInstanceNotKnown,
      AttributeNotRecognized,
      AttributeNotSubscribed,
      FederateInternalError)
{
   AttributeHandleValueMap::const_iterator iter
      = theAttributeValues.find(myData.myPositionHandle);

   if (iter != theAttributeValues.end() && iter->second.size() > 0)
   {
      // Position is in the reflected attributes and it contains data
      // The data is a numeric string representation of the position

      myData.position = atoi((char*)iter->second.data());

      cout << "Received Pos (" << myData.position;

      if ( myData.position < myData.lowerListen )
      {
         // Update region overlapped
         // but actual position less than subscribe region
         cout << ") less than subscribe Region [";
      }
      else if ( myData.position > myData.upperListen )
      {
         // Update region overlapped
         // but actual position greater than subscribe region
         cout << ") greater than subscribe Region [";
      }
      else
      {
         // Update region overlapped
         // and actual position inside subscribe region
         cout << ") inside subscribe Region [";
      }
      cout << myData.lowerListen << "," << myData.upperListen << ")\n";
   }
}

void MyFederateAmbassador::reflectAttributeValues
    (ObjectInstanceHandle theObject,
     AttributeHandleValueMap const & theAttributeValues,
     VariableLengthData const & theUserSuppliedTag,
     OrderType sentOrder,
     TransportationType theType,
     RegionHandleSet const & theSentRegionHandleSet)
      throw (ObjectInstanceNotKnown,
             AttributeNotRecognized,
             AttributeNotSubscribed,
             FederateInternalError)
{
   reflectAttributeValues(theObject, theAttributeValues, theUserSuppliedTag,
        sentOrder,theType);
}

void MyFederateAmbassador::reflectAttributeValues
    (ObjectInstanceHandle theObject,
     AttributeHandleValueMap const & theAttributeValues,
     VariableLengthData const & theUserSuppliedTag,
     OrderType sentOrder,
     TransportationType theType,
     LogicalTime const & theTime,
     OrderType receivedOrder)
      throw (ObjectInstanceNotKnown,
             AttributeNotRecognized,
             AttributeNotSubscribed,
             FederateInternalError)
{
   reflectAttributeValues(theObject, theAttributeValues, theUserSuppliedTag,
        sentOrder,theType);
}
  
void MyFederateAmbassador::reflectAttributeValues
    (ObjectInstanceHandle theObject,
     AttributeHandleValueMap const & theAttributeValues,
     VariableLengthData const & theUserSuppliedTag,
     OrderType sentOrder,
     TransportationType theType,
     LogicalTime const & theTime,
     OrderType receivedOrder,
     RegionHandleSet const & theSentRegionHandleSet)
      throw (ObjectInstanceNotKnown,
             AttributeNotRecognized,
             AttributeNotSubscribed,
             FederateInternalError)
{
   reflectAttributeValues(theObject, theAttributeValues, theUserSuppliedTag,
        sentOrder,theType);
}
  
void MyFederateAmbassador::reflectAttributeValues
    (ObjectInstanceHandle theObject,
     AttributeHandleValueMap const & theAttributeValues,
     VariableLengthData const & theUserSuppliedTag,
     OrderType sentOrder,
     TransportationType theType,
     LogicalTime const & theTime,
     OrderType receivedOrder,
     MessageRetractionHandle theHandle)
      throw (ObjectInstanceNotKnown,
             AttributeNotRecognized,
             AttributeNotSubscribed,
             InvalidLogicalTime,
             FederateInternalError)
{
   reflectAttributeValues(theObject, theAttributeValues, theUserSuppliedTag,
        sentOrder,theType);
}

void MyFederateAmbassador::reflectAttributeValues
    (ObjectInstanceHandle theObject,
     AttributeHandleValueMap const & theAttributeValues,
     VariableLengthData const & theUserSuppliedTag,
     OrderType sentOrder,
     TransportationType theType,
     LogicalTime const & theTime,
     OrderType receivedOrder,
     MessageRetractionHandle theHandle,
     RegionHandleSet const & theSentRegionHandleSet)
      throw (ObjectInstanceNotKnown,
             AttributeNotRecognized,
             AttributeNotSubscribed,
             InvalidLogicalTime,
             FederateInternalError)
{
   reflectAttributeValues(theObject, theAttributeValues, theUserSuppliedTag,
        sentOrder,theType);
}

void MyFederateAmbassador::receiveInteraction(
   InteractionClassHandle theInteraction,
   ParameterHandleValueMap const & theParameterValues,
   VariableLengthData const & theUserSuppliedTag,
   OrderType sentOrder,
   TransportationType theType)
   throw (InteractionClassNotRecognized,
          InteractionParameterNotRecognized,
          InteractionClassNotSubscribed,
          FederateInternalError)
{
    const char* tag = theUserSuppliedTag.size() ?
       (const char*)theUserSuppliedTag.data() : "";

   wcout << L"receiveInteraction: "
         << theInteraction.toString() << L" "
         << DtToWString(tag)  << L" "
         << (sentOrder == RECEIVE ? L"RECEIVE " : L"TIMESTAMP ")
         << (theType == RELIABLE ? L"RELIABLE " : L"BEST_EFFORT ")
         << L"#parameters: " << theParameterValues.size() << endl;

   printParamValues(theParameterValues);
}

void MyFederateAmbassador::receiveInteraction(
   InteractionClassHandle theInteraction,
   ParameterHandleValueMap const & theParameterValues,
   VariableLengthData const & theUserSuppliedTag,
   OrderType sentOrder,
   TransportationType theType,
   RegionHandleSet const & theSentRegionHandleSet)
   throw (InteractionClassNotRecognized,
          InteractionParameterNotRecognized,
          InteractionClassNotSubscribed,
          FederateInternalError)
{
    const char* tag = theUserSuppliedTag.size() ?
       (const char*)theUserSuppliedTag.data() : "";

   wcout << L"receiveInteraction: "
         << theInteraction.toString() << L" "
         << DtToWString(tag)  << L" "
         << (sentOrder == RECEIVE ? L"RECEIVE " : L"TIMESTAMP ")
         << (theType == RELIABLE ? L"RELIABLE " : L"BEST_EFFORT ")
         << L"#regions: " << theSentRegionHandleSet.size() << L" "
         << L"#parameters: " << theParameterValues.size() << endl;

   printParamValues(theParameterValues);
}

void MyFederateAmbassador::receiveInteraction(
   InteractionClassHandle theInteraction,
   ParameterHandleValueMap const & theParameterValues,
   VariableLengthData const & theUserSuppliedTag,
   OrderType sentOrder,
   TransportationType theType,
   LogicalTime const & theTime,
   OrderType receivedOrder)
   throw (InteractionClassNotRecognized,
          InteractionParameterNotRecognized,
          InteractionClassNotSubscribed,
          FederateInternalError)
{
    const char* tag = theUserSuppliedTag.size() ?
       (const char*)theUserSuppliedTag.data() : "";

   wcout << L"receiveInteraction: "
         << theInteraction.toString() << L" "
         << DtToWString(tag)  << L" "
         << (sentOrder == RECEIVE ? L"RECEIVE " : L"TIMESTAMP ")
         << (theType == RELIABLE ? L"RELIABLE " : L"BEST_EFFORT ")
         << theTime.toString() << L" "
         << (receivedOrder == RECEIVE ? L"RECEIVE " : L"TIMESTAMP ")
         << L"#parameters: " << theParameterValues.size() << endl;

   printParamValues(theParameterValues);
}

void MyFederateAmbassador::receiveInteraction(
   InteractionClassHandle theInteraction,
   ParameterHandleValueMap const & theParameterValues,
   VariableLengthData const & theUserSuppliedTag,
   OrderType sentOrder,
   TransportationType theType,
   LogicalTime const & theTime,
   OrderType receivedOrder,
   RegionHandleSet const & theSentRegionHandleSet)
   throw (InteractionClassNotRecognized,
          InteractionParameterNotRecognized,
          InteractionClassNotSubscribed,
          FederateInternalError)
{
    const char* tag = theUserSuppliedTag.size() ?
       (const char*)theUserSuppliedTag.data() : "";

   wcout << L"receiveInteraction: "
         << theInteraction.toString() << L" "
         << DtToWString(tag)  << L" "
         << (sentOrder == RECEIVE ? L"RECEIVE " : L"TIMESTAMP ")
         << (theType == RELIABLE ? L"RELIABLE " : L"BEST_EFFORT ")
         << theTime.toString() << L" "
         << (receivedOrder == RECEIVE ? L"RECEIVE " : L"TIMESTAMP ")
         << L"#regions: " << theSentRegionHandleSet.size() << L" "
         << L"#parameters: " << theParameterValues.size() << endl;

   printParamValues(theParameterValues);
}

void MyFederateAmbassador::receiveInteraction(
   InteractionClassHandle theInteraction,
   ParameterHandleValueMap const & theParameterValues,
   VariableLengthData const & theUserSuppliedTag,
   OrderType sentOrder,
   TransportationType theType,
   LogicalTime const & theTime,
   OrderType receivedOrder,
   MessageRetractionHandle theHandle)
   throw (InteractionClassNotRecognized,
          InteractionParameterNotRecognized,
          InteractionClassNotSubscribed,
          InvalidLogicalTime,
          FederateInternalError)
{
    const char* tag = theUserSuppliedTag.size() ?
       (const char*)theUserSuppliedTag.data() : "";

   wcout << L"receiveInteraction: "
         << theInteraction.toString() << L" "
         << DtToWString(tag)  << L" "
         << (sentOrder == RECEIVE ? L"RECEIVE " : L"TIMESTAMP ")
         << (theType == RELIABLE ? L"RELIABLE " : L"BEST_EFFORT ")
         << theTime.toString() << L" "
         << (receivedOrder == RECEIVE ? L"RECEIVE " : L"TIMESTAMP ")
         << theHandle.toString() << L" "
         << L"#parameters: " << theParameterValues.size() << endl;

   printParamValues(theParameterValues);
}

void MyFederateAmbassador::receiveInteraction(
   InteractionClassHandle theInteraction,
   ParameterHandleValueMap const & theParameterValues,
   VariableLengthData const & theUserSuppliedTag,
   OrderType sentOrder,
   TransportationType theType,
   LogicalTime const & theTime,
   OrderType receivedOrder,
   MessageRetractionHandle theHandle,
   RegionHandleSet const & theSentRegionHandleSet)
   throw (InteractionClassNotRecognized,
          InteractionParameterNotRecognized,
          InteractionClassNotSubscribed,
          InvalidLogicalTime,
          FederateInternalError) {
}


void MyFederateAmbassador::removeObjectInstance(
   ObjectInstanceHandle theObject,
   VariableLengthData const & theUserSuppliedTag,
   OrderType sentOrder)
   throw (
      ObjectInstanceNotKnown,
      FederateInternalError)
{
   const char* tag = theUserSuppliedTag.size()
      ? (const char*)theUserSuppliedTag.data() : "";

   wcout << L"removeObjectInstance: "
         << myData.objectInstanceMap[theObject].c_str() << L"("
         << theObject.toString().c_str() << L") "
         << DtToWString(tag)  << L" "
         << (sentOrder == RECEIVE ? L"RECEIVE " : L"TIMESTAMP ") << endl;
}

void MyFederateAmbassador::removeObjectInstance(
   ObjectInstanceHandle theObject,
   VariableLengthData const & theUserSuppliedTag,
   OrderType sentOrder,
   LogicalTime const & theTime,
   OrderType receivedOrder)
   throw (
      ObjectInstanceNotKnown,
      FederateInternalError)
{
   const char* tag = theUserSuppliedTag.size()
      ? (const char*)theUserSuppliedTag.data() : "";

   wcout << L"removeObjectInstance: "
         << myData.objectInstanceMap[theObject].c_str() << L"("
         << theObject.toString().c_str() << L") "
         << DtToWString(tag)  << L" "
         << (sentOrder == RECEIVE ? L"RECEIVE " : L"TIMESTAMP ")
         << theTime.toString().c_str() << L" "
         << (receivedOrder == RECEIVE ? L"RECEIVE " : L"TIMESTAMP ") << endl;
}

 void MyFederateAmbassador::removeObjectInstance(
   ObjectInstanceHandle theObject,
   VariableLengthData const & theUserSuppliedTag,
   OrderType sentOrder,
   LogicalTime const & theTime,
   OrderType receivedOrder,
   MessageRetractionHandle theHandle)
   throw (
      ObjectInstanceNotKnown,
      InvalidLogicalTime,
      FederateInternalError)
 {
   const char* tag = theUserSuppliedTag.size()
      ? (const char*)theUserSuppliedTag.data() : "";

   wcout << L"removeObjectInstance: "
         << myData.objectInstanceMap[theObject].c_str() << L"("
         << theObject.toString().c_str() << L") "
         << DtToWString(tag)  << L" "
         << (sentOrder == RECEIVE ? L"RECEIVE " : L"TIMESTAMP ")
         << theTime.toString().c_str() << L" "
         << (receivedOrder == RECEIVE ? L"RECEIVE " : L"TIMESTAMP ")
         << theHandle.toString().c_str()  << endl;
}


void MyFederateAmbassador::attributesInScope (
           ObjectInstanceHandle theObject,
      AttributeHandleSet const & theAttributes)
      throw (ObjectInstanceNotKnown,
             AttributeNotRecognized,
             AttributeNotSubscribed,
             FederateInternalError)
{
   if ( myData.enableScopeAdvisories )
   {
      cout<< "********************************\n"
          << "****Attributes entering scope***\n"
          << "********************************\n";
   }

}

void MyFederateAmbassador::attributesOutOfScope (
           ObjectInstanceHandle theObject,
      AttributeHandleSet const & theAttributes)
      throw (ObjectInstanceNotKnown,
             AttributeNotRecognized,
             AttributeNotSubscribed,
             FederateInternalError)
{
   if ( myData.enableScopeAdvisories )
   {
      cout<< "********************************\n"
          << "****Attributes exiting scope****\n"
          << "********************************\n";
   }
}

moc_simpleDDMAclock.cxx

simpleDDMAclock.cxx

/****************************************************************************
**
** Copyright (C) 2004-2007 Trolltech ASA. All rights reserved.
**
** This file is part of the example classes of the Qt Toolkit.
**
** Licensees holding a valid Qt License Agreement may use this file in
** accordance with the rights, responsibilities and obligations
** contained therein.  Please consult your licensing agreement or
** contact sales@trolltech.com if any conditions of this licensing
** agreement are not clear to you.
**
** Further information about Qt licensing is available at:
** http://www.trolltech.com/products/qt/licensing.html or by
** contacting info@trolltech.com.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
****************************************************************************/
/******************************************************************************
** $RCSfile: simpleDDMAclock.cxx,v $ $Revision: 1.2 $ $State: Exp $
******************************************************************************/

#ifdef SIMPLEDDMGUI

#include "simpleDDMAclock.h"
#include <qwidget.h>
#include <qdatetime.h>
#include <qpainter.h>
#include <qbitmap.h>
#include <qpushbutton.h>
#include <qlineedit.h>
#include <qsize.h>
#include <qsizepolicy.h>
#include <qlayout.h>
#include <qtimer.h> 
#include <qapplication.h>
#include <string>

//
// Constructs an analog clock widget that uses an internal QTimer.
//

const int analogClock::degreesInACircle = 360;
const int analogClock::numHoursOnOurClock = 12;
const int analogClock::numTicksPerDegree = 16;
const unsigned int analogClock::NUMSECONDSPERMINUTE = 60;
const unsigned int analogClock::NUMMINUTESPERHOUR = 60;
const unsigned int analogClock::NUMSECONDSPERHOUR = 
                  NUMSECONDSPERMINUTE * NUMMINUTESPERHOUR;

analogClock::analogClock(bool isPublisher, 
                         bool isClockWise, 
                         int zone,
                         bool displayRegion, 
                         QWidget *parent, 
                         const char *name )
: 
QWidget( parent ),
myMinSeconds(0),
myMinHour(0.0f),
myMinMinutes(0), 
myMaxSeconds(1),
myMaxMinutes(1),
myMaxHour(1.0f),
myHours(-1.0f),
myMinutes(0),
mySeconds(0),
myPublisher(isPublisher),
clockWise(isClockWise),
myDrawArc(displayRegion),
myUTCzone(zone),
initialized(false)
{
   internalTimer = new QTimer(this);
   connect(internalTimer, SIGNAL(timeout()), this, SLOT(update()));
   internalTimer->start(1000);
    
   resize(200, 200);   
   
   
   vLayout = new QVBoxLayout( this );   
   setLayout( vLayout );
   vSpacer = new QSpacerItem( 0, 0, QSizePolicy::Fixed, QSizePolicy::Expanding );
   vLayout->addItem(vSpacer);   
   hLayout = new QHBoxLayout( this );
   vLayout->addLayout( hLayout );

   
   hSpacer = new QSpacerItem( 0, 0, QSizePolicy::Minimum, QSizePolicy::Minimum );         
   clockwiseButton = new QPushButton(this);
   setUTCButton = new QPushButton(this);
   utcLineEdit = new QLineEdit(this);     
  
   initialize();   
}

void analogClock::closeEvent( QCloseEvent* arg)
{   
   if ( initialized )
   {    
      internalTimer->stop();      
   }
   initialized = false;
   QWidget::closeEvent(arg);
}

analogClock::~analogClock()
{

}

void analogClock::initialize()
{   
      
   hLayout->addItem(hSpacer);
   //hLayout->addItem(vSpacer);
   if ( myPublisher )
   {      
      utcLineEdit->hide();
      setUTCButton->hide();
      hLayout->addWidget(clockwiseButton);
   } 
   else
   {                  
      clockwiseButton->hide();
      utcLineEdit->setText(QString::number(myUTCzone));      
      utcLineEdit->setMaximumSize(25, 25);
      utcLineEdit->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);      
      hLayout->addWidget(utcLineEdit);    
      
      setUTCButton->setMaximumSize(115,25);
      //setUTCButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
      setUTCButton->setText("Set the Zone");      
      hLayout->addWidget( setUTCButton );            
   }


   if ( myPublisher )
   {
      connect(clockwiseButton, SIGNAL( clicked()), this,  SLOT(toggle()) );
   }
   else
   {
      connect(setUTCButton, SIGNAL( clicked()), this, SLOT(setUTC()) );
   }   
   internalTimer->start( 100 );     // emit signal every second
   
   if ( myPublisher )
   {
      if (clockWise)      
      {         
         clockwiseButton->setText(QString("Set CCW"));
      }
      else
      {
         clockwiseButton->setText(QString("Set CW"));
      }
   } 
   initialized = true;
}

 

void analogClock::toggle()
{
   if ( initialized ) 
   {
      clockWise = !clockWise;   
      // This should be unnecessary as the connect only happens when
      //myPublisher is true
      // but better safe than sorry!
      if ( myPublisher )
      {
         if (clockWise)
         {
            clockwiseButton->setText(QString("Set CCW"));
         }
      }
      else
      {
         clockwiseButton->setText(QString("Set CW"));
      }
   }
}

void analogClock::setUTC()
{
   if ( initialized ) 
      myUTCzone = utcLineEdit->text().toInt();   
}

void analogClock::paintEvent(QPaintEvent *)
{
   if ( initialized ) 
   {
      QPainter paint( this );
      //paint.setBrush( colorGroup().foreground() );
      drawClock( &paint );
   }
}

void analogClock::drawClock( QPainter* paint )
{
   const int widthOfWindow = 1000;
   const int heightOfWindow = 1300;
   const int diameterOfCircle = 1000;
   const int radiusOfCircle = (int)(diameterOfCircle / 2.0f);   
   const float timeLineWidthPercent = .88f;
   const float circleInUsePercentage = .9f;
   const int circleDiameterInUse = (int)((float)diameterOfCircle * circleInUsePercentage);   
   const int wOrigin = - ( circleDiameterInUse / 2 );      
   
   // Left hash is at leftmost extreme of timeLine.
   const int widthOfLeftHash = (int)(wOrigin * timeLineWidthPercent);
   const int widthOfRightHash = (int)(( wOrigin + circleDiameterInUse ) * timeLineWidthPercent);
   const int heightOfTopOfHash = (wOrigin + (int)(circleDiameterInUse * 1.15f));
   const int heightOfBottomOfHash = (wOrigin + (int)(circleDiameterInUse * 1.2f));
   const int heightOfTimeline = (int)((heightOfTopOfHash + heightOfBottomOfHash) / 2.0f);   
   const int heightOfCurrentPositionTick = heightOfTimeline + (int)( diameterOfCircle * .02f );
   const int numDegreesPerHour = 30;
   const int numDegreesPerMinute = numDegreesPerHour / 5;
   const int numDegreesPerSecond = numDegreesPerMinute;
   const int QT3oclockOffset = 90;
   
   const int lengthOfHourHand = (int) ( radiusOfCircle * .4f);
   const int lengthOfMinuteHand = (int) ( radiusOfCircle * .6f);
   const int lengthOfSecondHand = (int) (radiusOfCircle * .8f);
   const int widthOfHourHand = (int) (radiusOfCircle * .03f);
   const int widthOfMinuteHand = (int) (radiusOfCircle * .025f);
   const int widthOfSecondHand = (int) (radiusOfCircle * .016f);
   
   QColor minuteColor;
   QColor secondColor;
   QColor hourColor;
   QColor BlackColor = QColor(0,0,0);
   paint->save();   
   
   
   if (!myPublisher)
   {    
      minuteColor = QColor(150,0,40);
      secondColor = QColor(0,0,150);
      hourColor = QColor(150,40,170);
   }
   else
   {
      minuteColor = BlackColor;
      secondColor = BlackColor;
      hourColor = BlackColor;
   }
   
   
   QPen arcPenStyle;
   arcPenStyle.setWidth(4);   
   
   paint->setWindow( -radiusOfCircle, -radiusOfCircle, 
      widthOfWindow,
      heightOfWindow );          
   
   paint->setBrushOrigin(QPoint(0,0));
   
   // Set the Viewport to the square defined by the shorter side.
   //(i.e. don't let a non-square window distort image)
   QRect v = paint->viewport();
   int d = qMin( v.width(), v.height() );
   paint->setViewport( v.left() + (v.width()-d)/2,
      v.top() + (v.height()-d)/2, d, d );
   
   paint->save();
   arcPenStyle.setColor(hourColor);
   paint->setPen(arcPenStyle);
   
   if (myDrawArc)
   {
      // Qt places the origin at 3o'clock
      //float myShiftedMinHour = myMinHour + 3.0f;
      //float myMinHoursInDegrees = myShiftedMinHour * (360 / 12);
      //float myMinHoursinQT = myMinHoursInDegrees * 16;
      
      float myMinHoursinQT = (myMinHour - 3.0f) * 
         (degreesInACircle / numHoursOnOurClock) * 
         numTicksPerDegree; 
      
      //float lenInHours = (myMaxHour - myMinHour) ;
      //float lenInDegrees = lenInHours * (360 / 12);
      //float lenInQt = lenInDegrees * 16;
      float lenInQt = (myMaxHour - myMinHour) * 
         (degreesInACircle / numHoursOnOurClock) * 
         numTicksPerDegree;
      
      //the First 4 args describe a bounding box (x,y,w,h).  The arc is drawn on the 
      //circle defined by the box. (Largest circle that can fit in the box)
      //the 5th arg describes the starting point in degrees * 16 that the arc
      //should start at, relative to 3'oclock. Range: [0, 5760] 
      // The 6th arg defines the length of the arc in (16 * degrees) units.\
      // With +/- indicating direction.
      paint->drawArc( -radiusOfCircle,
            -radiusOfCircle,
            diameterOfCircle,
            diameterOfCircle,
            (int)(-myMinHoursinQT),
            (int)( -lenInQt) );        
      
      //We now draw a line to represent our current subscription.     
      arcPenStyle.setWidth(3);
      paint->setPen(arcPenStyle);      
      
      // (start of Timeline) + 
      // (percentage of numHoursOnClock) * (widthOfTimeline)
      int startingWidth = (int)(((float)wOrigin * timeLineWidthPercent) + 
               ((float)myMinHour / (float)numHoursOnOurClock) * 
               ((float)circleDiameterInUse * timeLineWidthPercent));
      
      // (start of Timeline ) +       
      // (percentage of numHoursOnClock) * (widthOfTimeline)      
      int endingWidth = (int)(((float)wOrigin * timeLineWidthPercent) + 
               ((float)myMaxHour / (float)numHoursOnOurClock) * 
               ((float)circleDiameterInUse * timeLineWidthPercent));
      
      paint->drawLine(
            QPoint(startingWidth,heightOfBottomOfHash),
            QPoint(endingWidth,heightOfBottomOfHash) ); 
   }
   
   arcPenStyle.setColor(BlackColor);
   arcPenStyle.setWidth(2);   
   paint->setPen(arcPenStyle);
   //Draw the left hash mark
   
   
   paint->drawLine(
         QPoint(widthOfLeftHash,heightOfTopOfHash), 
         QPoint(widthOfLeftHash,heightOfBottomOfHash ));   
   paint->drawLine(
         QPoint(widthOfRightHash,heightOfTopOfHash), 
         QPoint(widthOfRightHash,heightOfBottomOfHash ));  
   
   arcPenStyle.setWidth(2);
   paint->setPen(arcPenStyle);
   paint->drawLine( 
         QPoint(widthOfLeftHash,heightOfTimeline),
         QPoint(widthOfRightHash, heightOfTimeline) );
   
   
   
   
   arcPenStyle.setWidth(7);
   paint->setPen(arcPenStyle);  
   //the current position tick is just below the current subscription range.
   if (myHours > 0.0f)
   {   
      float centerOfCurrentPosition = ((wOrigin * timeLineWidthPercent) + 
                  (myHours / (float)numHoursOnOurClock)
                  * (circleDiameterInUse * timeLineWidthPercent));      
      paint->drawLine( 
            QPoint( (int)(centerOfCurrentPosition - 2.5f) , heightOfCurrentPositionTick) , 
            QPoint( (int)(centerOfCurrentPosition + 2.5f) , heightOfCurrentPositionTick) );    
   }
   
   paint->restore();
   
   // myHours is initially -1.0f.  Don't display hands if you haven't
   // discovered object!.
   if (myHours > 0.0f)
   {
      const int numPts = 4;
      QPointF pts[numPts];

      paint->save();    
      
      float numHoursInDegrees = (myHours * numDegreesPerHour) - QT3oclockOffset;  
      float numMinutesInDegrees = (myMinutes * numDegreesPerMinute) - QT3oclockOffset;
      float numSecondsInDegrees = (mySeconds * numDegreesPerSecond) - QT3oclockOffset;      
      
      paint->rotate( numHoursInDegrees ); 
      pts[0].setX( -widthOfHourHand );
      pts[0].setY( 0 );
      pts[1].setX( 0 );
      pts[1].setY( -widthOfHourHand );
      pts[2].setX( lengthOfHourHand );
      pts[2].setY( 0 );
      pts[3].setX( 0 );
      pts[3].setY( widthOfHourHand );
      paint->setPen(Qt::NoPen);
      paint->setBrush(hourColor);
      paint->drawConvexPolygon( pts, numPts );
      paint->setPen(Qt::SolidLine);    
      paint->restore();
      
      paint->save();
      paint->setPen(Qt::NoPen);
      paint->setBrush(minuteColor);    
      paint->rotate( numMinutesInDegrees );
      pts[0].setX( -widthOfMinuteHand );
      pts[0].setY( 0 );
      pts[1].setX( 0 );
      pts[1].setY( -widthOfMinuteHand );
      pts[2].setX( lengthOfMinuteHand );
      pts[2].setY( 0 );
      pts[3].setX( 0 );
      pts[3].setY( widthOfMinuteHand );
      paint->drawConvexPolygon( pts, numPts );
      
      paint->setPen(Qt::SolidLine);
      paint->setBrush(Qt::SolidPattern);
      paint->restore();
      
      paint->save();
      paint->setPen(Qt::NoPen);
      paint->setBrush(secondColor);
      paint->rotate( numSecondsInDegrees );
      pts[0].setX( -widthOfSecondHand );
      pts[0].setY( 0 );
      pts[1].setX( 0 );
      pts[1].setY( -widthOfSecondHand );
      pts[2].setX( lengthOfSecondHand );
      pts[2].setY( 0 );
      pts[3].setX( 0 );
      pts[3].setY( widthOfSecondHand );
      paint->drawConvexPolygon( pts, numPts );
      paint->setPen(Qt::SolidLine);
      paint->restore();
   }
   
   paint->setBrushOrigin(QPoint(50,50));
   
   for ( int i=0; i< numHoursOnOurClock; i++ ) 
   {
      paint->drawLine( (int)(radiusOfCircle *.93), 0, 
         (int)(radiusOfCircle * .95), 0 );
      paint->rotate( 30 );
   }
   
   
   paint->restore();
}


#endif // SIMPLEDDMGUI

simpleDDMDisplay.cxx

/******************************************************************************
** Copyright (c) 2006 MaK Technologies, Inc.
** All rights reserved.
******************************************************************************/
/******************************************************************************
** $RCSfile: simpleDDMDisplay.cxx,v $ $Revision: 1.2 $ $State: Exp $
******************************************************************************/

#ifdef SIMPLEDDMGUI

#include "simpleDDMDisplay.h"
#include "simpleDDMAclock.h"
#include "qapplication.h"


#ifdef WIN32 
#include <winsock2.h>
#include <process.h> 
#include <windows.h> 

#else
#include <unistd.h> 
#include <pthread.h>
#endif 

#ifdef WIN32
DWORD WINAPI qtWindowThreadProc( LPVOID lpParam )
#else
  void* qtWindowThreadProc(void* lpParam)
#endif

{     
   clockDisplay* ourParent = (clockDisplay*) lpParam;        
   int numberOfArgs = 0;
   char** args = NULL;      
   
   QApplication ourQapp(numberOfArgs, args);  
   ourParent->a = &ourQapp;
   ourParent->ourAnalogClock = new analogClock( ourParent->isPublisher(),
                  ourParent->isClockWise(),
                  ourParent->zone(),
                  ourParent->areRegionsDisplayed() );
   
   ourParent->ourAnalogClock->resize( 300, 300 );
   ourParent->setHasAClock(true);   
   ourParent->ourAnalogClock->show();
   int result = ourParent->a->exec(); 
   ourParent->setHasAClock(false);
   ourParent->closed = true;       
#ifdef WIN32
   
   return 0;
#else
   //   pthread_exit(NULL); 
   return 0;
#endif
}

clockDisplay::clockDisplay(bool pub, bool cw, bool showReg, int zone)
:
mySeconds(0),
myMinutes(0),
myHours(0.0f),
myUpperBoundRegion(0),
myLowerBoundRegion(1),
myAreRegionsDisplayed(showReg),
myHaveAClock(false),
closed(false),
closing(false),
myIsPublisher(pub),
myIsClockWise(cw),
myUTCZone(zone)
{     
   initializeQTDisplay();      
}

clockDisplay::~clockDisplay()
{    

   setHasAClock(false);

}
void clockDisplay::initializeQTDisplay()
{ 
  
#ifdef WIN32      
   DWORD name;
   HANDLE qtThread; 
   qtThread = CreateThread(NULL, 0, qtWindowThreadProc, this, 0, &name );
   if (qtThread ==  NULL)
   {                  
      ExitProcess(0);
   }
   while ( false == hasAClock() )    
      Sleep(150);
   Sleep(300);
#else      
   pthread_t windowThread;
   pthread_create( &windowThread, NULL, qtWindowThreadProc, this); 
   while ( false == hasAClock() )
     {
      usleep(150);    
     }
#endif //ifdef Win32        
}

void clockDisplay::setTime(int seconds)
{   
   if ( hasAClock() )
   {
      ourAnalogClock->setTime(seconds);
      ourAnalogClock->update();
   }
}

void clockDisplay::setTime(float hour, float min, float sec)
{      
   if ( hasAClock() )
   {
      ourAnalogClock->setTime(hour, min, sec);
      ourAnalogClock->update();   
   }
}

void clockDisplay::setBoundsRegionInSeconds(int lower, int upper)
{
   if ( hasAClock() )
   {
      if ( myAreRegionsDisplayed )
      {
         ourAnalogClock->setRangeInSeconds(lower, upper);
         ourAnalogClock->update();        
      }
   }
}
   
// The owner of a clockDisplay Object instantiates a clockDisplay obj and
 // passes in a value for clockwise.
// clockDisplay::initilizeQTDisplay instantiates a QT display, passing it a 
 // pointer to this.
 // That QT display needs to know whether it is clockwise, and calls this
 //  function.  Then clockDisplay sets clockDisplay::initialized to true.
//The owner of the clockDisplay Object will periodically call isClockWise()
  // and expect that the answer comes from the QT object.
bool clockDisplay::isClockWise()
{
   if (hasAClock())
   {      
      return ourAnalogClock->getClockWise();
   }
   else
   {
      return myIsClockWise;
   }
}

void  clockDisplay::toggleClockWise()
{
   if (hasAClock())
   {      
      ourAnalogClock->toggle();
   }
   else
   {
      myIsClockWise = !myIsClockWise;
   }
}

int clockDisplay::zone()
{
   if (hasAClock())
   {
      return ourAnalogClock->zone();
   }
   else
   {
      return myUTCZone;
   }
}

void clockDisplay::setZone(int newZone)
{
   if ( hasAClock() )
   {
      ourAnalogClock->setZone(newZone);
      myUTCZone = newZone;
   }
   else
   {
      myUTCZone = newZone;
   }
}

#endif // SIMPLEDDMGUI

simpleDDMFederate.cxx

/******************************************************************************
** Copyright (c) 2006 MaK Technologies, Inc.
** All rights reserved.
******************************************************************************/
/******************************************************************************
** $RCSfile: simpleDDMFederate.cxx,v $ $Revision: 1.12 $ $State: Exp $
******************************************************************************/

#ifdef WIN32
#pragma warning(disable: 4786)
#pragma warning(disable: 4290)
#include <winsock2.h>
#include <process.h>
#include <windows.h>


#else
#include <unistd.h>
#include <stdio.h>
#endif

#include "simpleDDMFederate.h"

using namespace std;

const unsigned int simpleDDMFederate::NUMSECONDSPERMINUTE = 60;
const unsigned int simpleDDMFederate::NUMMINUTESPERHOUR = 60;
const unsigned int simpleDDMFederate::NUMSECONDSPERHOUR = NUMSECONDSPERMINUTE * NUMMINUTESPERHOUR;

// 0 seconds is the minimum.
const unsigned int simpleDDMFederate::LOWESTSecondsInRegion = 0;
//60 seconds * 60 minutes * 360 degrees.
const unsigned int simpleDDMFederate::GREATESTSecondsInRegion = NUMSECONDSPERHOUR * 12;
// 0 is the default UTC
const unsigned int simpleDDMFederate::LOWESTUTCInRegion = 0 ;
// We're pretending for this example that the World has only 24 distinct Time Zones. (GREATESTUTCInRegion = 23)
const unsigned int simpleDDMFederate::GREATESTUTCInRegion = 23;

simpleDDMFederate::simpleDDMFederate()
:
   myListenUpperBound(GREATESTSecondsInRegion),
   myListenLowerBound(LOWESTSecondsInRegion),
   mySendUpperBound(LOWESTSecondsInRegion+1),
   mySendLowerBound(LOWESTSecondsInRegion),
   myIsPublisher(false),
   myCurrentposition(0),
   myUpdateCount(0),
   mySizeToInc(1),
   mySendRangeSize(500.0f),
   myEnableScopeAdvisories(false),
   myInitialized(false),
   myClosed(false),
   myMapsInitialized(false),
   myRegionValid(false),
   myUTCZone(LOWESTUTCInRegion)
   {
   }


simpleDDMFederate::simpleDDMFederate(simpleDDMFederate& data)
:
   myListenUpperBound(data.myListenUpperBound),
   myListenLowerBound(data.myListenLowerBound),
   mySendUpperBound(data.mySendUpperBound),
   mySendLowerBound(data.mySendLowerBound),
   myIsPublisher(data.myIsPublisher),
   myCurrentposition(data.myCurrentposition),
   myUpdateCount(data.myUpdateCount),
   mySizeToInc(data.mySizeToInc),
   mySendRangeSize(data.mySendRangeSize),
   myEnableScopeAdvisories(data.myEnableScopeAdvisories),
   myInitialized(data.myInitialized),
   myClosed(data.myClosed),
   myMapsInitialized(data.myMapsInitialized),
   myRegionValid(data.myRegionValid),
   myUTCZone(LOWESTUTCInRegion)
{
}

simpleDDMFederate::~simpleDDMFederate()
{
}

simpleDDMKeyboard.cxx

/******************************************************************************
* Adapted from "Beginning Linux Programming", from Wrox Press -- www.wrox.com
******************************************************************************/
/******************************************************************************
** $RCSfile: simpleDDMKeyboard.cxx,v $ $Revision: 1.2 $ $State: Exp $
******************************************************************************/

#include "simpleDDMKeyboard.h"

#ifdef WIN32
#pragma warning(disable: 4786)
#pragma warning(disable: 4290)
#include <conio.h>
#else
#include <unistd.h>
#endif

keyboard::keyboard()
{
#ifndef WIN32
   tcgetattr(0,&initial_settings);
   new_settings = initial_settings;
   new_settings.c_lflag &= ~ICANON;
   new_settings.c_lflag &= ~ECHO;
   new_settings.c_lflag &= ~ISIG;
   new_settings.c_cc[VMIN] = 1;
   new_settings.c_cc[VTIME] = 0;
   tcsetattr(0, TCSANOW, &new_settings);
   peek_character=-1;
#endif
}

keyboard::~keyboard()
{
#ifndef WIN32
   tcsetattr(0, TCSANOW, &initial_settings);
#endif
}

int keyboard::kbhit()
{
#ifdef WIN32
   return _kbhit();
#else
   unsigned char ch;
   int nread;

   if (peek_character != -1) return 1;
   new_settings.c_cc[VMIN]=0;
   tcsetattr(0, TCSANOW, &new_settings);
   nread = read(0,&ch,1);
   new_settings.c_cc[VMIN]=1;
   tcsetattr(0, TCSANOW, &new_settings);

   if (nread == 1)
   {
      peek_character = ch;
      return 1;
   }
   return 0;
#endif
}

int keyboard::getkey()
{
   char ch;
#ifdef WIN32
   ch = _getch();
#else
   if (peek_character != -1)
   {
      ch = peek_character;
      peek_character = -1;
   }
   else
      read(0,&ch,1);

#endif
   return ch;
}

int keyboard::keybrdTick()
{
   char key = ' ';
   if (!kbhit())
      return 0;
   key = getkey();

   while (key != 'q' && key != 'Q' && key != upKey && key != downKey && kbhit())
      key = getkey();
   if (key == 'q' || key == 'Q')
   {
      return -1;
   }
   else if (key == upKey)
      return 1;
   else if (key == downKey)
      return 2;
   else if (key == leftKey)
      return 3;
   else if (key == rightKey)
      return 4;
   else if (key == 'p' || key == 'P')
      return 5;
   else
      return 6;
}


simpleDDMMain.cxx

/******************************************************************************
** Copyright (c) 2006 MaK Technologies, Inc.
** All rights reserved.
******************************************************************************/
/******************************************************************************
** $RCSfile: simpleDDMMain.cxx,v $ $Revision: 1.7 $ $State: Exp $
******************************************************************************/

// The simpleDDM example demonstrates the use of the Data Distribution Management services.
// It performs the typical federation calls required by most federates (join, create etc.)
// with the addition that when an object is registered or an interaction is sent,
// it is done so "with Region".
//
// The conceptual model of the example is a clock that updates its time.
// The time is represented as the number of seconds along a 12 hour time line.
// There are two dimensions used for routing updates and interactions.
// The dimension seconds designates the position of the clock.
// The dimension UTCn designated the time zone of the clock.
//
// The simpleDDM federate can be either a publisher or a subscriber.
//
// The publisher will register a single object and update its position attribute.
// The position attribute will be associated with a region having the seconds and UTCn dimensions.
// It will also send alarm interactions with this same region.
// The region extent will be maintained to encompass the clock's time zone
// and position. The range bounds for the UTCn dimension will be a single point containing
// the current zone. The range bounds for the seconds dimension will be extrapolated to
// contain future positions (at least the next update).
//
// The subscriber will subscribe to the clock position attribute and the alarm interactions
// with a region having the seconds and UTCn dimensions.  The region extent determines which
// clock is reflected and the time range where it will receive updates and interactions.

#ifdef WIN32
#pragma warning(disable: 4290)
#pragma warning(disable: 4786)
#include <winsock2.h> 
#include <process.h>
#include <windows.h>
#include <exception>
#include <string>
#else
#include <unistd.h>
#include <stdio.h>
#endif

#include <iterator>

#include "simpleDDMKeyboard.h"
#include "simpleDDMFederate.h"

#ifdef SIMPLEDDMGUI
#include "simpleDDMDisplay.h"
#endif //defined SIMPLEDDMGUI

#ifdef DtHLA13
#include "simpleDDMSimple13.h"
#elif DtHLA13DLC
#include "simpleDDMSimple13dlc.h"
#elif DtHLA1516E
#include "simpleDDMSimple1516e.h"
#else
#include "simpleDDMSimple1516.h"
#endif

using namespace std;

#ifndef SIMPLEDDMGUI
// Dummy display class when not linking GUI
class clockDisplay {};
#endif //defined SIMPLEDDMGUI

// Function Prototypes

// Convert command line parameters.
template< class T >
bool convert( const string& param,
             const string& value,
             T& dest );

// Parse command line parameters.
bool parseCmdLine( int argc, char* argv[], simpleDDMFederate* ourFed );

// Create the GUI Display
clockDisplay* createDisplay(simpleDDMFederate* aFederate);

// Change the region bounds
void changeBounds( int lower,
                   int upper,
                   int zone,
                   simpleDDMFederate* aFederate,
                   clockDisplay* aClock = 0);

// Set the time
void SetPosition( int seconds,
              simpleDDMFederate* aFederate,
              clockDisplay* aDisplay = 0 );

// Set the time and adjust the bounds
void SetPositionAndChangeBounds( int seconds,
              simpleDDMFederate* aFederate,
              clockDisplay* aDisplay = 0 );

// Check input for zone changes
bool syncOurZoneWithGui(simpleDDMFederate* aFederate,
   clockDisplay* aDisplay = 0);

// Check input for clockwise changes
bool checkForClockwiseChange(simpleDDMFederate* aFederate,
   clockDisplay* aDisplay = 0);

// Process keyboard input
// Returns -1 if quit command is given
int checkInput(simpleDDMFederate* aFederate,
               clockDisplay* aDisplay);

// Global Data

// Handles keyboard theInput without blocking
keyboard theInput;

// Indicate whether to use a GUI
bool theUseGui = true;

// Indicate whether to display region extents
bool theDisplayRegionExtents = true;

// This variable defines how close to the border of the extents
// (our sender's position can reach) before the sender's region should be
// re-calculated

// This is expressed as a percentage of sendRangeSize
// The default value is 20%, for the default sendRangeSize this indicates
//      that the sender will not update its send region until
//      its position is within 20% distance units of the edge of the Region
float theSendRangeTolerance(20.0f);

// This variable is just the calculation of the above variable multiplied
//    by the size of the send region.
float theSizeOfToleratedSendRange(1);

// The default time zone for publishing and subscribing
const int theDefaultZone = 0;

// This represents the current position of the clock.
//  The valid range for this int is between
// [thePositionLowerBound, thePositionUpperBound)
int theCurrentPosition(0);

// This represents the last position of the clock.
int theLastPosition(0);

// This value represents the current zone of interest.
int theZone(theDefaultZone);

// This value represents the direction of the publisher.
bool theClockWise = true;

// Indicates that the clockwise direction should be changed
bool theChangeClockwiseDirection = false;

// Indicates that the clock movement should be paused
bool thePauseClock = false;

// The time to sleep each execution cycle in milliseconds
#ifdef WIN32
unsigned int theSleepInterval = 2;
#else
unsigned int theSleepInterval = 200;
#endif

// Print an dot for each update to better distinguish the bounds changes.
bool thePrintUpdate = true;

// This value is the default upper bound on legal positions
static int thePositionUpperBound(simpleDDMFederate::GREATESTSecondsInRegion);
// This value is the default lower bound on legal positions
static int thePositionLowerBound(simpleDDMFederate::LOWESTSecondsInRegion);
// The value is the default maximum range
static int theMaximumRange(simpleDDMFederate::GREATESTSecondsInRegion - simpleDDMFederate::LOWESTSecondsInRegion);


// The main routine

int main(int argc, char** argv)
{

   std::cout << "MAK simpleDDM " << std::endl;


   clockDisplay* ourDisplay = 0;
   simpleDDMFederate* ourFed;
#ifdef DtHLA1516   
   ourFed = new simpleDDMFederate1516();
#elif DtHLA1516E
   ourFed = new simpleDDMFederate1516e();
#else   
   ourFed = new simpleDDMFederate13();
#endif

   if (!parseCmdLine(argc, argv, ourFed))
      return 0;

   try
   {
      // Start up
      ourFed->initializeRTI();

      // Create the federation
      ourFed->createFedEx();

      // Join the federation
      ourFed->joinFedEx();

      if ( theUseGui )
      {
         ourDisplay = createDisplay(ourFed);
      }

      // Publish, subscribe and register and object with region
      if (!ourFed->publishSubscribeAndRegisterObject())
      {
         ourFed->resignAndDestroy();
         return 0;
      }

      // Publish and subscribe to the required interaction with Region
      if (!ourFed->publishAndSubscribeInteraction())
      {
         ourFed->resignAndDestroy();
         return 0;
      }

      // The subscriber has no initial position.  It only receives
         // positions updates from the publisher.
      if (ourFed->isPublisher())
      {
         // Initial position
         SetPosition(theCurrentPosition, ourFed);
      }
      

      ourFed->tick(0.0000001, 0.005);

      // Execution loop
      bool finished(false);
      while (!finished)
      {                 
         if (!ourFed->isPublisher())
         {
            // Process subscriber actions

            if (theUseGui)
            {            
               if (syncOurZoneWithGui(ourFed, ourDisplay)) 
               {
#ifdef SIMPLEDDMGUI
                  // Change the bounds to the new zone
                  changeBounds( ourFed->listenLowerBound(),
                                ourFed->listenUpperBound(), 
                                ourDisplay->zone(), 
                                ourFed, 
                                ourDisplay );
#endif
               }
            }
            if (ourFed->position() != theCurrentPosition )
            {
               // A new position has been reflected.
               // Update our local copy and the display.
               theCurrentPosition = ourFed->position();
               SetPosition(theCurrentPosition, ourFed, ourDisplay);
            }
         }
         else
         {
            // Process publisher actions

            checkForClockwiseChange(ourFed, ourDisplay);

            // Increment the position

            if( !thePauseClock )
            {
               if ( theClockWise )
               {
                  // Increment the position in clockwise direction
                  theLastPosition = theCurrentPosition;
                  theCurrentPosition += ourFed->sizeToInc();
                  if ( theCurrentPosition >= thePositionUpperBound )
                  {
                     // The position has reached the end; wrap around
                     theCurrentPosition = thePositionLowerBound
                        + (theCurrentPosition - thePositionUpperBound);
                  }
               }
               else
               {
                  // Increment the position in counter clockwise direction
                  theLastPosition = theCurrentPosition;
                  theCurrentPosition -= ourFed->sizeToInc();

                  if ( theCurrentPosition < thePositionLowerBound )
                  {
                     // The position has reached the beginning; wrap around
                     theCurrentPosition = thePositionUpperBound
                        - (thePositionLowerBound - theCurrentPosition);
                  }
               }

               // Now that the position has been incremented,
               // set it's attrValue in the Federate object and make an update

               SetPositionAndChangeBounds(theCurrentPosition, ourFed, ourDisplay);

               // send the update
               ourFed->sendUpdate(theCurrentPosition);

               // Send an interaction every 3 hours.
               if ( (theCurrentPosition % (60 * 60 * 3)) == 0 )
               {
                  ourFed->sendInteraction_quarterly();
               }

               else if ( (theCurrentPosition % ( 60 * 60 )) == 0 )
               {
                  ourFed->sendInteraction_hourly();
               }
            }
         }


         ourFed->tick(0.0000001, 0.005);

         // Check for input
         if (checkInput(ourFed, ourDisplay) < 0)
         {  
            finished = true;  
         }

#ifdef WIN32
         Sleep(theSleepInterval);
#else
         usleep(theSleepInterval);
#endif

      }
      // Resign and destroy federation
      ourFed->resignAndDestroy();

      if( ourFed )
      {
         delete ourFed;
         ourFed = 0;
      }
   }
#ifdef DtHLA13
   catch (RTI::Exception& ex)
   {
      cout << "RTI Exception (main loop): "
         << ex._name << " " << ex._reason << endl;

      if( ourFed )
      {
         delete ourFed;
      }
   }
#elif DtHLA13DLC
   catch (rti13::Exception& ex)
   {
      cout << "RTI Exception (main loop): "
         << ex._name << " " << ex._reason << endl;

      if( ourFed )
      {
         delete ourFed;
      }
   }
#elif DtHLA1516
   catch (rti1516::Exception& ex)
   {
      cout << "rti1516 Exception (main loop): "
         << DtToString(ex.what()) << endl;

      if( ourFed )
      {
         delete ourFed;
      }
   }
#elif DtHLA1516E
   catch (rti1516e::Exception& ex)
   {
       cout << "rti1516 Exception (main loop): "
           << DtToString(ex.what()) << endl;

       if( ourFed )
       {
           delete ourFed;
       }
   }
#endif
   catch ( ... )
   {
      cout << "Caught unknown exception "
         << endl;

      if( ourFed )
      {
         delete ourFed;
      }

      return 1;
   }
   return 0;

}

clockDisplay* createDisplay(simpleDDMFederate* ourFed)
{
   clockDisplay* tempDisplay = 0;

#ifdef SIMPLEDDMGUI
   // Create a clock GUI and set the initialize it
   tempDisplay = new clockDisplay(ourFed->isPublisher(),
      theClockWise,
      theDisplayRegionExtents,
      theZone != 0);

   if (ourFed->isPublisher())
   {
      changeBounds(ourFed->sendLowerBound(), ourFed->sendUpperBound(),
         theZone, ourFed, tempDisplay );
   }
   else
   {
      changeBounds(ourFed->listenLowerBound(),
         ourFed->listenUpperBound(),
         theZone, ourFed, tempDisplay );
   }
#endif
   return tempDisplay;
}

void SetPosition( int seconds,
              simpleDDMFederate* aFederate,
              clockDisplay* aDisplay )
{
   if (thePrintUpdate && !theUseGui && aFederate->isPublisher())
   {
      // Indicate each update versus range bound update
      cout << ".";
   }
   // Set the position in the federate object
   aFederate->setPosition(seconds);
#ifdef SIMPLEDDMGUI
   // Set the position in the display
   if (aDisplay)
   {
      aDisplay->setTime(seconds);
   }
#endif
}

void SetPositionAndChangeBounds( int seconds,
              simpleDDMFederate* aFederate,
              clockDisplay* aDisplay )
{
   int lowerPos(0);
   int upperPos(0);
   bool updated(false);

   // Set the position,
   // check the range bounds for the new position, and
   // change the bounds when the position is near the edge

   SetPosition(seconds, aFederate, aDisplay);


   if (aFederate->sendRangeSize() >= theMaximumRange)
   {
      // Bounds take up total range
      if (aFederate->sendLowerBound() != thePositionLowerBound
          || aFederate->sendUpperBound() != thePositionUpperBound)
      {
         changeBounds( thePositionLowerBound,
            thePositionUpperBound, theZone, aFederate, aDisplay);
      }
      return;
   }

   if ( theClockWise )
   {
      if ( theCurrentPosition < theLastPosition)
      {
         updated = true;
         // Must have wrapped around, update the bounds
         lowerPos = theCurrentPosition;
         upperPos = lowerPos + aFederate->sendRangeSize();
         if (upperPos > thePositionUpperBound)
         {
            // Don't exceed total range
            upperPos = thePositionUpperBound;
         }
      }
      else if ( (theCurrentPosition + theSizeOfToleratedSendRange) >= aFederate->sendUpperBound() )
      {
         // Position is nearing the end of the send range
         // Move the send range out
         if ( (theCurrentPosition + aFederate->sendRangeSize()) < thePositionUpperBound )
         {
            updated = true;
            // The new send range is within the total range
            lowerPos = theCurrentPosition;
            upperPos = theCurrentPosition + aFederate->sendRangeSize();
         }
         else if (aFederate->sendUpperBound() != thePositionUpperBound)
         {
            updated = true;
            // The new send range would be invalid.
            // However, the range bound cannot wrap around.
            // Set the upper bound to the maximum.
            // Once the upper bound is at the maximum,
            // bounds will remain unchanged until the position wraps
            lowerPos = theCurrentPosition;
            upperPos = thePositionUpperBound;

            // When the position wraps, the update will occur outside of
            // the previous range bound.
            // As an exercise, the federate could simply change clockwise
            // direction when reaching the maximum bound. How should the
            // range bounds be modified?
            // Alternatively, the federate could maintain two regions that
            // split the total range bounds. When the federate reaches
            // a border condition, it could set one range bound as above and
            // set the other range bound to where the federate
            // will be when it wraps.
         }
      }

      if (updated)
      {
         // The range bound needs to be changed.
         changeBounds( lowerPos, upperPos, theZone, aFederate, aDisplay);
      }
   }
   else
   {
      // Moving counter clockwise
      if ( theCurrentPosition > theLastPosition)
      {
         updated = true;
         // Must have wrapped around, update the bounds
         lowerPos = theCurrentPosition - aFederate->sendRangeSize();
         upperPos = theCurrentPosition;
         if (lowerPos < thePositionLowerBound)
         {
            updated = true;
            // Don't exceed total range
            lowerPos = thePositionLowerBound;
         }
      }
      else if ( (theCurrentPosition - theSizeOfToleratedSendRange) <= aFederate->sendLowerBound() )
      {
         // Position is nearing the end of the send range
         // Move the send range out
         if ( (theCurrentPosition - aFederate->sendRangeSize()) > thePositionLowerBound )
         {
            updated = true;
            // The new send range is within the total range
            lowerPos = theCurrentPosition - aFederate->sendRangeSize();
            upperPos = theCurrentPosition;
         }
         else if (aFederate->sendLowerBound() != thePositionLowerBound)
         {
            updated = true;
            // The new send range would be invalid.
            // However, the range bound cannot wrap around.
            // Set the lower bound to the minimum.
            // Once the lower bound is at the minimum,
            // bounds will remain unchanged until the position wraps.
            lowerPos = thePositionLowerBound;
            upperPos = theCurrentPosition;
         }
      }

      if (updated)
      {
         // The range bound needs to be changed.
         changeBounds(lowerPos, upperPos, theZone, aFederate, aDisplay);
      }
   }
}


void changeBounds( int lower,
                   int upper,
                   int zone,
                   simpleDDMFederate* aFederate,
                   clockDisplay* aDisplay)
{

   if ( (lower < (int)simpleDDMFederate::LOWESTSecondsInRegion) ||
      (upper > (int)simpleDDMFederate::GREATESTSecondsInRegion) )
   {
      // Seconds bounds outside limits
      cout << "The limits on seconds Subscriptions are ["  << simpleDDMFederate::LOWESTSecondsInRegion
           << " , " << simpleDDMFederate::GREATESTSecondsInRegion << ")\n";
   }
   else if (lower >= upper)
   {
      // Lower must be greater than upper
      cout << "You must set the Lowerbound to be < your Upper bound\n";
   }
   else if ( (zone < (int)simpleDDMFederate::LOWESTUTCInRegion) ||
         (zone >= (int)simpleDDMFederate::GREATESTUTCInRegion) )
   {
      // Zone bounds outside limits
      cout << "The limits on theZone are ["  << simpleDDMFederate::LOWESTUTCInRegion
           << " , " << simpleDDMFederate::GREATESTUTCInRegion << ")\n";

#ifdef SIMPLEDDMGUI
      if ( aDisplay)
      {
         // Reset display to what should be a good value
         aDisplay->setZone(theZone);
      }
#endif
   }
   else
   {
      // Bounds values are OK
      theZone = zone;

      if (thePrintUpdate && !aDisplay && aFederate->isPublisher())
      {
         // Start new line to break from updates
         cout << endl;
      }
      cout << "Setting Bounds to seconds Range ("
         << lower << "," << upper << ")" << " in zone " << zone << endl;

      aFederate->changeBounds( lower, upper, zone );
#ifdef SIMPLEDDMGUI
      if ( aDisplay )
      {
         // Adjust display
         aDisplay->setBoundsRegionInSeconds(lower, upper );
         aDisplay->setZone(zone);
      }
#endif
   }
}

bool syncOurZoneWithGui(simpleDDMFederate* aFederate,
   clockDisplay* aDisplay)
{
   bool zoneWasChanged = false;
#ifdef SIMPLEDDMGUI
   if ( theUseGui && aDisplay)
   {
      // Check to see if the user has changed the zone
      if ( aFederate->zone() != aDisplay->zone() )
      {         
         zoneWasChanged = true;
         //theZone = aDisplay->zone();
      }
   }
#endif
   return zoneWasChanged;
}

bool checkForClockwiseChange(simpleDDMFederate* aFederate,
   clockDisplay* aDisplay)
{
   bool directionWasChanged = false;
#ifndef SIMPLEDDMGUI
   if (theChangeClockwiseDirection)
   {
      theClockWise = !theClockWise;
      directionWasChanged = true;
      theChangeClockwiseDirection = false;
      cout << "Change direction to " << (theClockWise ? "ClockWise" : "CounterClockWise") << endl;
   }
#else
   if ( theUseGui && aDisplay)
   {
      if (theChangeClockwiseDirection)
      {
         // clockwise direction changed in console
         aDisplay->toggleClockWise();
         theClockWise = aDisplay->isClockWise();
         directionWasChanged = true;
         theChangeClockwiseDirection = false;
      }
      else
      if ( theClockWise != aDisplay->isClockWise() )
      {
         // clockwise direction change in GUI
         theClockWise = aDisplay->isClockWise();
         directionWasChanged = true;
      }
   }
#endif
   return directionWasChanged;
}

int checkInput(simpleDDMFederate* aFederate,
               clockDisplay* aDisplay)
{
   int result = 1;

   // Process keyboard input

   int keyboardReturnCode = theInput.keybrdTick();
   if (keyboardReturnCode < 0)
   {  
      result = -1;
   }
   else if (keyboardReturnCode == 1)
   {
      // keybrdTick returns one if the up arrow was pushed
      // only the subscriber can change timezone.
      if (false == aFederate->isPublisher())
      {         
         changeBounds(
               aFederate->listenLowerBound(),
               aFederate->listenUpperBound(),
               (aFederate->zone() + 1),
               aFederate,
               aDisplay);
      }
   }
   else if (keyboardReturnCode == 2)
   {
      // keybrdTick returns two if the down arrow was pushed
      // only the subscriber can change timezone.
      if (false == aFederate->isPublisher())
      {
         theZone = aFederate->zone();
         changeBounds(
               aFederate->listenLowerBound(),
               aFederate->listenUpperBound(),
               (aFederate->zone() - 1),
               aFederate,
               aDisplay);
      }
   }
   else if (keyboardReturnCode == 3)
   {
      // keybrdTick returns three if the left arrow was pushed
      // only the publisher can change clockwise.
      if (aFederate->isPublisher())
      {
         theChangeClockwiseDirection = theClockWise;
      }
   }
   else if (keyboardReturnCode == 4)
   {
      // keybrdTick returns four if the right arrow was pushed
      // only the publisher can change clockwise.
      if (aFederate->isPublisher())
      {
         theChangeClockwiseDirection = !theClockWise;
      }
   }
   else if (keyboardReturnCode == 5)
   {
      // keybrdTick returns five if 'p' was pressed to pause the rotation
      // only the publisher can pause
      if (aFederate->isPublisher())
      {
         thePauseClock = !thePauseClock;
      }
   }
   else if (keyboardReturnCode != 0)
   {
      if (aFederate->isPublisher())
      {
         cout  << "Left Arrow  - counter clockwise\n"
               << "Right Arrow - clockwise\n"
               << "P,p         - pause/unpause\n"
               << "Q,q         - quit\n";
      }
      else
      {
         cout  << "Up Arrow   - increase listen zone\n"
               << "Down Arrow - decrease listen zone\n"
               << "Q,q        - quit\n";
      }
   }

   return result;
}

bool parseCmdLine( int argc, char* argv[], simpleDDMFederate* ourFed )
{
   // Process commandline input

   // This local variable is used in calculating sendRangeSize
   // The sendRangeSize is calculated by the size of the Range in units of
   // Updates multiplied by sizeToInc in units of Distance / Update.
   // In this example Distance is a measure of time along the Clock.
   float pertinentRange = 500.0f;
   int maxSecondsSubscribe(simpleDDMFederate::GREATESTSecondsInRegion);
   int minSecondsSubscribe(simpleDDMFederate::LOWESTSecondsInRegion);


   vector< string > cmdArgs;
   // Skip the first arg - program name
   copy( argv + 1, argv + argc, back_inserter( cmdArgs ));

   vector< string >::const_iterator cur = cmdArgs.begin();
   vector< string >::const_iterator last = cmdArgs.end();
   int mult(1);


   while ( cur != last )
   {
      vector< string >::const_iterator next = cur + 1;
      if ( *cur == "-h" )
      {
         cerr << usage();
         return false;
      }
      else if (*cur == "-fedFile" )
      {
         ourFed->setFedFileName( next->c_str() );
         ++cur;
      }
      else if (*cur == "-maxSubscribe" )
      {
         if ( !convert<int> (*cur, *next, maxSecondsSubscribe ) )
            return false;
         ++cur;
      }
      else if (*cur == "-minSubscribe" )
      {
         if ( !convert<int> (*cur, *next, minSecondsSubscribe ) )
            return false;

         ++cur;
      }
      else if (*cur == "-maxSubscribeH" )
      {
         float maxSecondsSubscribeH;
         if ( !convert<float> (*cur, *next, maxSecondsSubscribeH ) )
            return false;
         ++cur;
         // convert maxSubscribeH (in Hours) to maxSubscribe (in seconds)
         maxSecondsSubscribe = ((int)(maxSecondsSubscribeH * 60.0f * 60.0f));
      }
      else if (*cur == "-minSubscribeH" )
      {
         float minSecondsSubscribeH;
         if ( !convert<float> (*cur, *next, minSecondsSubscribeH ) )
            return false;
         ++cur;
         // convert minSubscribeH (in Hours) to minSubscribe (in seconds)
         minSecondsSubscribe = ((int)(minSecondsSubscribeH * 60.0f * 60.0f));
      }
      else if (*cur == "-scopeAdvisories" )
      {
         int tmpscopeAdvisory(-1);
         if ( !convert<int> (*cur, *next, tmpscopeAdvisory ) )
            return false;
         if ( tmpscopeAdvisory == 0 || tmpscopeAdvisory == 1 )
            ourFed->setEnableScopeAdvisories(tmpscopeAdvisory != 0);
         else
            return false;
         ++cur;
      }
      else if (*cur == "-isPublisher" )
      {
         int intisPub(0);
         if (!convert<int>(*cur, *next, intisPub))
            return false;
         ourFed->setIsPublisher(intisPub != 0);
         ++cur;
      }
      else if (*cur == "-clockWise" )
      {
         int intCW(0);
         if (!convert<int>(*cur, *next, intCW))
            return false;
         theClockWise = intCW != 0;
         ++cur;
      }
      else if (*cur == "-increment" )
      {
         int inc;
         if (!convert<int> (*cur, *next, inc) )
            return false;
         if (inc < 0)
         {
            ourFed->setSizeToInc(-1 * (1 / inc));
         }
         else if ( inc == 0 )
         {
            cout << " The publisher has to increment > 0\nTo set your increment to be a fraction"
                 << " negative numbers are assigned as follows: (-1 * (1 / input))\n";
            return false;
         }
         else
            ourFed->setSizeToInc(inc);
         ++cur;
      }
      else if (*cur == "-multiplier" )
      {
         if (!convert<int> (*cur, *next, mult))
            return 0;
         ++cur;
      }
      else if (*cur == "-wait" )
      {
         int waitTime = 2;
         if (!convert<int> (*cur, *next, waitTime) || waitTime < 0)
            return false;
#ifdef WIN32
         theSleepInterval = waitTime;
#else
         theSleepInterval = waitTime * 100;
#endif
         ++cur;
      }
      else if (*cur == "-range" )
      {
         if (!convert<float> (*cur, *next, pertinentRange) )
            return false;
         ++cur;
      }
      else if (*cur == "-sendRangeTolerance")
      {
         if (!convert<float> (*cur, *next, theSendRangeTolerance ))
            return false;
         ++cur;
      }
      else if (*cur == "-timeZone" )
      {
         if ( !convert<int> (*cur, *next, theZone ) )
            return false;
         if ( theZone > (int)simpleDDMFederate::GREATESTUTCInRegion
            || theZone < (int)simpleDDMFederate::LOWESTUTCInRegion )
         {
            return false;
         }
         ++cur;
      }
      else if (*cur == "-printUpdate" )
      {
         int printUpdateSwitch(-1);
         if ( !convert<int> (*cur, *next, printUpdateSwitch ) )
            return false;
         if ( printUpdateSwitch == 0 || printUpdateSwitch == 1 )
            thePrintUpdate = printUpdateSwitch == 1;
         else
            return false;
         ++cur;
      }     
      
      else if (*cur == "-displayRegion")
      {
         int tmpdisplayRegion(-1);
         if (!convert<int> (*cur, *next, tmpdisplayRegion ))
            return false;
         if ( tmpdisplayRegion == 0 || tmpdisplayRegion == 1 )
            theDisplayRegionExtents = tmpdisplayRegion == 1;
         else
            return false;
         ++cur;
      }      
      else if (*cur == "-useGUI" )
      {
#ifdef SIMPLEDDMGUI
         int intUseGUI(0);
         if (!convert<int>(*cur, *next, intUseGUI ))
            return false;
         if ( theUseGui == 0 || theUseGui == 1 )
            theUseGui = intUseGUI == 1;
         else
            return false;
         ++cur;
#else
         cerr << "Cannot use -useGUI. The GUI is not available in this version of the example.\n"
            << usage();
         return false;
#endif
      }      
      else
      {
         cerr << "Unrecognized command line option: "
            << *cur << "\n"
            << usage();
         return false;
      }
      ++cur;    
   }

   //******************************************//
   // Check sanity of input parameters         //
   //******************************************//


   if ( (minSecondsSubscribe < (int)simpleDDMFederate::LOWESTSecondsInRegion) ||
      (maxSecondsSubscribe > (int)simpleDDMFederate::GREATESTSecondsInRegion) )
   {
      cout << "The limits on seconds Subscriptions are ["  << simpleDDMFederate::LOWESTSecondsInRegion
           << " , " << simpleDDMFederate::GREATESTSecondsInRegion << ")\nExiting...";
      return false;
   }

   if (minSecondsSubscribe >= maxSecondsSubscribe)
   {
      cout << "You cannot set the Lowerbound to be < your Upper bound\nExiting...\n";
      return false;
   }

   if ( mult < 1 )
   {
      cout << "You cannot set a multiplier to less than unity\nExiting...\n";
      return false;
   }

   if ( pertinentRange < 0 )
   {
      cout << "You must have a non-Zero sized range \nExiting...\n";
      return false;
   }

   if ( (theZone < (int)simpleDDMFederate::LOWESTUTCInRegion) ||
         (theZone >= (int)simpleDDMFederate::GREATESTUTCInRegion) )
   {
      cout << "The limits on theZone are ["  << simpleDDMFederate::LOWESTUTCInRegion
           << " , " << simpleDDMFederate::GREATESTUTCInRegion << ")\nExiting...";
      return false;
   }

   if ( theSendRangeTolerance > 100 || theSendRangeTolerance < 0 )
   {
      cout << "The tolerance parameter is expressed as a percentage of your Range\n"
           << " it must be between [1,100]\n";
      return false;
   }

   //******************************************//
   // Update dependencies of variables that may//
   //   have been set in parseCmdLine          //
   //******************************************//

   //Initial conditions are defined for the subscriber federate,
   // but not for the publishing federate.
   if ( !ourFed->isPublisher() )
   {
      ourFed->changeBounds(minSecondsSubscribe, maxSecondsSubscribe, theZone);
      cout << "Setting initial Bounds to seconds Range ("
         << minSecondsSubscribe << "," << maxSecondsSubscribe << ")"
         << " in zone " << theZone << endl;
   }
   else
   {
      ourFed->changeBounds(0, 1, theZone);
      cout << "No initial bounds specifed, setting to seconds Range ("
         << 0 << "," << 1 << ")" << " in zone " << theZone << endl;
   }

   // Set the initial current position to be with our publishing range
   theCurrentPosition = (0);

   ourFed->setSizeToInc(mult * ourFed->sizeToInc() );

   //******************************************//
   // For the publisher, the size of the region//
   //   shall be determined by the             //
   //pertinentRange * the size of the increment//
   //******************************************//

   ourFed->setSendRangeSize((int)(pertinentRange * ourFed->sizeToInc()));

   //******************************************//
   // For the publisher, the size of the buffer//
   //  between the current position and the    //
   //  edge of the region being advanced upon: //
   //   theSizeOfToleratedSendRange             //
   //pertinentRange * the size of the increment//
   //******************************************//

   theSizeOfToleratedSendRange =
      ((float)ourFed->sendRangeSize() * (theSendRangeTolerance / 100.0f));
   return true;
}

template< class T >
bool convert( const string& param,
             const string& value,
             T& dest )
{
   istringstream convert( value );
   convert >> dest;
   if ( convert.fail() )
   {
      cerr << "Bad Parameter Value\n"
         << "Param: " << param
         << "\tValue: " << value << endl;
      return false;
   }
   return true;
}

simpleDDMAclock.h

/****************************************************************************
**
** Copyright (C) 2004-2007 Trolltech ASA. All rights reserved.
**
** This file is part of the example classes of the Qt Toolkit.
**
** Licensees holding a valid Qt License Agreement may use this file in
** accordance with the rights, responsibilities and obligations
** contained therein.  Please consult your licensing agreement or
** contact sales@trolltech.com if any conditions of this licensing
** agreement are not clear to you.
**
** Further information about Qt licensing is available at:
** http://www.trolltech.com/products/qt/licensing.html or by
** contacting info@trolltech.com.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
****************************************************************************/
/******************************************************************************
** $RCSfile: simpleDDMAclock.h,v $ $Revision: 1.2 $ $State: Exp $
******************************************************************************/

#ifndef ANALOGCLOCK_H
#define ANALOGCLOCK_H

#include <qwidget.h>
#include <math.h>
#include <qlineedit.h>

class QPushButton;
class QVBoxLayout;
class QHBoxLayout;
class QSpacerItem;

class analogClock : public QWidget
{
    Q_OBJECT

public:
    analogClock( bool isPublisher, bool isClockWise, int zone, bool displayRegions, 
        QWidget *parent=0, const char *name=0 );
    
    ~analogClock();
    void setAutoMask(bool b);    
    inline void setRangeInHours(float minimum, float maximum);
    inline void setRangeInSeconds(int minimum, int maximum);
    inline void setTime(int seconds);
    inline void setTime(float hour = 12.0f, float minute = 0, float second = 0);
    inline bool getClockWise();
    inline int  zone();
    inline void setZone(int newZone);

    static const int degreesInACircle;
    static const int numHoursOnOurClock;
    static const int numTicksPerDegree;
    bool initialized;
    
protected:
    void paintEvent(QPaintEvent *event);
    void closeEvent( QCloseEvent* );
    void drawClock( QPainter* paint );
        
private:
   float myMinHour;
   float myMaxHour;
   int myMinSeconds;
   int myMinMinutes;
   int myMaxSeconds;
   int myMaxMinutes;
   float myMinutes;
   float mySeconds;
   float myHours;
   bool myPublisher;
   bool clockWise;
   bool myDrawArc;
   int myUTCzone;

private slots:
    void initialize();

public slots:
   void toggle();
   void setUTC();
   

private:
    QPoint clickPos;
    QPushButton* clockwiseButton;
    QPushButton* setUTCButton;    
    QLineEdit*   utcLineEdit;
    
    QTimer* internalTimer;       
    QVBoxLayout* vLayout;
    QHBoxLayout* hLayout;
    
    QSpacerItem* hSpacer;
    QSpacerItem* vSpacer;
    
    
   static const unsigned int NUMSECONDSPERMINUTE;
   static const unsigned int NUMMINUTESPERHOUR;
   static const unsigned int NUMSECONDSPERHOUR;
};



inline void analogClock::setTime(int seconds)
{   
   
   float hour = seconds / (float)NUMSECONDSPERHOUR;
   seconds -= ( (int)floor(hour) * NUMSECONDSPERHOUR);
   float minute = seconds / (float)NUMSECONDSPERMINUTE;
   seconds -= ( (int)floor(minute) * NUMSECONDSPERMINUTE);
   float second = seconds;
   
   setTime(hour, minute, second);

}

inline void analogClock::setTime(float hour, float minute, float second)
{   
   myHours = hour;
   myMinutes = minute;
   mySeconds = second;
}


inline void analogClock::setRangeInSeconds(int minimum, int maximum )
{
   myMinHour = (float)minimum / (float)NUMSECONDSPERHOUR;
   myMaxHour = (float)maximum / (float)NUMSECONDSPERHOUR;
}

inline void analogClock::setRangeInHours(float minimum, float maximum)
{
   myMinHour = minimum;
   myMaxHour = maximum;
}

inline bool analogClock::getClockWise()
{
   return clockWise;
}

inline int analogClock::zone()
{
   return myUTCzone;
}

inline void analogClock::setZone(int newZone)
{
   myUTCzone = newZone;
   utcLineEdit->setText(QString::number(newZone));

}

#endif // ACLOCK_H

simpleDDMDisplay.h

/******************************************************************************
** Copyright (c) 2006 MaK Technologies, Inc.
** All rights reserved.
******************************************************************************/
/******************************************************************************
** $RCSfile: simpleDDMDisplay.h,v $ $Revision: 1.2 $ $State: Exp $
******************************************************************************/

#ifndef DISPLAYFORREGIONEXAMPLE_H_
#define DISPLAYFORREGIONEXAMPLE_H_

#ifdef SIMPLEDDMGUI

#include <vector>
#include <string>

class analogClock;
class QApplication;
 

class clockDisplay
{
public:
   clockDisplay( bool pub = false, bool cw = true,                               
                            bool showReg = true, int zone = 0 );
   ~clockDisplay();
   clockDisplay(clockDisplay& data);

protected:
   void initializeQTDisplay();


public:
   float upperBoundRegion();
   float lowerBoundRegion();
   bool  areRegionsDisplayed();
   bool  isPublisher();
   bool  isClockWise();
   void  toggleClockWise();
   bool  hasAClock();
   void  setHasAClock(bool newVal);
   int   zone();
   void  setZone(int newZone);
   
   // In Seconds
   void setBoundsRegionInSeconds(int lower, int upper);

   void setTime(int seconds);
   void setTime(float hour, float min, float sec);

   bool myHaveAClock;
   bool closed;  
   bool closing;   

   analogClock* ourAnalogClock;   
   QApplication* a;

private:
   float mySeconds;
   float myMinutes;
   float myHours;
   float myUpperBoundRegion;
   float myLowerBoundRegion;
   bool  myAreRegionsDisplayed;
   bool  myIsPublisher;   
   bool  myIsClockWise;
   int   myUTCZone;

};


inline float clockDisplay::upperBoundRegion()
{
   return myUpperBoundRegion;
}

inline float clockDisplay::lowerBoundRegion()
{
   return myLowerBoundRegion;
}

inline bool clockDisplay::areRegionsDisplayed()
{
   return myAreRegionsDisplayed;
}

inline bool clockDisplay::isPublisher() 
{
   return myIsPublisher;
}

inline bool clockDisplay::hasAClock()
{
  return myHaveAClock;
}

inline void clockDisplay::setHasAClock(bool newVal)
{
   myHaveAClock = newVal;
}

#endif // SIMPLEDDMGUI

#endif // DISPLAYFORREGIONEXAMPLE_H_

simpleDDMFedAmb1516.h

/******************************************************************************
** Copyright (c) 2006 MaK Technologies, Inc.
** All rights reserved.
******************************************************************************/
/******************************************************************************
** $RCSfile: simpleDDMFedAmb1516.h,v $ $Revision: 1.1 $ $State: Exp $
******************************************************************************/

// The Federate Ambassador discovers and remove objects and
// processes object reflects and recieve interactions. It also notes
// attribute scope advisories

#ifndef MyFederateAmbassador_H_
#define MyFederateAmbassador_H_

#include "simpleDDMStringUtil.h"

#include <map>
#include <RTI/RTI1516.h>
#include <RTI/NullFederateAmbassador.h>
#include <string>

// Data exchanged between federate and Federate Ambassador
class DtTalkAmbData
{
public:
   bool myNameReservationReturned;
   bool myNameReservationSucceeded;
   std::map<rti1516::ObjectClassHandle, std::wstring> objectClassMap;
   std::map<rti1516::ObjectInstanceHandle, std::wstring> objectInstanceMap;
   std::map<rti1516::InteractionClassHandle, std::wstring> interactionClassMap;
   rti1516::AttributeHandle myPositionHandle;
   int position;
   int lowerListen;
   int upperListen;
   int lowerSend;
   int upperSend;
   bool enableScopeAdvisories;
   bool isPublisher;
};

class MyFederateAmbassador : public rti1516::NullFederateAmbassador
{
public:

   MyFederateAmbassador(DtTalkAmbData & data);

   virtual ~MyFederateAmbassador()
     throw ();

    virtual
    void
    objectInstanceNameReservationSucceeded
    (std::wstring const & theObjectInstanceName)
     throw (rti1516::UnknownName,
            rti1516::FederateInternalError);

    virtual
    void
    objectInstanceNameReservationFailed
    (std::wstring const & theObjectInstanceName)
     throw (rti1516::UnknownName,
            rti1516::FederateInternalError);

    virtual
    void
    discoverObjectInstance
    (rti1516::ObjectInstanceHandle theObject,
     rti1516::ObjectClassHandle theObjectClass,
     std::wstring const & theObjectInstanceName)
     throw (rti1516::CouldNotDiscover,
            rti1516::ObjectClassNotKnown,
            rti1516::FederateInternalError);


    virtual
    void
    reflectAttributeValues
    (rti1516::ObjectInstanceHandle theObject,
     rti1516::AttributeHandleValueMap const & theAttributeValues,
     rti1516::VariableLengthData const & theUserSuppliedTag,
     rti1516::OrderType sentOrder,
     rti1516::TransportationType theType)
     throw (rti1516::ObjectInstanceNotKnown,
            rti1516::AttributeNotRecognized,
            rti1516::AttributeNotSubscribed,
            rti1516::FederateInternalError);

    virtual
    void
    reflectAttributeValues
    (rti1516::ObjectInstanceHandle theObject,
     rti1516::AttributeHandleValueMap const & theAttributeValues,
     rti1516::VariableLengthData const & theUserSuppliedTag,
     rti1516::OrderType sentOrder,
     rti1516::TransportationType theType,
     rti1516::RegionHandleSet const & theSentRegionHandleSet)
     throw (rti1516::ObjectInstanceNotKnown,
            rti1516::AttributeNotRecognized,
            rti1516::AttributeNotSubscribed,
            rti1516::FederateInternalError);

    virtual
    void
    reflectAttributeValues
    (rti1516::ObjectInstanceHandle theObject,
     rti1516::AttributeHandleValueMap const & theAttributeValues,
     rti1516::VariableLengthData const & theUserSuppliedTag,
     rti1516::OrderType sentOrder,
     rti1516::TransportationType theType,
     rti1516::LogicalTime const & theTime,
     rti1516::OrderType receivedOrder)
     throw (rti1516::ObjectInstanceNotKnown,
            rti1516::AttributeNotRecognized,
            rti1516::AttributeNotSubscribed,
            rti1516::FederateInternalError);
  
    virtual
    void
    reflectAttributeValues
    (rti1516::ObjectInstanceHandle theObject,
     rti1516::AttributeHandleValueMap const & theAttributeValues,
     rti1516::VariableLengthData const & theUserSuppliedTag,
     rti1516::OrderType sentOrder,
     rti1516::TransportationType theType,
     rti1516::LogicalTime const & theTime,
     rti1516::OrderType receivedOrder,
     rti1516::RegionHandleSet const & theSentRegionHandleSet)
     throw (rti1516::ObjectInstanceNotKnown,
             rti1516::AttributeNotRecognized,
             rti1516::AttributeNotSubscribed,
             rti1516::FederateInternalError);
  
    virtual
    void
    reflectAttributeValues
    (rti1516::ObjectInstanceHandle theObject,
     rti1516::AttributeHandleValueMap const & theAttributeValues,
     rti1516::VariableLengthData const & theUserSuppliedTag,
     rti1516::OrderType sentOrder,
     rti1516::TransportationType theType,
     rti1516::LogicalTime const & theTime,
     rti1516::OrderType receivedOrder,
     rti1516::MessageRetractionHandle theHandle)
      throw (rti1516::ObjectInstanceNotKnown,
             rti1516::AttributeNotRecognized,
             rti1516::AttributeNotSubscribed,
             rti1516::InvalidLogicalTime,
             rti1516::FederateInternalError);

    virtual
    void
    reflectAttributeValues
    (rti1516::ObjectInstanceHandle theObject,
     rti1516::AttributeHandleValueMap const & theAttributeValues,
     rti1516::VariableLengthData const & theUserSuppliedTag,
     rti1516::OrderType sentOrder,
     rti1516::TransportationType theType,
     rti1516::LogicalTime const & theTime,
     rti1516::OrderType receivedOrder,
     rti1516::MessageRetractionHandle theHandle,
     rti1516::RegionHandleSet const & theSentRegionHandleSet)
      throw (rti1516::ObjectInstanceNotKnown,
             rti1516::AttributeNotRecognized,
             rti1516::AttributeNotSubscribed,
             rti1516::InvalidLogicalTime,
             rti1516::FederateInternalError);

    virtual
    void
    receiveInteraction
    (rti1516::InteractionClassHandle theInteraction,
     rti1516::ParameterHandleValueMap const & theParameterValues,
     rti1516::VariableLengthData const & theUserSuppliedTag,
     rti1516::OrderType sentOrder,
     rti1516::TransportationType theType)
      throw (rti1516::InteractionClassNotRecognized,
             rti1516::InteractionParameterNotRecognized,
             rti1516::InteractionClassNotSubscribed,
             rti1516::FederateInternalError);

    virtual
    void
    receiveInteraction
    (rti1516::InteractionClassHandle theInteraction,
     rti1516::ParameterHandleValueMap const & theParameterValues,
     rti1516::VariableLengthData const & theUserSuppliedTag,
     rti1516::OrderType sentOrder,
     rti1516::TransportationType theType,
     rti1516::RegionHandleSet const & theSentRegionHandleSet)
      throw (rti1516::InteractionClassNotRecognized,
             rti1516::InteractionParameterNotRecognized,
             rti1516::InteractionClassNotSubscribed,
             rti1516::FederateInternalError);

    virtual
    void
    receiveInteraction
    (rti1516::InteractionClassHandle theInteraction,
     rti1516::ParameterHandleValueMap const & theParameterValues,
     rti1516::VariableLengthData const & theUserSuppliedTag,
     rti1516::OrderType sentOrder,
     rti1516::TransportationType theType,
     rti1516::LogicalTime const & theTime,
     rti1516::OrderType receivedOrder)
      throw (rti1516::InteractionClassNotRecognized,
             rti1516::InteractionParameterNotRecognized,
             rti1516::InteractionClassNotSubscribed,
             rti1516::FederateInternalError);

    virtual
    void
    receiveInteraction
    (rti1516::InteractionClassHandle theInteraction,
     rti1516::ParameterHandleValueMap const & theParameterValues,
     rti1516::VariableLengthData const & theUserSuppliedTag,
     rti1516::OrderType sentOrder,
     rti1516::TransportationType theType,
     rti1516::LogicalTime const & theTime,
     rti1516::OrderType receivedOrder,
     rti1516::RegionHandleSet const & theSentRegionHandleSet)
      throw (rti1516::InteractionClassNotRecognized,
             rti1516::InteractionParameterNotRecognized,
             rti1516::InteractionClassNotSubscribed,
             rti1516::FederateInternalError);

    virtual
    void
    receiveInteraction
    (rti1516::InteractionClassHandle theInteraction,
     rti1516::ParameterHandleValueMap const & theParameterValues,
     rti1516::VariableLengthData const & theUserSuppliedTag,
     rti1516::OrderType sentOrder,
     rti1516::TransportationType theType,
     rti1516::LogicalTime const & theTime,
     rti1516::OrderType receivedOrder,
     rti1516::MessageRetractionHandle theHandle)
      throw (rti1516::InteractionClassNotRecognized,
             rti1516::InteractionParameterNotRecognized,
             rti1516::InteractionClassNotSubscribed,
             rti1516::InvalidLogicalTime,
             rti1516::FederateInternalError);

    virtual
    void
    receiveInteraction
    (rti1516::InteractionClassHandle theInteraction,
     rti1516::ParameterHandleValueMap const & theParameterValues,
     rti1516::VariableLengthData const & theUserSuppliedTag,
     rti1516::OrderType sentOrder,
     rti1516::TransportationType theType,
     rti1516::LogicalTime const & theTime,
     rti1516::OrderType receivedOrder,
     rti1516::MessageRetractionHandle theHandle,
     rti1516::RegionHandleSet const & theSentRegionHandleSet)
      throw (rti1516::InteractionClassNotRecognized,
             rti1516::InteractionParameterNotRecognized,
             rti1516::InteractionClassNotSubscribed,
             rti1516::InvalidLogicalTime,
             rti1516::FederateInternalError);

    virtual
    void
    removeObjectInstance(rti1516::ObjectInstanceHandle theObject,
                         rti1516::VariableLengthData const & theUserSuppliedTag,
                         rti1516::OrderType sentOrder)
      throw (rti1516::ObjectInstanceNotKnown,
             rti1516::FederateInternalError);

    virtual
    void
    removeObjectInstance(rti1516::ObjectInstanceHandle theObject,
                         rti1516::VariableLengthData const & theUserSuppliedTag,
                         rti1516::OrderType sentOrder,
                         rti1516::LogicalTime const & theTime,
                         rti1516::OrderType receivedOrder)
      throw (rti1516::ObjectInstanceNotKnown,
             rti1516::FederateInternalError);

    virtual
    void
    removeObjectInstance(rti1516::ObjectInstanceHandle theObject,
                         rti1516::VariableLengthData const & theUserSuppliedTag,
                         rti1516::OrderType sentOrder,
                         rti1516::LogicalTime const & theTime,
                         rti1516::OrderType receivedOrder,
                         rti1516::MessageRetractionHandle theHandle)
      throw (rti1516::ObjectInstanceNotKnown,
             rti1516::InvalidLogicalTime,
             rti1516::FederateInternalError);

    virtual
    void
    attributesInScope
    (rti1516::ObjectInstanceHandle theObject,
      rti1516::AttributeHandleSet const & theAttributes)
      throw (rti1516::ObjectInstanceNotKnown,
             rti1516::AttributeNotRecognized,
             rti1516::AttributeNotSubscribed,
             rti1516::FederateInternalError) ;

    virtual
    void
    attributesOutOfScope
    (rti1516::ObjectInstanceHandle theObject,
      rti1516::AttributeHandleSet const & theAttributes)
      throw (rti1516::ObjectInstanceNotKnown,
             rti1516::AttributeNotRecognized,
             rti1516::AttributeNotSubscribed,
             rti1516::FederateInternalError) ;

public:
   DtTalkAmbData & myData;
};

#endif

simpleDDMFederate.h

/******************************************************************************
** Copyright (c) 2006 MaK Technologies, Inc.
** All rights reserved.
******************************************************************************/
/******************************************************************************
** $RCSfile: simpleDDMFederate.h,v $ $Revision: 1.17 $ $State: Exp $
******************************************************************************/

#ifndef REGIONEXAMPLE_H_
#define REGIONEXAMPLE_H_

// Base class for wrappers around the RTI Ambassador calls.

#include <sstream>
#include <string>
#include <iostream>
#include <iomanip>
#include <vector>


#include "simpleDDMStringUtil.h"



class simpleDDMFederate
{
public:
// Default Constructor
   simpleDDMFederate();

// Constructor
   simpleDDMFederate(simpleDDMFederate& data);

// Destructor
   virtual ~simpleDDMFederate();

// RTI Wrappers

// Initialize the RTI
   virtual void initializeRTI() = 0;

// Create a federation execution
   virtual bool createFedEx() = 0;

// Join a federation execution
   virtual bool joinFedEx() = 0;

// Resign from the federation execution and destroy it
   virtual void resignAndDestroy() = 0;

// Create the Region and initialize its bounds
   virtual bool createAndInitializeRegions() = 0;

// Publish and subscribe the object class attributes.
// Register an object instance of the class.
   virtual bool publishSubscribeAndRegisterObject() = 0;

// Publish and Subscribe to an interaction class
   virtual bool publishAndSubscribeInteraction() = 0;

// Send the default update with Region.  A less simple federate would have to
// specify which attributes need be updated.  This on merely passes in the
// position which is sent with Region as the object update.
   virtual void sendUpdate(int currentPosition ) = 0;

// Send Interactions with Region.  The following two interactions are meant to
// emulate a cuckoo clock with both an hourly chime, and a quarterly chime.

// Send the hourly interaction with Region. This is an interaction that in this
// example occurs for each hour that is passed on the clock that is not
// {12,3,6,9}.
   virtual void sendInteraction_hourly() = 0;

// Send the quarterly interaction with Region.  This is an interaction that in
// this example occurs for each hour that is passed on the clock that is in the
// following set {12,3,6,9}
   virtual void sendInteraction_quarterly() = 0;

// changeBounds sets the subscription of publication bounds of this federate.
   virtual void changeBounds(int lower, int upper, int UTCZone) = 0;

// Set the RTI's enable advisory switch
   virtual void setEnableScopeAdvisories(bool yesNo) = 0;

// Get scope advisory setting
   bool enableScopeAdvisories() const ;

// Perform the tick or evokeCallback method.
   virtual void tick(double atMost=0.0f) = 0;

// Perform the tick or evokeCallback method.
   virtual void tick(double atLeast, double atMost) = 0;

   // Simulation Methods

// Set federate as publisher (true) or subscriber (false)
   virtual void setIsPublisher(bool yesNo) = 0;

// Return true if this federate is publishing
   bool isPublisher() const ;

// Set the position (number of seconds)
   virtual void setPosition(int data) = 0;

// Get the position (number of seconds)
   virtual int position() = 0;

// Set the number of seconds to increment each cycle
   void setSizeToInc(int data);

// Get the number of seconds to increment each cycle
   int sizeToInc() const ;

// Get the zone used to send or listen
   int zone() const ;

   // Region Range Bound Methods

// Set the update range (number of seconds ahead of current position)
// This value should be at least large enough to have the next update fall
// within the range.
   void setSendRangeSize(int data);

// Get the update range (number of seconds ahead of current position)
   int sendRangeSize() const ;

// Get this listen upper bound
   int listenUpperBound() const ;

// Get this listen lower bound
   int listenLowerBound() const ;

// Get the send upper bound
   int sendUpperBound() const ;

// Get the send lower bound
   int sendLowerBound() const;


// Set the Fed File Name
virtual void setFedFileName(const wchar_t* newFedName) = 0;

// Set the Fed File Name with a std::string.
virtual void setFedFileName(const char* newFedName) = 0;

// Get the Fed File Name
virtual char* getFedFileName() const = 0;

   // Constants used in calculations
   static const unsigned int NUMSECONDSPERMINUTE;
   static const unsigned int NUMMINUTESPERHOUR;
   static const unsigned int NUMSECONDSPERHOUR;

   // 0 seconds is the minimum.
   static const unsigned int LOWESTSecondsInRegion;
   //60 seconds * 60 minutes * 360 degrees.
   static const unsigned int GREATESTSecondsInRegion;
   // 0 is the default UTC
   static const unsigned int LOWESTUTCInRegion;
   // For this example, the World has only 24 distinct Time Zones. (GREATESTUTCInRegion = 23)
   static const unsigned int GREATESTUTCInRegion;

   enum simpleAttributeHandleIndex
   {
      simplePositionIndex = 0,
      simpleMaxIndex
   };

protected:

   // Our upper bound is the number of seconds in a circle.
   // This is our default upper bound of interest extent in our region.
   int myListenUpperBound;

   // This is our default lower bound of interest extent in our region.
   int myListenLowerBound;

   // Is this instance the publisher.  The Simple DDM example has one federate
   // publishing and the other federate publishing no information,
   // simply subscribing.
   bool myIsPublisher;

   //******************************************//
   // The following are publisher specific data
   //******************************************//
   // This is our default upper area of interest extent in our region.
   int mySendUpperBound;
   // This is our default lower area of interest extent in our region.
   int mySendLowerBound;
   // This is the default time increment between ticks (seconds)
   int mySizeToInc;
   // This is the calculated range of the sender
   float mySendRangeSize;
   // This represents the current position of the executing federate.
   //  The valid range for this int is between
   //                     [positionLowerBound, positionUpperBound)
   int myCurrentposition;

   // The number of updates sent
   int myUpdateCount;

   int myUTCZone;

   //******************************************//
   // The following is subscriber specific data
   //******************************************//
   // This boolean enables the scope Advisory callback from the rti1516.
   // The scoping callback is issued when an object that is subscribed with
   // region changes visibility to the federate.  i.e. When the subscribed and
   // published region start to instersect and cease to intersect.
   bool myEnableScopeAdvisories;

   //initialized represents whether or not the QT process has Initialized,
   // After main launches a QT thread,
   //  main waits for QT to set initialized before proceeding
   bool myInitialized;
   // closed is a global representing whether the main loop has exited for any
   // reason including the user closing the dialog.
   // The main loop sets it prior to exiting and the QT thread
   // exits when it detects the main loop has closed.
   bool myClosed;

   bool myRegionValid;
   bool myMapsInitialized;

private:
   // Assignment Operator not implemented: Copy not allowed
   simpleDDMFederate &operator=(const simpleDDMFederate&);
};


inline void simpleDDMFederate::setSizeToInc(int data)
{
   mySizeToInc = data;
}
inline void simpleDDMFederate::setSendRangeSize(int data)
{
   if ( data < (int)(GREATESTSecondsInRegion - LOWESTSecondsInRegion) )
   {
      mySendRangeSize = (float)data;
   }
   else
   {
      mySendRangeSize = (float)(GREATESTSecondsInRegion - LOWESTSecondsInRegion);
   }
}

inline int simpleDDMFederate::listenUpperBound() const
{
   return myListenUpperBound;
}

inline int simpleDDMFederate::listenLowerBound() const
{
   return myListenLowerBound;
}

inline bool simpleDDMFederate::isPublisher() const
{
   return myIsPublisher;
}

inline int simpleDDMFederate::sendUpperBound() const
{
   return mySendUpperBound;
}

inline int simpleDDMFederate::sendLowerBound() const
{
   return mySendLowerBound;
}

inline int simpleDDMFederate::sizeToInc() const
{
   return mySizeToInc;
}

inline int simpleDDMFederate::sendRangeSize() const
{
   return (int)mySendRangeSize;
}

inline bool simpleDDMFederate::enableScopeAdvisories() const
{
   return myEnableScopeAdvisories;
}

inline int simpleDDMFederate::zone() const
{
   return myUTCZone;
}

#endif

simpleDDMKeyboard.h

/******************************************************************************
* Adapted from "Beginning Linux Programming", from Wrox Press -- www.wrox.com
******************************************************************************/
/******************************************************************************
** $RCSfile: simpleDDMKeyboard.h,v $ $Revision: 1.1 $ $State: Exp $
******************************************************************************/

// Utility to allow keyboard input without blocking

#ifndef MYKBHIT_H_
#define MYKBHIT_H_

#ifndef WIN32
#include <termios.h>
#endif

class keyboard
{
public:

   // Special Extended Key Definitions
   enum
   {
#ifdef WIN32
       upKey            = '\110',
       downKey          = '\120',
       leftKey          = '\113',
       rightKey         = '\115'
#else
       // Fix incorrect keybindings in *nix.
       // we're still using the keypad.
       upKey            = 'A',
       downKey          = 'B',
       leftKey          = 'D',
       rightKey         = 'C'
#endif
   };

   keyboard();

   ~keyboard();

   // Returns 1 if keyboard input is ready; otherwise, 0
   int kbhit();

   // Returns character from keyboard if avaialable; otherwise, 0
   int keybrdTick();

protected:

   // Return character from keyboard input
   int getkey();

private:

#ifndef WIN32
   struct termios initial_settings, new_settings;
   int peek_character;
#endif

};


#endif

simpleDDMSimple1516.h

/******************************************************************************
** Copyright (c) 2006 MaK Technologies, Inc.
** All rights reserved.
******************************************************************************/
/******************************************************************************
** $RCSfile: simpleDDMSimple1516.h,v $ $Revision: 1.2 $ $State: Exp $
******************************************************************************/

#ifndef REGIONEXAMPLE1516_H_
#define REGIONEXAMPLE1516_H_

// A wrapper around the RTI Ambassador calls that incorporates
// Data Distribution Management (DDM).
// The typical calls are supported such as create/destroy, join/resign,
// publish/subscribe, register/delete object, update object, and send interaction.
// The DDM calls to create and maintain regions are also supported and regions
// are used with the other services where appropriate.

#include <wchar.h>
#include "simpleDDMFederate.h"
#include <string.h>

#include <RTI/RTI1516.h>
#include <RTI/RTIambassadorFactory.h>
#include "simpleDDMFedAmb1516.h"

// Map between strings and attribute handles
typedef std::map<std::wstring, rti1516::AttributeHandle>  DtAttrNameHandleMap;
// Map between strings and parameter handles
typedef std::map<std::wstring, rti1516::ParameterHandle>  DtParamNameHandleMap;


class simpleDDMFederate1516 : public simpleDDMFederate
{
public:

// Default Constructor
   simpleDDMFederate1516();

// Constructor
   simpleDDMFederate1516(simpleDDMFederate1516& data);

// Destructor
   virtual ~simpleDDMFederate1516();

// RTI Wrappers

// Initialize the RTI
   void initializeRTI();

// Create a federation execution
   bool createFedEx();

// Join a federation execution
   bool joinFedEx();

// Resign from the federation execution and destroy it
   void resignAndDestroy();

// Create the Region and initialize its bounds
   bool createAndInitializeRegions();

// Publish and subscribe the object class attributes.
// Register an object instance of the class.
   bool publishSubscribeAndRegisterObject();

// Publish and Subscribe to an interaction class
   bool publishAndSubscribeInteraction();

// Send the default update with Region.  A less simple federate would have to
// specify which attributes need be updated.  This on merely passes in the
// position which is sent with Region as the object update.
   void sendUpdate(int currentPosition);

// Send Interactions with Region.  The following two interactions are meant to
// emulate a cuckoo clock with both an hourly chime, and a quarterly chime.

// Send the hourly interaction with Region. This is an interaction that in this
// example occurs for each hour that is passed on the clock that is not
// {12,3,6,9}.
   void sendInteraction_hourly();

// Send the quarterly interaction with Region.  This is an interaction that in
// this example occurs for each hour that is passed on the clock that is in the
// following set {12,3,6,9}
   void sendInteraction_quarterly();

// Perform the tick or evokeCallback method.
   void tick(double atMost=0.0f);

// Perform the tick or evokeCallback method.
   void tick(double atLeast, double atMost);

// changeBounds sets the subscription of publication bounds of this federate.
   void changeBounds(int lower, int upper, int UTCZone) ;

// Set the RTI's enable advisory switch
   void setEnableScopeAdvisories(bool yesNo);

   // Simulation Methods

// Set federate as publisher (true) or subscriber (false)
   void setIsPublisher(bool yesNo);

// Get the position (number of seconds)
   int  position();

// Set the position (number of seconds)
   void setPosition(int data);


// Set the Fed File Name
   void setFedFileName(const wchar_t* newFedName);

// Set the Fed File Name with a std::string.
   void setFedFileName(const char* newFedName);


// Get the Fed File Name
char* getFedFileName() const;

   
protected:

// Map between strings and attribute handles
   DtAttrNameHandleMap myAttrNameHandleMap;

// Map between strings and parameter handles
   DtParamNameHandleMap myParamNameHandleMap;

// Construct an attribute handle value pair set with the
// values containing the attribute names
   rti1516::AttributeHandleValueMap myAttrValues;

// Data shared between federate and federate ambassador
   DtTalkAmbData theAmbData;

private:
   // Federate and Federation info
   std::wstring myFederationName;
   std::wstring myFederationFile;
   std::wstring myFederateType;

   // An interaction published at {1, 2, 4, 5, 7, 8, 10 , 11}
   std::wstring myHourlyInteraction;

   // An interaction published at {3,6,9,12}
   std::wstring myQuarterlyInteraction;

   // The interaction class name
   std::wstring myInterClassName;

   // The object class name
   std::wstring myClassName;

   // The attribute name
   std::wstring myAttrName;

   // The RTI Ambassador
   rti1516::RTIambassador* myRTIamb;

   // The Federate Ambassador
   MyFederateAmbassador* myFedAmb;

   // the Handle for the hourlyInteraction, (to be retrieved from rti1516).
   rti1516::ParameterHandle myHourlyHandle;

   // the Handle for the quarterlyInteraction, (to be retrieved from rti1516).
   rti1516::ParameterHandle myQuarterlyHandle;

   // The dimension handle Set.
   rti1516::DimensionHandleSet myDimHandleSet;

   // Construct a parameter handle value pair set with the
   // values containing the parameter names
   rti1516::ParameterHandleValueMap myParamValues;

   // The name of the seconds dimension as specified in your FED file.
   std::wstring mySecondsDimensionName;
   // seconds dimension handle
   rti1516::DimensionHandle mySecondsDim;

   // The name of the UTC dimension as specified in your FED file.
   std::wstring myUTCDimensionName;
   // UTC dimension handle
   rti1516::DimensionHandle myUTCDim;

   // The object class handle (to be retrieved from rti1516).
   rti1516::ObjectClassHandle myClassHandle;

   //The object instance handle ( to be retrieved from the rti).
   rti1516::ObjectInstanceHandle myObjectInstanceHandle;

   // The interaction class handle (to be retrieved from rti1516).
   rti1516::InteractionClassHandle myInterClassHandle;

   rti1516::AttributeHandleSetRegionHandleSetPairVector myRegionHandleSet;

   // Array of attributeHandles.
   rti1516::AttributeHandleSet myAttrHandles;

   // Region handle list
   rti1516::RegionHandleSet myRegions;

   // The listen region
   rti1516::RegionHandle myListenRegion;

   // The send region
   rti1516::RegionHandle mySendRegion;
};


inline void simpleDDMFederate1516::setIsPublisher(bool yesNo)
{
   myIsPublisher = yesNo;
   theAmbData.isPublisher = yesNo;
}

inline void simpleDDMFederate1516::setEnableScopeAdvisories(bool yesNo)
{
   myEnableScopeAdvisories = yesNo;
   theAmbData.enableScopeAdvisories = yesNo;
}

inline int simpleDDMFederate1516::position()
{
   if (!isPublisher())
      myCurrentposition = theAmbData.position;
   return myCurrentposition;
}

inline void simpleDDMFederate1516::setFedFileName(const wchar_t* newFedName)
{   
   myFederationFile = std::wstring(newFedName);
}

inline void simpleDDMFederate1516::setFedFileName(const char* newFedName)
{   
   myFederationFile = DtToWString(newFedName);
}

inline char* simpleDDMFederate1516::getFedFileName() const
{
   return strdup(DtToString(myFederationFile).c_str());
}

#endif

simpleDDMStringUtil.h

/******************************************************************************
** Copyright (c) 2006 MaK Technologies, Inc.
** All rights reserved.
******************************************************************************/
/******************************************************************************
** $RCSfile: simpleDDMStringUtil.h,v $ $Revision: 1.1 $ $State: Exp $
******************************************************************************/

#ifndef stringUtil_H_
#define stringUtil_H_

// Utility for converting strings between narrow and wide formats

#include <string>
#include <sstream>

std::wstring DtToWString(const char* in_val);
std::string DtToString(const std::wstring &in_val);
std::string usage();


// Convert narrow C string to wide string
inline std::wstring DtToWString(const char* in_val)
{
   std::wstring temp;
   while (*in_val != '\0')
   temp += *in_val++;
   return temp;
}

// Convert narrow string to wide string
inline std::string DtToString(const std::wstring &in_val)
{
   std::string temp;
   std::wstring::const_iterator b = in_val.begin();
   const std::wstring::const_iterator e = in_val.end();
   while (b != e)
   {
      temp += static_cast<char>(*b);
      ++b;
   }
   return temp;
}



inline std::string usage()
{
   std::ostringstream ostr;
   ostr << "Usage:\n"

      << std::setw( 20 ) << " -fedFile "
      << "specify the Fed file name \n"
      << std::setw ( 32 ) << " " << "1.3  Default: (MAKSimpleDDM.fed) \n"
      << std::setw ( 32 ) << " " << "1516 Default: (MAKSimpleDDM.xml) \n"
      << "\nSubscriber parameters\n"
      
      << std::setw( 20 ) << " -maxSubscribe "
      << "Simple DDM uses just one extent and dimension, \n"
      << std::setw( 32 ) << " " << "this is the subscribers upper range \n"
      << std::setw( 32 ) << " " << "(in seconds)\n"

      << std::setw( 20 ) << " -minSubscribe "
      << "Simple DDM uses just one extent and dimension, \n"
      << std::setw( 32 ) << " " << "this is the subscriber's lower range \n"
      << std::setw( 32 ) << " " << "(in seconds)\n"

      << std::setw( 20 ) << " -maxSubscribeH "
      << "Simple DDM uses just one extent and dimension, \n"
      << std::setw( 32 ) << " " << "this is the subscribers upper range\n"
      << std::setw( 32 ) << " " << "(in hours)\n"
      
      << std::setw( 20 ) << " -minSubscribeH "
      << "Simple DDM uses just one extent and dimension, \n"
      << std::setw( 32 ) << " " << "this the subscriber's lower range  \n"
      << std::setw( 32 ) << " " << "(in hours)\n"
      
      << std::setw( 20 ) << " -scopeAdvisories "
      << "Whether or not the user wants to receive       \n"
      << std::setw( 32 ) << " " << "scoping advisory notices (0 || 1)\n"


      << "\nPublisher parameters\n"

      << std::setw( 20 ) << " -isPublisher "
      << "Whether the application should as publisher or \n"
      << std::setw( 32 ) << " " << "subscriber. (default 0)\n"

      << std::setw( 20 ) << " -clockWise "
      << "Whether the object moves in CW or CCW direction \n"
      << std::setw( 32 ) << " " << "1 = CW (default)\n"

      << std::setw( 20 ) << " -increment "
      << "Increment that the publisher will advance by in seconds\n"
      << std::setw( 32 ) << " " << "modified by multiplier\n"

      << std::setw( 20 ) << " -multiplier "
      << "Multiplier for both advancement upon the extent\n"
      << std::setw( 32 ) << " " << "and lookahead on the extent\n"

      << std::setw( 20 ) << " -wait "
      << "Time interval (in milliseconds) to wait inbetween each update cycle.\n"

      << std::setw( 20 ) << " -range "
      << "Lookahead multiplier that the listening range  \n"
      << std::setw( 32 ) << " " << "will subscribe to\n"

      << std::setw( 20 ) << " -sendRangeTolerance "
      << " Describes a percentage of the sending range,  \n"
      << std::setw( 32 ) << " " << "how close the sender can get to the \n"
      << std::setw( 32 ) << " " << "extents of the sending range before \n"
      << std::setw( 32 ) << " " << "the Lower and Upper Bound of the \n"
      << std::setw( 32 ) << " " << "sender are re-sent\n"

      << std::setw( 20 ) << " -timeZone"
      << " Sets the UTC zone of the publisher  \n"
      << std::setw( 32 ) << " " << "Acceptable Values are from 0 .. 23 \n"
      << std::setw( 32 ) << " " << " Default value is 0, representing GMT\n"

      << std::setw( 20 ) << " -printUpdate "
      << "When GUI is disabled, prints a dot for each update to better\n"
      << std::setw( 32 ) << " " << "distinguish bounds changes\n"


      << "\nDisplay Options \n"
      << std::setw( 20 ) << " -displayRegion "
      << "Whether or not there is distinction in shading \n"
      << std::setw( 32 ) << " " << "in extent of a region and the entire \n"
      << std::setw( 32 ) << " " << "dimension (0 || 1)\n"

#ifdef SIMPLEDDMGUI
      << std::setw( 20 ) << " -useGUI "
      << "Whether the application should run in GUI or \n"
      << std::setw( 32 ) << " " << "console mode. \n"
#endif
      << std::endl;

   return ostr.str();
}

#endif




Document ID: Generated on Thu Jun 14 14:15:04 EDT 2012 from SVN revision 116116
Copyright © 2005-2012 VT MÄK Inc. All Rights Reserved (www.mak.com)