![]() |
MAK RTIspy API Documentation for HLA 1516
|
simpleDDMSimple13.cxx and simpleDDMFedAmb13.cxx (simpleDDMFedAmb13.h) have the RTI calls and federate ambassador calls for the HLA 1.3 version of simpleDDM.
This page has the code for the following files:
/****************************************************************************** ** Copyright (c) 2006 MaK Technologies, Inc. ** All rights reserved. ******************************************************************************/ /****************************************************************************** ** $RCSfile: simpleDDMSimple13.cxx,v $ $Revision: 1.3 $ $State: Exp $ ******************************************************************************/ #ifdef DtHLA13 #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 "simpleDDMSimple13.h" #include <cstdlib> using namespace std; const unsigned int simpleDDMFederate13::myNumAttributes = 1; const unsigned long simpleDDMFederate13::myNumExtents = 1; simpleDDMFederate13::simpleDDMFederate13() : simpleDDMFederate(), myNumberOfDimensions(myNumExtents), myHourlyInteraction("hourlyChime"), myQuarterlyInteraction("quarterlyChime"), mySecondsDimensionName("seconds"), myUTCDimensionName("UTCn"), mySpaceName("WallClock"), myInterClassName("Chimes"), myClassName("BaseEntity"), myAttrName("clockPosition"), myRTIamb(0), myFedAmb(0) { myFederationName = "MAKsimpleDDM"; myFederationFile = "MAKsimpleDDM.fed"; myFederateType = "rtisimple13"; } simpleDDMFederate13::simpleDDMFederate13(simpleDDMFederate13& data) : simpleDDMFederate(data), myNumberOfDimensions(data.myNumberOfDimensions), myHourlyInteraction(data.myHourlyInteraction), myQuarterlyInteraction(data.myQuarterlyInteraction), mySecondsDimensionName(data.mySecondsDimensionName), myUTCDimensionName(data.myUTCDimensionName), myInterClassName(data.myInterClassName), myClassName(data.myClassName), myAttrName(data.myAttrName) { } simpleDDMFederate13::~simpleDDMFederate13() { if(myRTIamb) { delete myRTIamb; } if(myFedAmb) { delete myFedAmb; } } void simpleDDMFederate13::initializeRTI() { vector< string > args; myAttrHandlesArray = new RTI::AttributeHandle[myNumAttributes]; // rti1516 and Federate Ambassadors myRTIamb = new RTI::RTIambassador(); myFedAmb = new MyFederateAmbassador(myAmbData); // Construct an attribute handle set myAttrHandlesSet = RTI::AttributeHandleSetFactory::create(myNumAttributes); } // Create the federation execution bool simpleDDMFederate13::createFedEx() { cout << "createFederationExecution " << myFederationName << " " << myFederationFile << endl; try { myRTIamb->createFederationExecution(myFederationName.c_str(), myFederationFile.c_str()); } catch(RTI::FederationExecutionAlreadyExists& ex) { cout << "Could not create Federation Execution: " << "FederationExecutionAlreadyExists: " << ex._name << " " << ex._reason << endl; return false; } catch(RTI::Exception& ex) { cout << "Could not create Federation Execution: " << endl << "RTI Exception: " << ex._name << " " << ex._reason << endl; exit(0); } myRTIamb->tick(0.1, 0.2); cout << "Federation Created" << endl; return true; } // Join the federation execution bool simpleDDMFederate13::joinFedEx() { bool joined=false; const int maxTry = 10; int numTries = 0; cout << "joinFederationExecution " << myFederateType.c_str() << " " << myFederationName.c_str() << endl; while (!joined && numTries++ < maxTry) { try { myRTIamb->joinFederationExecution(myFederateType.c_str(), myFederationName.c_str(), myFedAmb); joined = true; } catch(RTI::FederationExecutionDoesNotExist) { cout << "FederationExecutionDoesNotExist, try " << numTries << "out of " << maxTry << endl; continue; } catch(RTI::Exception& ex) { cout << "RTI Exception: " << ex._name << " " << ex._reason << endl; return false; } myRTIamb->tick(0.1, 0.2); } if (joined) cout << "Joined Federation." << endl; else { cout << "Giving up." << endl; myRTIamb->destroyFederationExecution(myFederationName.c_str()); exit(0); } return true; } // Resign and destroy the federation execution void simpleDDMFederate13::resignAndDestroy() { myRegionValid = false; myRTIamb->resignFederationExecution(RTI::DELETE_OBJECTS); myRTIamb->destroyFederationExecution(myFederationName.c_str()); } // Create the Region and initialize its bounds bool simpleDDMFederate13::createAndInitializeRegions() { // The space handle (to be retrieved from the RTI). RTI::SpaceHandle theSpaceHandle = 0; try { // Get the space and dimension handles theSpaceHandle = myRTIamb->getRoutingSpaceHandle( mySpaceName.c_str() ); mySecondsDimHandle = myRTIamb->getDimensionHandle( mySecondsDimensionName.c_str(), theSpaceHandle ); myUTCDimHandle = myRTIamb->getDimensionHandle( myUTCDimensionName.c_str(), theSpaceHandle ); } catch (RTI::Exception& ex) { cout << "RTI Exception: " << ex._name << " " << ex._reason << endl << "Could not " << " get SpaceHandle or DimensionHandle " << endl; return false; } try { // Create the region if ( myIsPublisher ) { mySendRegion = myRTIamb->createRegion(theSpaceHandle, myNumberOfDimensions ); } else { myListenRegion = myRTIamb->createRegion(theSpaceHandle, myNumberOfDimensions); } } catch (RTI::Exception& ex) { cout << "RTI Exception: " << ex._name << " " << ex._reason << endl << "Could not " << " create Region" << endl; return false; } if (myIsPublisher) { // Set the range bounds for a publisher mySendRegion->setRangeLowerBound(0,myUTCDimHandle, myUTCZone); mySendRegion->setRangeUpperBound(0,myUTCDimHandle, myUTCZone); mySendRegion->setRangeLowerBound(0,mySecondsDimHandle,mySendLowerBound); mySendRegion->setRangeUpperBound(0,mySecondsDimHandle,mySendUpperBound); try { myRTIamb->notifyAboutRegionModification(*mySendRegion); myAmbData.lowerSend = mySendLowerBound; myAmbData.upperSend = mySendUpperBound; } catch (RTI::Exception& ex) { cout << "RTI Exception: " << ex._name << " " << ex._reason << endl << "Could not " << " notify about region mods" << endl; return false; } } else { // Set the range bounds for a subscriber myListenRegion->setRangeLowerBound(0, myUTCDimHandle, myUTCZone); myListenRegion->setRangeUpperBound(0, myUTCDimHandle, myUTCZone); myListenRegion->setRangeLowerBound(0, mySecondsDimHandle, myListenLowerBound); myListenRegion->setRangeUpperBound(0, mySecondsDimHandle, myListenUpperBound); try { myRTIamb->notifyAboutRegionModification(*myListenRegion); myAmbData.lowerListen = myListenLowerBound; myAmbData.upperListen = myListenUpperBound; } catch (RTI::Exception& ex) { cout << "RTI Exception: " << ex._name << " " << ex._reason << endl << "Could not " << " notify about region mods" << endl; return false; } } myRegionValid = true; return true; } // Publish and subscribe the object class attributes. // Register an object instance of the class. bool simpleDDMFederate13::publishSubscribeAndRegisterObject() { try { // Get the object class handle myClassHandle = myRTIamb->getObjectClassHandle(myClassName.c_str()); myAmbData.objectClassMap[myClassHandle] = myClassName; } catch (RTI::Exception& ex) { cout << "RTI Exception: " << ex._name << " " << ex._reason << endl << "Could not get object class handle: " << myClassName.c_str() << endl; return false; } try { // Get the attribute handles and construct the name-handle map. // A handle array is used in anticipation of using it in region association myAmbData.myPositionHandle = myAttrHandlesArray[0] = myRTIamb->getAttributeHandle(myAttrName.c_str(), myClassHandle); myAttrNameHandleMap.insert(make_pair(myAttrName, myAttrHandlesArray[0])); myAttrHandlesSet->add(myAttrHandlesArray[0]); } catch (RTI::Exception& ex) { cout << "RTI Exception: " << ex._name << " " << ex._reason << endl << "Could not get attribute handle " << myAttrName.c_str() << endl; return false; } // Initialize attribute handle Value Map. string initialPosition("0"); myAttrValues = RTI::AttributeSetFactory::create(myAttrNameHandleMap.size()); myAttrValues->add(myAttrHandlesArray[0], initialPosition.c_str(), initialPosition.length() + 1); myMapsInitialized = true; // Initialize the Region if ( !createAndInitializeRegions() ) { return false; } try { // Publish or subscribe if (myIsPublisher) { myRTIamb->publishObjectClass(myClassHandle, *myAttrHandlesSet); } else { myRTIamb->subscribeObjectClassAttributesWithRegion(myClassHandle, *myListenRegion, *myAttrHandlesSet); cout << "Subscribed to object: " << myClassName.c_str() << " With region: [" << myListenRegion->getRangeLowerBound(0, mySecondsDimHandle) << " , " << myListenRegion->getRangeUpperBound(0, mySecondsDimHandle) << ") in Time Zone " << myListenRegion->getRangeUpperBound(0, myUTCDimHandle) << endl; } myRTIamb->tick(0.1, 0.2); } catch(RTI::Exception& ex) { cout << "RTI Exception: " << ex._name << " " << ex._reason << endl; cout << "Could not " << (myIsPublisher ? L"publish" : L"subscribe") << endl; return false; } if (myIsPublisher) { const RTI::ULong numHandle = 5; RTI::Region* theRegions[numHandle]; string objectName("UTC_publisher_"); stringstream zoneID; theRegions[0] = mySendRegion; zoneID << myUTCZone; objectName += zoneID.str(); // register object instance try { #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 possible to associate an attribute with multiple regions // by invoking associateRegionsForUpdates for multiple times // i.e., these region associations are additive not substitutive. myObjectHandle = myRTIamb->registerObjectInstance(myClassHandle, objectName.c_str()); myRTIamb->associateRegionForUpdates( *mySendRegion, myObjectHandle, *myAttrHandlesSet); #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. // It is possible to pair the same attribute with multiple // regions by repeating it in the attribute array. myObjectHandle = myRTIamb->registerObjectInstanceWithRegion( myClassHandle, objectName.c_str(), myAttrHandlesArray, theRegions, 1); // Add object name-handle to map myAmbData.objectInstanceMap[myObjectHandle] = objectName; myRTIamb->tick(0.1, 0.2); } catch(RTI::Exception& ex) { cout << "RTI Exception: " << ex._name << " " << ex._reason << endl << "Could not Register Object " << " with class " << myClassName.c_str() << endl; return false; } cout << "Registered object " << " with class name " << myClassName.c_str() << endl; } return true; } // Publish and Subscribe to an interaction class bool simpleDDMFederate13::publishAndSubscribeInteraction() { try { // Get the interaction class handle myInterClassHandle = myRTIamb->getInteractionClassHandle(myInterClassName.c_str()); myAmbData.interactionClassMap[myInterClassHandle] = myInterClassName; } catch (RTI::Exception& ex) { cout << "RTI Exception: " << ex._name << " " << ex._reason << endl << "Could not get interaction class handle: " << myInterClassName.c_str() << endl; return false; } string paramName; try { // Get the parameter handles and construct the name-handle map myHourlyHandle = myRTIamb->getParameterHandle(myHourlyInteraction.c_str(), myInterClassHandle); myParamNameHandleMap[myHourlyInteraction] = myHourlyHandle; myQuarterlyHandle = myRTIamb->getParameterHandle(myQuarterlyInteraction.c_str(), myInterClassHandle); myParamNameHandleMap[myQuarterlyInteraction] = myQuarterlyHandle; // Construct a parameter handle value pair set with the // values containing the parameter names myParamValues = RTI::ParameterSetFactory::create(myParamNameHandleMap.size()); } catch (RTI::Exception& ex) { cout << "RTI Exception: " << ex._name << " " << ex._reason << endl << "Could not get parameter handle " << paramName.c_str() << endl; return false; } try { // Publish and subscribe if ( myIsPublisher ) { myRTIamb->publishInteractionClass(myInterClassHandle); myRTIamb->tick(0.1, 0.2); } else { myRTIamb->subscribeInteractionClassWithRegion(myInterClassHandle, *myListenRegion); myRTIamb->tick(0.1, 0.2); } } catch (RTI::Exception& ex) { cout << "RTI Exception: " << ex._name << " " << ex._reason << endl << "Could not " << (myIsPublisher ? "publish" : "subscribe") << " to interaction." << endl; return false; } if (!myIsPublisher) { cout << "Subscribed to interaction class: " << myInterClassName.c_str() << " with handle: " << myInterClassHandle << endl; } return true; } void simpleDDMFederate13::sendUpdate( int currentPosition ) { stringstream ss; ss << "13-" << myUpdateCount++; string tagForThisUpdate(ss.str()); // myAttrHandleMap contains AttributeHandles indexed by attributeNames // attrValues contains values indexed by attributeHandles myAttrValues->remove(myAttrHandlesArray[0]); myAttrValues->add(myAttrHandlesArray[0], tagForThisUpdate.c_str(), tagForThisUpdate.length()); setPosition(currentPosition); try { myRTIamb->updateAttributeValues(myObjectHandle, *myAttrValues, tagForThisUpdate.c_str()); } catch (RTI::Exception& ex) { cout << "Caught Exception in update Attribute values\n" << ex._name << " " << ex._reason << endl; } } // Parameter values will be constructed when the sender generates an // interaction and emptied after the interaction is sent. void simpleDDMFederate13::sendInteraction_hourly() { DtParamNameHandleMap::const_iterator iterAtHour = myParamNameHandleMap.find(myHourlyInteraction); stringstream ss; ss << "13-" << myUpdateCount++; string tagForThisUpdate(ss.str()); try { myParamValues->add(iterAtHour->second, iterAtHour->first.c_str(), iterAtHour->first.length() + 1); myRTIamb->sendInteractionWithRegion(myInterClassHandle, *myParamValues, tagForThisUpdate.c_str(), *mySendRegion); } catch (RTI::Exception& ex) { cout << "Caught Exception in send Interaction with Regions\n" << ex._name << " " << ex._reason << endl; } myParamValues->remove(iterAtHour->second); } void simpleDDMFederate13::sendInteraction_quarterly() { DtParamNameHandleMap::const_iterator iterAtQuarter = myParamNameHandleMap.find(myQuarterlyInteraction); stringstream ss; ss << "13-" << myUpdateCount++; string tagForThisUpdate(ss.str()); try { myParamValues->add(iterAtQuarter->second, iterAtQuarter->first.c_str(), iterAtQuarter->first.length() + 1); myRTIamb->sendInteractionWithRegion(myInterClassHandle, *myParamValues, tagForThisUpdate.c_str(), *mySendRegion ); } catch (RTI::Exception& ex) { cout << "Caught Exception in send Interaction with Regions\n" << ex._name << " " << ex._reason << endl; } myParamValues->remove(iterAtQuarter->second); } void simpleDDMFederate13::changeBounds(int lowerSeconds, int upperSeconds, int newUTC) { if ( !myRegionValid ) { // Region has not be created yet, just set up the bounds myUTCZone = newUTC; if (myIsPublisher) { mySendLowerBound = lowerSeconds; mySendUpperBound = upperSeconds; } else { myListenLowerBound = lowerSeconds; myListenUpperBound = upperSeconds; } } else if (myIsPublisher) { try { // Set the values in the region mySendRegion->setRangeUpperBound(0, myUTCDimHandle, newUTC + 1); mySendRegion->setRangeLowerBound(0, myUTCDimHandle, newUTC); mySendRegion->setRangeUpperBound(0, mySecondsDimHandle, upperSeconds); mySendRegion->setRangeLowerBound(0, mySecondsDimHandle, lowerSeconds); // Commit the changes myRTIamb->notifyAboutRegionModification(*mySendRegion); // Commit was successful, get the ranges back myUTCZone = mySendRegion->getRangeLowerBound(0, myUTCDimHandle); mySendLowerBound = mySendRegion->getRangeLowerBound(0, mySecondsDimHandle); mySendUpperBound = mySendRegion->getRangeUpperBound(0, mySecondsDimHandle); myAmbData.lowerSend = mySendLowerBound; myAmbData.upperSend = mySendUpperBound; } catch (RTI::Exception& ex) { cout << "Caught Exception when changing bounds\n" << ex._name << " " << ex._reason << " " << endl; } } else { try { // Set the values in the region myListenRegion->setRangeUpperBound(0, myUTCDimHandle, newUTC + 1); myListenRegion->setRangeLowerBound(0, myUTCDimHandle, newUTC); myListenRegion->setRangeLowerBound(0, mySecondsDimHandle, lowerSeconds); myListenRegion->setRangeUpperBound(0, mySecondsDimHandle, upperSeconds); // Commit the changes myRTIamb->notifyAboutRegionModification(*myListenRegion); // Commit was successful, get the ranges back myUTCZone = myListenRegion->getRangeLowerBound(0, myUTCDimHandle); myListenUpperBound = myListenRegion->getRangeUpperBound(0, mySecondsDimHandle); myListenLowerBound = myListenRegion->getRangeLowerBound(0, mySecondsDimHandle); myAmbData.lowerListen = myListenLowerBound; myAmbData.upperListen = myListenUpperBound; } catch (RTI::Exception& ex) { cout << "Caught Exception\n" << ex._name << " " << ex._reason << " " << endl; } } } void simpleDDMFederate13::tick(double atMost) { try { myRTIamb->tick(); } catch(RTI::Exception& ex) { cout << "rti13 Exception (during tick): " << ex._name << " " << ex._reason << endl; } } void simpleDDMFederate13::tick(double atLeast, double atMost) { try { myRTIamb->tick(atLeast, atMost); } catch(RTI::Exception& ex) { cout << "rti13 Exception (during tick): " << ex._name << " " << ex._reason << endl; } } void simpleDDMFederate13::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. string pos_string; ostringstream oss ; oss << pos; pos_string = oss.str(); myAttrValues->remove(myAttrNameHandleMap[myAttrName]); myAttrValues->add(myAttrNameHandleMap[myAttrName], pos_string.c_str(), pos_string.length() + 1); } else { cout << "You must initialize the maps before calling this function."; } } #endif
/****************************************************************************** ** Copyright (c) 2006 MaK Technologies, Inc. ** All rights reserved. ******************************************************************************/ /****************************************************************************** ** $RCSfile: simpleDDMFedAmb13.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 <cstdlib> #include "simpleDDMFedAmb13.h" #include "simpleDDMStringUtil.h" using namespace std; void printAttributes(const RTI::AttributeHandleValuePairSet& attributes, const DtTalkAmbData& data) { for (unsigned int iloop = 0; iloop < attributes.size(); iloop++) { RTI::ULong length = attributes.getValueLength(iloop); cout << attributes.getHandle(iloop) << " " << attributes.getValuePointer(iloop,length) << endl; } } void printParameters(const RTI::ParameterHandleValuePairSet& params) { for (unsigned int iloop = 0; iloop < params.size(); iloop++) { RTI::ULong length = params.getValueLength(iloop); cout << params.getHandle(iloop) << " " << params.getValuePointer(iloop,length) << endl; } } std::string timeToString(RTI::FedTime const& time) { char* buff = new char[time.getPrintableLength()+1]; ((RTI::FedTime &)time).getPrintableString(buff); std::string timeStr(buff); delete [] buff; return timeStr; } MyFederateAmbassador::MyFederateAmbassador(DtTalkAmbData & data) : NullFederateAmbassador(), myData(data) { } MyFederateAmbassador::~MyFederateAmbassador() throw (RTI::FederateInternalError) { } void MyFederateAmbassador::discoverObjectInstance ( RTI::ObjectHandle theObject, RTI::ObjectClassHandle theObjectClass, const char* theObjectName) throw ( RTI::CouldNotDiscover, RTI::ObjectClassNotKnown, RTI::FederateInternalError) { cout << "discoverObjectInstance: " << theObjectName << "(" << theObject << ") of class " << myData.objectClassMap[theObjectClass].c_str() << "( " << theObjectClass << ")" << endl; // Map the handle to the name myData.objectInstanceMap[theObject] = theObjectName; } void MyFederateAmbassador::reflectAttributeValues ( RTI::ObjectHandle theObject, const RTI::AttributeHandleValuePairSet& theAttributes, const RTI::FedTime& theTime, const char *theTag, RTI::EventRetractionHandle theHandle) throw ( RTI::ObjectNotKnown, RTI::AttributeNotKnown, RTI::FederateOwnsAttributes, RTI::InvalidFederationTime, RTI::FederateInternalError) { reflectAttributeValues (theObject, theAttributes, theTag); } void MyFederateAmbassador::reflectAttributeValues ( RTI::ObjectHandle theObject, const RTI::AttributeHandleValuePairSet& theAttributes, const char *theTag) throw ( RTI::ObjectNotKnown, RTI::AttributeNotKnown, RTI::FederateOwnsAttributes, RTI::FederateInternalError) { RTI::ULong length = theAttributes.getValueLength(0); char* dataPointer = theAttributes.getValuePointer(0,length); bool havePosition = false; for (unsigned int iloop = 0; !havePosition && iloop < theAttributes.size(); iloop++) { RTI::AttributeHandle handle = theAttributes.getHandle(iloop); if (handle == myData.myPositionHandle && theAttributes.getValueLength(iloop) > 0) { // Position is in the reflected attributes and it contains data // The data is a numeric string representation of the position myData.position = atoi(theAttributes.getValuePointer(iloop, length)); havePosition = true; } } if (!havePosition) { cout << "Received reflect with no or NULL position\n"; } else { 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"; } } // 4.6 void MyFederateAmbassador::receiveInteraction ( RTI::InteractionClassHandle theInteraction, const RTI::ParameterHandleValuePairSet& theParameters, const RTI::FedTime& theTime, const char *theTag, RTI::EventRetractionHandle theHandle) throw ( RTI::InteractionClassNotKnown, RTI::InteractionParameterNotKnown, RTI::InvalidFederationTime, RTI::FederateInternalError) { cout << "receiveInteraction: " << myData.interactionClassMap[theInteraction].c_str() << "( " << theInteraction << ") " << timeToString(theTime).c_str() << " " << (theTag ? theTag : "") << " " << "#parameters: " << theParameters.size() << endl; printParameters(theParameters); } void MyFederateAmbassador::receiveInteraction ( RTI::InteractionClassHandle theInteraction, const RTI::ParameterHandleValuePairSet& theParameters, const char *theTag) throw ( RTI::InteractionClassNotKnown, RTI::InteractionParameterNotKnown, RTI::FederateInternalError) { cout << "receiveInteraction: " << myData.interactionClassMap[theInteraction].c_str() << "( " << theInteraction << ") " << (theTag ? theTag : "") << " " << "#parameters: " << theParameters.size() << endl; printParameters(theParameters); } void MyFederateAmbassador::removeObjectInstance ( RTI::ObjectHandle theObject, const RTI::FedTime& theTime, const char *theTag, RTI::EventRetractionHandle theHandle) throw ( RTI::ObjectNotKnown, RTI::InvalidFederationTime, RTI::FederateInternalError) { cout << "removeObjectInstance: " << myData.objectInstanceMap[theObject].c_str() << "(" << theObject << ") " << timeToString(theTime).c_str() << " " << (theTag ? theTag : "") << endl; } void MyFederateAmbassador::removeObjectInstance ( RTI::ObjectHandle theObject, const char *theTag) throw ( RTI::ObjectNotKnown, RTI::FederateInternalError) { cout << "removeObjectInstance: " << myData.objectInstanceMap[theObject].c_str() << "(" << theObject << ") " << (theTag ? theTag : "") << endl; } void MyFederateAmbassador::attributesInScope ( RTI::ObjectHandle theObject, const RTI::AttributeHandleSet& theAttributes) throw ( RTI::ObjectNotKnown, RTI::AttributeNotKnown, RTI::FederateInternalError) { if ( myData.enableScopeAdvisories ) { cout<< "********************************\n" << "****Attributes entering scope***\n" << "********************************\n"; } } void MyFederateAmbassador::attributesOutOfScope ( RTI::ObjectHandle theObject, const RTI::AttributeHandleSet& theAttributes) throw ( RTI::ObjectNotKnown, RTI::AttributeNotKnown, RTI::FederateInternalError) { if ( myData.enableScopeAdvisories ) { cout<< "********************************\n" << "****Attributes exiting scope****\n" << "********************************\n"; } }
/**************************************************************************** ** ** 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
/****************************************************************************** ** 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
/****************************************************************************** ** 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() { }
/****************************************************************************** * 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; }
/****************************************************************************** ** 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; }
/**************************************************************************** ** ** 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
/****************************************************************************** ** 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_
/****************************************************************************** ** Copyright (c) 2006 MaK Technologies, Inc. ** All rights reserved. ******************************************************************************/ /****************************************************************************** ** $RCSfile: simpleDDMFedAmb13.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 "NullFederateAmbassador.hh" #include <map> #include <string> // Data exchanged between federate and Federate Ambassador class DtTalkAmbData { public: std::map<RTI::ObjectClassHandle, std::string> objectClassMap; std::map<RTI::ObjectHandle, std::string> objectInstanceMap; std::map<RTI::InteractionClassHandle, std::string> interactionClassMap; RTI::AttributeHandle myPositionHandle; int position; int lowerListen; int upperListen; int lowerSend; int upperSend; bool enableScopeAdvisories; bool isPublisher; }; class MyFederateAmbassador : public NullFederateAmbassador { public: MyFederateAmbassador(DtTalkAmbData & data); virtual ~MyFederateAmbassador() throw (RTI::FederateInternalError); // Object Management Services // virtual void discoverObjectInstance ( RTI::ObjectHandle theObject, // supplied C1 RTI::ObjectClassHandle theObjectClass, // supplied C1 const char* theObjectName) // supplied C4 throw ( RTI::CouldNotDiscover, RTI::ObjectClassNotKnown, RTI::FederateInternalError); virtual void reflectAttributeValues ( RTI::ObjectHandle theObject, // supplied C1 const RTI::AttributeHandleValuePairSet& theAttributes, // supplied C4 const RTI::FedTime& theTime, // supplied C1 const char *theTag, // supplied C4 RTI::EventRetractionHandle theHandle) // supplied C1 throw ( RTI::ObjectNotKnown, RTI::AttributeNotKnown, RTI::FederateOwnsAttributes, RTI::InvalidFederationTime, RTI::FederateInternalError); virtual void reflectAttributeValues ( RTI::ObjectHandle theObject, // supplied C1 const RTI::AttributeHandleValuePairSet& theAttributes, // supplied C4 const char *theTag) // supplied C4 throw ( RTI::ObjectNotKnown, RTI::AttributeNotKnown, RTI::FederateOwnsAttributes, RTI::FederateInternalError); // 4.6 virtual void receiveInteraction ( RTI::InteractionClassHandle theInteraction, // supplied C1 const RTI::ParameterHandleValuePairSet& theParameters, // supplied C4 const RTI::FedTime& theTime, // supplied C4 const char *theTag, // supplied C4 RTI::EventRetractionHandle theHandle) // supplied C1 throw ( RTI::InteractionClassNotKnown, RTI::InteractionParameterNotKnown, RTI::InvalidFederationTime, RTI::FederateInternalError); virtual void receiveInteraction ( RTI::InteractionClassHandle theInteraction, // supplied C1 const RTI::ParameterHandleValuePairSet& theParameters, // supplied C4 const char *theTag) // supplied C4 throw ( RTI::InteractionClassNotKnown, RTI::InteractionParameterNotKnown, RTI::FederateInternalError); virtual void removeObjectInstance ( RTI::ObjectHandle theObject, // supplied C1 const RTI::FedTime& theTime, // supplied C4 const char *theTag, // supplied C4 RTI::EventRetractionHandle theHandle) // supplied C1 throw ( RTI::ObjectNotKnown, RTI::InvalidFederationTime, RTI::FederateInternalError); virtual void removeObjectInstance ( RTI::ObjectHandle theObject, // supplied C1 const char *theTag) // supplied C4 throw ( RTI::ObjectNotKnown, RTI::FederateInternalError); virtual void attributesInScope ( RTI::ObjectHandle theObject, // supplied C1 const RTI::AttributeHandleSet& theAttributes) // supplied C4 throw ( RTI::ObjectNotKnown, RTI::AttributeNotKnown, RTI::FederateInternalError) ; virtual void attributesOutOfScope ( RTI::ObjectHandle theObject, // supplied C1 const RTI::AttributeHandleSet& theAttributes) // supplied C4 throw ( RTI::ObjectNotKnown, RTI::AttributeNotKnown, RTI::FederateInternalError) ; public: DtTalkAmbData & myData; }; #endif
/****************************************************************************** ** 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
/****************************************************************************** * 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
/****************************************************************************** ** Copyright (c) 2006 MaK Technologies, Inc. ** All rights reserved. ******************************************************************************/ /****************************************************************************** ** $RCSfile: simpleDDMSimple13.h,v $ $Revision: 1.2 $ $State: Exp $ ******************************************************************************/ #ifndef REGIONEXAMPLE13_H_ #define REGIONEXAMPLE13_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 "simpleDDMFederate.h" #include <string.h> #include "RTI.hh" #include "simpleDDMFedAmb13.h" // Map between strings and attribute handles typedef std::map<std::string, RTI::AttributeHandle> DtAttrNameHandleMap; // Map between strings and parameter handles typedef std::map<std::string, RTI::ParameterHandle> DtParamNameHandleMap; class simpleDDMFederate13 : public simpleDDMFederate { public: // Default Constructor simpleDDMFederate13(); // Constructor simpleDDMFederate13(simpleDDMFederate13& data); // Destructor ~simpleDDMFederate13(); // 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 char* newFedName); // Set the Fed File Name void setFedFileName(const wchar_t* 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; static const unsigned int myNumAttributes; static const unsigned long myNumExtents; // Array of attributeHandles. RTI::AttributeHandle* myAttrHandlesArray; RTI::AttributeHandleSet* myAttrHandlesSet; RTI::AttributeHandleValuePairSet *myAttrValues; // Data shared between federate and federate ambassador DtTalkAmbData myAmbData; private: // Federate and Federation info std::string myFederationName; std::string myFederationFile; std::string myFederateType; // An interaction published at {1, 2, 4, 5, 7, 8, 10 , 11} std::string myHourlyInteraction; // An interaction published at {3,6,9,12} std::string myQuarterlyInteraction; // The interaction class name std::string myInterClassName; // The object class name std::string myClassName; // The attribute name std::string myAttrName; // The number of dimensions unsigned int myNumberOfDimensions; // The RTI Ambassador RTI::RTIambassador* myRTIamb; // The Federate Ambassador MyFederateAmbassador* myFedAmb; // the Handle for the hourlyInteraction, (to be retrieved from RTI). RTI::ParameterHandle myHourlyHandle; // the Handle for the quarterlyInteraction, (to be retrieved from RTI). RTI::ParameterHandle myQuarterlyHandle; // Construct a parameter handle value pair set with the // values containing the parameter names RTI::ParameterHandleValuePairSet* myParamValues; // The name of the dimension is specified in your FED file. std::string mySecondsDimensionName; // The time zone dimension name std::string myUTCDimensionName; // The routing space name std::string mySpaceName; // The object class handle (to be retrieved from RTI). RTI::ObjectClassHandle myClassHandle; //The object instance handle ( to be retrieved from the rti). RTI::ObjectHandle myObjectHandle; // The interaction class handle (to be retrieved from RTI). RTI::InteractionClassHandle myInterClassHandle; // The Seconds dimension handle (to be retrieved from the RTI). RTI::DimensionHandle mySecondsDimHandle; // The UTC dimension handle (to be retrieved from the RTI). RTI::DimensionHandle myUTCDimHandle; // The listen region RTI::Region* myListenRegion; // The publish region RTI::Region* mySendRegion; }; inline void simpleDDMFederate13::setIsPublisher(bool yesNo) { myIsPublisher = yesNo; myAmbData.isPublisher = yesNo; } inline void simpleDDMFederate13::setEnableScopeAdvisories(bool yesNo) { myEnableScopeAdvisories = yesNo; myAmbData.enableScopeAdvisories = yesNo; } inline int simpleDDMFederate13::position() { if (!isPublisher()) myCurrentposition = myAmbData.position; return myCurrentposition; } inline void simpleDDMFederate13::setFedFileName(const char* newFedName) { myFederationFile = std::string(newFedName); } inline void simpleDDMFederate13::setFedFileName(const wchar_t* newFedName) { myFederationFile = DtToString(std::wstring(newFedName)); } inline char* simpleDDMFederate13::getFedFileName() const { return strdup(myFederationFile.c_str()); } #endif
/****************************************************************************** ** 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