![]() |
MAK RTIspy API Documentation for HLA 1.3
|
simpleTime1516.cxx and simpleTimeFedAmb1516.cxx (simpleTimeFedAmb1516.h) have the RTI calls and federate ambassador calls for the HLA 1516 version of rtisimple.
This page has the code for the following files:
/******************************************************************************* ** Copyright (c) 2004 MaK Technologies, Inc. ** All rights reserved. *******************************************************************************/ /******************************************************************************* ** $RCSfile: simpleTime1516.cxx,v $ $Revision: 1.5 $ $State: Exp $ *******************************************************************************/ // A simple federate that updates an object with attributes whose values // are the name of the attribute. Objects from other simple federates // are discovered and reflected. The string values are byte encoded to allow // compatibility between 1.3 and 1516 #ifdef WIN32 #pragma warning(disable: 4251) #pragma warning(disable: 4786) #pragma warning(disable: 4290) #include <winsock2.h> #include <process.h> #else #include <unistd.h> #include <stdlib.h> #include <sched.h> #include <netdb.h> #endif #include <iostream> #include <wchar.h> #include <sstream> #include <string> #include <sstream> #include <iterator> #include <RTI/RTI1516.h> #include <RTI/RTIambassadorFactory.h> #include <RTI/logicalTimeFactoryImpl.h> #include <RTI/logicalTimeImpl.h> #include <RTI/logicalTimeIntervalImpl.h> #include "simpleTimeFedAmb1516.h" #include "simpleTimeKeyboard.h" using namespace std; using namespace rti1516; inline bool parseCmdLine( int argc, char* argv[] ); // Logical time factory implementation LogicalTimeFactoryImpl theTimeFactory; // Handles keyboard input without blocking keyboard input; // Data shared between federate and federate ambassador DtTalkAmbData theAmbData; // The object class name std::wstring theClassName = L"BaseEntity"; // The interaction class name string fireInteractionName = "WeaponFire"; string detonateInteractionName = "MunitionDetonation"; // The object class handle (to be retrieved from RTI). ObjectClassHandle theClassHandle; // The interaction class handles (to be retrieved from RTI). InteractionClassHandle fireInteractionHandle; InteractionClassHandle detonateInteractionHandle; // The object instance handle (to be retrieved from the RTI). ObjectInstanceHandle theObjectHandle; // This federation of simple objects has a single master object, (determined by command line arguments) // The master federate will keep the other federates from entering their main loop of execution until // all of numFederates have joined. bool Master(false); // numFederates is the number of federates (including the master) that the master should wait to join the // federation before it allows any federate to enter its main loop. // This variable is only used by the master federate. int numFederates(0); // dedicatedMachine indicates that this federate will be as greedy as possible with the processor. // this is helpful for users who have two federates on separate machines and want them to time-step // as quickly as possible. // If each federate is not on a dedicated machine, this may actually slow federates. bool dedicatedMachine(false); // unManaged Federate will allow you to see the operation of a time regulating and constrained federate // when the federate does not wait for the "begin" synchronization before executing. bool unManagedFederate(false); // sleepTime (indicated in milliseconds, defaults to 850ms), is the time that a federate will sleep between // iterations of the main loop. This value is invalidated if (above) dedicatedMachine is set. // 850 ms is selected to allow the user to see the time advances progressing at a very slow pace. // There is no need to set this to a value > 50ms or so other than allowing the user to watch the text scroll. int sleepTime(850); // the name of the fed file this federate will use. Can be overridden with cmd line parameter fedFile wstring fedFileName(L"MAKsimpletime.xml"); // the name of the federation we'll create. wstring federationName(L"MAKsimpletime"); // The name of the initialization synchronization point that the master and other federates use to establish a // synchronized starting point for the federation. wstring initSyncPointLabel(L"begin"); // Create the federation execution void createFedEx(RTIambassador* rtiAmb, std::wstring const& fedName, std::wstring const& fedFile) { std::cout << "createFederationExecution " << DtToString(fedName) << " " << DtToString(fedFile) << endl; try { rtiAmb->createFederationExecution(fedName, fedFile); rtiAmb->evokeMultipleCallbacks(0.1, 0.2); } catch(FederationExecutionAlreadyExists& ex) { std::cout << "Could not create Federation Execution: " << "FederationExecutionAlreadyExists: " << DtToString(ex.what()) << endl; } catch(rti1516::Exception& ex) { std::cout << "RTI Exception: " << DtToString(ex.what()) << endl << "Could not create Federation Execution: " << endl; exit(0); } std::cout << "Federation Created." << endl; } // Join the federation execution void joinFedEx( RTIambassador* rtiAmb, MyFederateAmbassador & fedAmb, std::wstring const& federateType, std::wstring const& federationName) { bool joined=false; const int maxTry = 10; int numTries = 0; std::cout << "joinFederationExecution " << DtToString(federateType) << " " << DtToString(federationName) << endl; while (!joined && numTries++ < maxTry) { try { rtiAmb->joinFederationExecution(federateType, federationName, fedAmb); joined = true; } catch(FederationExecutionDoesNotExist) { std::cout << "FederationExecutionDoesNotExist, try " << numTries << " out of " << maxTry << endl; continue; } catch(rti1516::Exception& ex) { std::cout << "RTI Exception: " << DtToString(ex.what()) << endl; return; } rtiAmb->evokeMultipleCallbacks(0.1, 0.2); } if (joined) std::cout << "Joined Federation." << endl; else { std::cout << "Giving up." << endl; rtiAmb->destroyFederationExecution(federationName); exit(0); } } // Resign and destroy the federation execution void resignAndDestroy( RTIambassador * rtiAmb) { rtiAmb->resignFederationExecution(rti1516::DELETE_OBJECTS); rtiAmb->destroyFederationExecution(federationName); } // Publish and subscribe the object class attributes. // Register an object instance of the class. bool publishSubscribeAndRegisterObject(RTIambassador* rtiAmb) { // Declare the attributes that we will be publishing. theAmbData.ourAttrs.insert(string("AccelerationVector")); theAmbData.ourAttrs.insert(string("DeadReckoningAlgorithm")); theAmbData.ourAttrs.insert(string("Orientation")); theAmbData.ourAttrs.insert(string("WorldLocation")); theAmbData.ourAttrs.insert(string("VelocityVector")); theAmbData.ourAttrs.insert(string("DamageState")); // Get the object class handle try { theClassHandle = rtiAmb->getObjectClassHandle(theClassName); theAmbData.objectClassMap[theClassHandle] = theClassName; } catch (rti1516::Exception& ex) { std::cout << "RTI Exception: " << DtToString(ex.what()) << endl; std::cout << "Could not get object class handle: " << DtToString(theClassName) << endl; return false; } // Get the attribute handles and construct the name-handle map and // attribute set std::wstring attrName; AttributeHandleSet hSet; theAmbData.attrValues = new AttributeHandleValueMap(); set<string>::iterator attributeSetIterator = theAmbData.ourAttrs.begin(); set<string>::iterator attributeSetEnd = theAmbData.ourAttrs.end(); string currentAttribute(""); AttributeHandle retrievedHandle; for( ; attributeSetIterator != attributeSetEnd; ++attributeSetIterator) { currentAttribute = *attributeSetIterator; try{ retrievedHandle = rtiAmb->getAttributeHandle(theClassHandle, DtToWString(currentAttribute.c_str())); } catch (rti1516::Exception& ex) { std::cout << "RTI Exception: " << DtToString(ex.what()) << endl; std::cout << "Could not get attribute handle " << DtToString(attrName.c_str()) << endl; return false; } //Populate theAttributeHandleSet. hSet.insert(retrievedHandle); //Populate the attributeHandleValueMap with the values // containing the attribute Names. // Attribute values will be just the name of the attribute. theAmbData.attrValues->insert( std::make_pair( retrievedHandle, VariableLengthData( currentAttribute.c_str(), currentAttribute.length() + 1))); theAmbData.theAttrNameHandleMap.insert( std::make_pair(DtToWString(currentAttribute.c_str()), retrievedHandle)); } // Publish and subscribe int cnt=0; try { rtiAmb->publishObjectClassAttributes(theClassHandle, hSet); rtiAmb->evokeMultipleCallbacks(0.1, 0.2); cnt=1; rtiAmb->subscribeObjectClassAttributes(theClassHandle, hSet); rtiAmb->evokeMultipleCallbacks(0.1, 0.2); } catch (rti1516::Exception& ex) { std::cout << "RTI Exception: " << DtToString(ex.what()) << endl; std::cout << "Could not " << (cnt ? "publish" : "subscribe") << endl; return false; } std::string objectName("Talk"); // Reserve object name and register the object instance try { unsigned int objId = abs(getpid()); std::stringstream pid; pid << objId; objectName += pid.str(); theAmbData.myNameReservationReturned = theAmbData.myNameReservationSucceeded = false; rtiAmb->reserveObjectInstanceName(DtToWString(objectName.c_str())); int count = 0; while (count++ < 100 && !theAmbData.myNameReservationReturned) { rtiAmb->evokeMultipleCallbacks(0.1, 0.2); } if (count < 100) { theObjectHandle = rtiAmb->registerObjectInstance(theClassHandle, DtToWString(objectName.c_str())); // Add name-handle to map theAmbData.objectInstanceMap[theObjectHandle] = DtToWString(objectName.c_str()); } else { std::cout << "Failed waiting for reserve object name " << objectName << endl; return false; } rtiAmb->evokeMultipleCallbacks(0.1, 0.2); } catch (rti1516::Exception& ex) { std::cout << "RTI Exception: " << DtToString(ex.what()) << endl; std::cout << "Could not Register Object " << objectName << " with class " << DtToString(theClassName.c_str()) << endl; return false; } std::cout << "Registered object " << objectName << " with class name " << DtToString(theClassName.c_str()) << endl; return true; } // Publish and Subscribe to an interaction class bool publishAndSubscribeInteraction(RTIambassador* rtiAmb) { theAmbData.ourParms.insert("EventIdentifier"); theAmbData.ourParms.insert("FiringLocation"); theAmbData.ourParms.insert("FiringObjectIdentifier"); theAmbData.ourParms.insert("MunitionObjectIdentifier"); theAmbData.ourParms.insert("TargetObjectIdentifier"); // Get the interaction class handle try { fireInteractionHandle = rtiAmb->getInteractionClassHandle( DtToWString(fireInteractionName.c_str())); theAmbData.interactionClassMap[fireInteractionHandle] = DtToWString(fireInteractionName.c_str()); detonateInteractionHandle = rtiAmb->getInteractionClassHandle( DtToWString(detonateInteractionName.c_str())); theAmbData.interactionClassMap[detonateInteractionHandle] = DtToWString(detonateInteractionName.c_str()); } catch (rti1516::Exception& ex) { std::cout << "RTI Exception: " << DtToString(ex.what()) << endl; std::cout << "Could not get interaction class handle: " << DtToString(theClassName.c_str()) << endl; return false; } // Construct a parameter handle value pair set with the // values containing the parameter names theAmbData.paramValues = new ParameterHandleValueMap(); // Get the parameter handles and construct the name-handle map. string paramName; set<string>::const_iterator parameterIter = theAmbData.ourParms.begin(); set<string>::const_iterator parameterEnd = theAmbData.ourParms.end(); ParameterHandle retrievedHandle; for( ; parameterIter != parameterEnd; ++parameterIter ) { paramName = *parameterIter; try { retrievedHandle = rtiAmb->getParameterHandle(fireInteractionHandle, DtToWString(paramName.c_str())); } catch (rti1516::Exception& ex) { std::cout << "RTI Exception: " << DtToString(ex.what()) << endl; std::cout << "Could not get parameter handle " << paramName << endl; return false; } //Parameter values will be just the name of the attibute. theAmbData.paramValues->insert(std::make_pair( retrievedHandle, VariableLengthData( paramName.c_str(), paramName.length() + 1 ))); theAmbData.theParamNameHandleMap.insert( std::make_pair(DtToWString(paramName.c_str()), retrievedHandle)); } // Publish and subscribe int cnt=0; try { rtiAmb->publishInteractionClass(fireInteractionHandle); rtiAmb->evokeMultipleCallbacks(0.1, 0.2); rtiAmb->publishInteractionClass(detonateInteractionHandle); rtiAmb->evokeMultipleCallbacks(0.1, 0.2); cnt=1; rtiAmb->subscribeInteractionClass(fireInteractionHandle); rtiAmb->evokeMultipleCallbacks(0.1, 0.2); rtiAmb->subscribeInteractionClass(detonateInteractionHandle); rtiAmb->evokeMultipleCallbacks(0.1, 0.2); } catch (rti1516::Exception& ex) { std::cout << "RTI Exception: " << DtToString(ex.what()) << endl; std::cout << "Could not " << (cnt ? "publish" : "subscribe") << " to interaction class." << endl; return false; } std::cout << "Subscribed to interaction class: " << fireInteractionName << " with handle: " << DtToString(fireInteractionHandle.toString()) << endl << " and interaction class " << detonateInteractionName << " with handle: " << DtToString(detonateInteractionHandle.toString()) << endl; return true; } // This function will exit the program after resigning the federation. void cleanUpProgram(RTIambassador* rtiAmb) { try { if ( theAmbData.isRegulating ) { rtiAmb->disableTimeRegulation(); } // Resign and destroy federation resignAndDestroy(rtiAmb); } catch (rti1516::Exception& ex) { std::cout << "RTI Exception (during exit): " << DtToString(ex.what()) << endl; } #ifdef WIN32 WSACleanup(); #endif exit(0); } // This is a simple function to output a FedTime object. // Helpful for debugging and general diagnostics. void printOutFedTime(LogicalTime* time) { std::cout << DtToString(time->toString()) ; } // This is a simple function to output a FedTimeInterval object. // Helpful for debugging and general diagnostics. void printOutFedTime(LogicalTimeInterval* time) { std::cout << DtToString(time->toString()) ; } // platform independent sleep function. void sleepFunction() { // On a dedicated machine we do not sleep, making this function a nop if ( ! dedicatedMachine ) { #ifdef WIN32 Sleep(sleepTime); #else usleep(sleepTime * 1000); #endif } } // platform independent sleep, for a predetermined small time. (10 ms) void minimalSleepFunction() { #ifdef WIN32 Sleep(10); #else usleep(10 * 1000); #endif } // simply yields the current thread independent of the platform void yieldFunction() { // On a dedicated machine we do not yield the processor, making this function a nop if ( ! dedicatedMachine ) { #ifdef _WIN32 Sleep( 0 ); #elif __solaris__ yield(); #else sched_yield(); #endif } } // This function causes the federate to become time constrained and regulating. // If the user presses q while the federate is waiting for the callback from the RTI // making it time constrained, the federate will quit. void becomeConstrainedAndRegulating(RTIambassador* rtiAmb, LogicalTime* currentTime, LogicalTimeInterval* lookAhead ) { try { rtiAmb->enableTimeRegulation((*lookAhead)); std::cout << "Waiting to become Time Regulating " << endl; while ( ! theAmbData.isRegulating ) { rtiAmb->evokeMultipleCallbacks(.1, 1); std::cout << "."; if (input.keybrdTick() < 0) { cleanUpProgram(rtiAmb); } minimalSleepFunction(); } std::cout << endl; rtiAmb->enableTimeConstrained(); std::cout << "Waiting to become Time Constrained \n"; rtiAmb->evokeMultipleCallbacks(.1, 1); while ( ! theAmbData.isConstrained ) { std::cout << "."; if (input.keybrdTick() < 0 ) { cleanUpProgram(rtiAmb); } rtiAmb->evokeMultipleCallbacks(.1, 1); if ( ! theAmbData.isConstrained ) { yieldFunction(); } } cout << std::endl; } catch (Exception& ) { std::cout << " unable to become regulating and constrained\n" << " Exiting ...\n"; cleanUpProgram(rtiAmb); } } // This function will not exit until numFederates (as indicated to the master // of this federation execution) have been made known to the master federate. // The master then waits to have discovered numFederates - 1, // (i.e. all federates but itself), then accomplished by the master registering // a sync point. From this point the master behaves exactly as the other federates. // The non-master federates wait for the announceSyncPoint callback, indicating that // the master federate has discovered all necessary federates. They each non-master federate // will call synchPointAchieved, indicating to the RTI that they are prepared to start. // Then both master and non-master simply wait for the RTI federationSynchronized callback. // Note: An alternative to waiting for object discovery callbacks to indicate a joined federate // is to use MOM interactions. The master can subscribe to a MOM interaction and have a joined // federate send that interaction prior to entering the synchronizeFederation function. void synchronizeFederation(RTIambassador* rtiAmb) { if ( theAmbData.isMaster ) { std::wstring syncPointLabel(initSyncPointLabel.c_str()); std::string synchPointTag(""); int maximumSize(256); char* hostName = new char[maximumSize]; if ( -1 == gethostname(hostName, maximumSize) ) { unsigned int objId = abs(getpid()); std::stringstream pid; pid.str(std::string("")); pid << "unknownHostName" << "_" << objId; synchPointTag = pid.str(); } else { unsigned int objId = abs(getpid()); std::stringstream pid; pid.str(std::string("")); pid << hostName << "_" << objId; synchPointTag = pid.str(); } delete hostName; // Wait until other federates have joined. rtiAmb->evokeMultipleCallbacks(0.1, 0.2); std::cout << " Master waiting for all federates to Join.\n"; while ( theAmbData.otherFederatesReady < (theAmbData.numFederates - 1) ) { if (input.keybrdTick() < 0 ) { cleanUpProgram(rtiAmb); } yieldFunction(); rtiAmb->evokeMultipleCallbacks(0.1, 0.2); } // Now that all required federates have joined, register a sync point. std::cout << " Master federate has discovered the required number of other federates.\n\n"; VariableLengthData ourTag(synchPointTag.c_str(), synchPointTag.size()); rtiAmb->registerFederationSynchronizationPoint(syncPointLabel.c_str(), ourTag); rtiAmb->evokeMultipleCallbacks(0.1, 0.2); while ( !theAmbData.registerFailed && !theAmbData.registerSucceeded ) { if (input.keybrdTick() < 0 ) { cleanUpProgram(rtiAmb); } yieldFunction(); rtiAmb->evokeMultipleCallbacks(0.1, 0.2); } if ( theAmbData.registerFailed ) { std::cout << " We failed to register synch point " << DtToString(syncPointLabel) << std::endl << " with tag " << synchPointTag << std::endl; cleanUpProgram(rtiAmb); } std::cout << "Master succesfully registered\n"; } else { rtiAmb->evokeMultipleCallbacks(0.1, 0.2); std::cout << " Ordinary federate is waiting for synchPoint message\n"; while ( ! theAmbData.announceSyncReceived ) { if (input.keybrdTick() < 0 ) { cleanUpProgram(rtiAmb); } yieldFunction(); rtiAmb->evokeMultipleCallbacks(0.1, 0.2); } std::cout << "sync Point message received\n"; } // At this time, any kind of federate announces to the RTI that they have reached their // synchronization. try { rtiAmb->synchronizationPointAchieved(initSyncPointLabel.c_str()); } catch (Exception& ) { std::cout << " Synch point achieved failed\n" << " Exiting....\n"; cleanUpProgram(rtiAmb); } // Both kinds of federate are required to wait for the federation to be synchronized. //Then they will wait for the RTI to announce to all federates that all federates are synchronized. rtiAmb->evokeMultipleCallbacks(0.1, 0.2); while ( !theAmbData.federationIsSynchronized ) { if (input.keybrdTick() < 0 ) { cleanUpProgram(rtiAmb); } minimalSleepFunction(); rtiAmb->evokeMultipleCallbacks(0.1, 0.2); } } int main(int argc, char** argv) { std::cout << "MAK simpleTime version 1516" << std::endl; RTIambassador* rtiAmb = 0; try { if (argc > 1) { if (! parseCmdLine(argc, argv) ) { exit(0); } } // Federate and Federation info std::vector< std::wstring > args; std::wstring federateType(L"simpletime1516"); std::cout << "Using " << DtToString(RTIname().c_str() ) << " " << DtToString(RTIversion().c_str()) << std::endl; // RTI and Federate Ambassadors RTIambassadorFactory* rtiAmbFactory = new RTIambassadorFactory(); std::auto_ptr < RTIambassador > rtiAmbAP = rtiAmbFactory->createRTIambassador(args); delete rtiAmbFactory; rtiAmb = rtiAmbAP.release(); MyFederateAmbassador fedAmb(theAmbData); // Create the federation createFedEx(rtiAmb, federationName, fedFileName); // Join the federation joinFedEx(rtiAmb, fedAmb, federateType, federationName); #ifdef WIN32 WSADATA data; WSAStartup(MAKEWORD(1,1), &data); #endif rtiAmb->evokeCallback(0.0); long count=0; LogicalTime* currentTime = new LogicalTimeImpl(0.0); LogicalTimeInterval* lookAhead = new LogicalTimeIntervalImpl(1.0f); LogicalTime* currentRTITime = new LogicalTimeImpl(0.0); LogicalTimeInterval* oneTimeStep = new LogicalTimeIntervalImpl(5.0f); //Become Time managed and regulating in this federation. becomeConstrainedAndRegulating(rtiAmb, currentTime, lookAhead); (*currentTime) += (*oneTimeStep); // Publish, subscribe and register and object if (!publishSubscribeAndRegisterObject(rtiAmb)) { resignAndDestroy(rtiAmb); return 0; } // By using synchronization points, ensure that all expected federates // have joined prior to commencing. This function requires that // other federates have registered an object as it utilizes discovery // callbacks to count the number of federates that have joined as yet. if ( !unManagedFederate ) { synchronizeFederation(rtiAmb); } // Publish and subscribe to the required interaction if (!publishAndSubscribeInteraction(rtiAmb)) { resignAndDestroy(rtiAmb); return 0; } // This is the main loop of the application. In it, the federate ticks the RTI, updates // its published attributes and if indicated, fires and detonates, this continues // until this federate has been detonated. while ( !theAmbData.timeManagedObject.isDetonated() ) { std::cout << "============================================" "============================================" << endl; std::cout << " Fedtime ("; printOutFedTime(currentRTITime); std::cout << "), Lookahead ("; printOutFedTime(lookAhead); std::cout << ") and wallclock time ("; printOutFedTime(currentTime); std::cout << ") " << endl; std::cout << endl; std::stringstream ss; ss << "1516-" << count++; std::string tag(ss.str()); // Tag format is narrow string representation compatible // with 1.3 simple federate theAmbData.timeManagedObject.tick(); theAmbData.timeManagedObject.incPosition(); try{ // Update the object rtiAmb->updateAttributeValues( theObjectHandle, (*theAmbData.attrValues), VariableLengthData(tag.c_str(), tag.size()+1), (*currentTime)); rtiAmb->evokeMultipleCallbacks(0.1, 0.5); // Send the interaction if appropriate if ( theAmbData.timeManagedObject.shouldDetonate() ) { string munitionString = "MunitionObjectIdentifier"; // Find the Parameter Handle that the RTI associated with this Parameter Name. ParameterHandle retrievedHandle = theAmbData.theParamNameHandleMap[DtToWString(munitionString.c_str())]; // By adding a munitions parameter with nothing for the data, we communicate that this // interaction is a munitions interaction. ParameterHandleValueMap::iterator munitionData = theAmbData.paramValues->find( retrievedHandle ); VariableLengthData prior = theAmbData.paramValues->find( munitionData->first)->second; VariableLengthData emptySet("\0", 1); (*theAmbData.paramValues)[munitionData->first] = emptySet; rtiAmb->sendInteraction( fireInteractionHandle, (*theAmbData.paramValues), VariableLengthData(tag.c_str(), tag.size()+1), (*currentTime)); // Restore the munitions parameter data. (*theAmbData.paramValues)[munitionData->first] = prior; } if ( theAmbData.timeManagedObject.shouldFire() ) { string fireString = "FiringObjectIdentifier"; // Find the Parameter Handle that the RTI associated with the Fire Parameter. ParameterHandleValueMap::iterator fireData = theAmbData.paramValues->find( theAmbData.theParamNameHandleMap[DtToWString(fireString.c_str())]); // By replacing the existing fire parameter with one thas has null data, we indicate // that this interaction is a fire interation. VariableLengthData prior = theAmbData.paramValues->find(fireData->first)->second; VariableLengthData emptySet("\0", 1); (*theAmbData.paramValues)[fireData->first] = emptySet; rtiAmb->sendInteraction( fireInteractionHandle, (*theAmbData.paramValues), VariableLengthData(tag.c_str(), tag.size()+1), (*currentTime)); // Restore the fire parameter's data. (*theAmbData.paramValues)[fireData->first] = prior; } } catch( InvalidLogicalTime& ex) { std::cout << "RTI Invalid Logical Time" << endl; std::cout << DtToString(ex.what()) << "Could not update object or send interaction" << endl; cleanUpProgram(rtiAmb); } catch( Exception& ex) { std::cout << "RTI Exception " << endl << DtToString(ex.what()) << endl << " Could not update object or send interaction" << endl; } int kb(0); try { if ( theAmbData.isRegulating ) { (*currentRTITime) += (*oneTimeStep); (*currentTime) += (*oneTimeStep); rtiAmb->timeAdvanceRequest(*currentRTITime); theAmbData.timeAdvanced = false; rtiAmb->evokeMultipleCallbacks(0.1, 0.5); while ( ! theAmbData.timeAdvanced ) { kb = input.keybrdTick(); if (kb < 0) { break; } else if ( kb == 1 ) { theAmbData.timeManagedObject.firePressed(); cout << "**********Firing at time " ; printOutFedTime(currentRTITime); cout << "*************\n"; } else if ( !theAmbData.timeAdvanced ) { rtiAmb->evokeMultipleCallbacks(0.1, 0.5); yieldFunction(); } } } } catch( Exception& ex ) { std::cout << "RTI Exception" << endl << DtToString(ex.what()) << endl << "Could not advance time" << endl; } rtiAmb->evokeMultipleCallbacks(0.1, 0.5); if ( kb == 0 ) { kb = input.keybrdTick(); } if (kb < 0) { break; } else if ( kb == 1 ) { theAmbData.timeManagedObject.firePressed(); cout << "**********Firing at time " ; printOutFedTime(currentRTITime); cout << "*************\n"; } std::cout << "============================================" "============================================" << endl << endl; sleepFunction(); } delete currentTime; delete currentRTITime; delete lookAhead; delete oneTimeStep; delete theAmbData.paramValues; delete theAmbData.attrValues; if ( theAmbData.isRegulating ) { rtiAmb->disableTimeRegulation(); } // Resign and destroy federation resignAndDestroy(rtiAmb); if( rtiAmb ) { delete rtiAmb; rtiAmb = 0; } } catch (rti1516::Exception& ex) { std::cout << "RTI Exception (main loop): " << DtToString(ex.what()) << endl; if( rtiAmb ) { delete rtiAmb; } } #ifdef WIN32 WSACleanup(); #endif return 0; } bool parseCmdLine( int argc, char* argv[] ) { // Process commandline linput. vector < std::string > cmdArgs; copy( argv + 1, argv + argc, back_inserter(cmdArgs)); vector<std::string>::const_iterator cur = cmdArgs.begin(); vector<std::string>::const_iterator last = cmdArgs.end(); while ( cur != last ) { vector<std::string>::const_iterator next = cur + 1; if ( *cur == "-h" ) { std::cerr << usage(); return false; } else if ( *cur == "-fedFile" ) { fedFileName = DtToWString((*next).c_str()); ++cur; } else if (*cur == "-m" ) { if ( !convert<int> (*cur, *next, theAmbData.numFederates)) { std::cerr << usage(); return false; } theAmbData.isMaster = true; ++cur; } else if ( *cur == "-phaseLine" ) { int phaseLine(0); if ( !convert<int>(*cur, *next, phaseLine)) { std::cerr << usage(); return false; } theAmbData.timeManagedObject.setPhaseLine(phaseLine); ++cur; } else if ( *cur == "-sleepTime" ) { if ( !convert<int> (*cur, *next, sleepTime )) { std::cerr << usage(); return false; } ++cur; } else if ( *cur == "-dedicated" ) { dedicatedMachine = true; } else if ( *cur == "-unManaged" ) { unManagedFederate = true; } else { std::cerr<< usage(); return false; } ++cur; } return true; }
/******************************************************************************* ** Copyright (c) 2004 MaK Technologies, Inc. ** All rights reserved. *******************************************************************************/ #ifdef WIN32 #pragma warning(disable: 4251) #pragma warning(disable: 4786) #pragma warning(disable: 4290) #endif #include <iostream> #include "simpleTimeFedAmb1516.h" using namespace std; DtTalkAmbData::DtTalkAmbData() : isConstrained(false), isRegulating(false), timeAdvanced(false), otherFederatesReady(false) { } DtTalkAmbData::~DtTalkAmbData() { } MyFederateAmbassador::MyFederateAmbassador(DtTalkAmbData & data) : NullFederateAmbassador(), myData(data) {} MyFederateAmbassador::~MyFederateAmbassador() throw () {} void MyFederateAmbassador::objectInstanceNameReservationSucceeded( std::wstring const & theObjectInstanceName) throw ( UnknownName, FederateInternalError) { myData.myNameReservationReturned = myData.myNameReservationSucceeded = true; } void MyFederateAmbassador::objectInstanceNameReservationFailed( std::wstring const & theObjectInstanceName) throw ( UnknownName, FederateInternalError) { myData.myNameReservationReturned = true; myData.myNameReservationSucceeded = false; } void MyFederateAmbassador::discoverObjectInstance ( ObjectInstanceHandle theObject, ObjectClassHandle theObjectClass, std::wstring const & theObjectInstanceName) throw ( CouldNotDiscover, ObjectClassNotKnown, FederateInternalError) { // This is an over simplification of the initialization of a federation. // In our case we simply wait until there are the requisite # of known federates // before starting. ++myData.otherFederatesReady; if ( myData.isMaster ) { std::cout << " Master federate is aware of " << myData.otherFederatesReady + 1 << " federates, including itself\n"; } // Now that we've discovered an object we should request an Attribute // update for all of the attributes that we're subscribed for. // Construct an attribute handle set AttributeHandleSet* hSet = new AttributeHandleSet(); for ( DtAttrNameHandleMap::iterator iter = myData.theAttrNameHandleMap.begin(); iter != myData.theAttrNameHandleMap.end(); ++iter ) { hSet->insert( iter->second ); } // In order to avoid making RTI calls from within an RTI callback, // we'll add this attrRequest to a shared Object, allowing the // call to be made from outside this callback. myData.objectInstanceMap[theObject] = theObjectInstanceName; myData.updateRequestMap.insert( std::make_pair(theObject, hSet) ); delete hSet; } // To keep callbacks expedient and simple, we simply save all pertinent information // from this reflect in our timeManagedObject, allowing the main thread of execution // to process the update when it chooses. // The same can be said of the other reflectAttributeValues calls void MyFederateAmbassador::reflectAttributeValues ( ObjectInstanceHandle theObject, AttributeHandleValueMap const & theAttributeValues, VariableLengthData const & theUserSuppliedTag, OrderType sentOrder, TransportationType theType) throw ( ObjectInstanceNotKnown, AttributeNotRecognized, AttributeNotSubscribed, FederateInternalError) { AttributeHandleValueMap const ahvps; VariableLengthData const theUserSuppliedTag2; const OrderType sentOrder2 = RECEIVE; const TransportationType theType2 = BEST_EFFORT; attributeUpdateEvent tmp2( ahvps, theUserSuppliedTag2, sentOrder2, theType2 ); attributeUpdateEvent* tmp = new attributeUpdateEvent(theAttributeValues, theUserSuppliedTag, sentOrder, theType); myData.timeManagedObject.addAttrUpdateEvent(tmp); } void MyFederateAmbassador::reflectAttributeValues ( ObjectInstanceHandle theObject, AttributeHandleValueMap const & theAttributeValues, VariableLengthData const & theUserSuppliedTag, OrderType sentOrder, TransportationType theType, RegionHandleSet const & theSentRegionHandleSet) throw ( ObjectInstanceNotKnown, AttributeNotRecognized, AttributeNotSubscribed, FederateInternalError) { reflectAttributeValues(theObject, theAttributeValues, theUserSuppliedTag, sentOrder, theType); } void MyFederateAmbassador::reflectAttributeValues ( ObjectInstanceHandle theObject, AttributeHandleValueMap const & theAttributeValues, VariableLengthData const & theUserSuppliedTag, OrderType sentOrder, TransportationType theType, LogicalTime const & theTime, OrderType receivedOrder) throw ( ObjectInstanceNotKnown, AttributeNotRecognized, AttributeNotSubscribed, FederateInternalError) { myData.timeManagedObject.addAttrUpdateEvent( new attributeUpdateEvent( theAttributeValues, theUserSuppliedTag, sentOrder, theType, theTime )); } void MyFederateAmbassador::reflectAttributeValues ( ObjectInstanceHandle theObject, AttributeHandleValueMap const & theAttributeValues, VariableLengthData const & theUserSuppliedTag, OrderType sentOrder, TransportationType theType, LogicalTime const & theTime, OrderType receivedOrder, RegionHandleSet const & theSentRegionHandleSet) throw ( ObjectInstanceNotKnown, AttributeNotRecognized, AttributeNotSubscribed, FederateInternalError) { reflectAttributeValues(theObject, theAttributeValues, theUserSuppliedTag, sentOrder, theType, theTime, receivedOrder); } void MyFederateAmbassador::reflectAttributeValues ( ObjectInstanceHandle theObject, AttributeHandleValueMap const & theAttributeValues, VariableLengthData const & theUserSuppliedTag, OrderType sentOrder, TransportationType theType, LogicalTime const & theTime, OrderType receivedOrder, MessageRetractionHandle theHandle) throw ( ObjectInstanceNotKnown, AttributeNotRecognized, AttributeNotSubscribed, InvalidLogicalTime, FederateInternalError) { reflectAttributeValues(theObject, theAttributeValues, theUserSuppliedTag, sentOrder, theType, theTime, receivedOrder); } void MyFederateAmbassador::reflectAttributeValues ( ObjectInstanceHandle theObject, AttributeHandleValueMap const & theAttributeValues, VariableLengthData const & theUserSuppliedTag, OrderType sentOrder, TransportationType theType, LogicalTime const & theTime, OrderType receivedOrder, MessageRetractionHandle theHandle, RegionHandleSet const & theSentRegionHandleSet) throw ( ObjectInstanceNotKnown, AttributeNotRecognized, AttributeNotSubscribed, InvalidLogicalTime, FederateInternalError) { reflectAttributeValues(theObject, theAttributeValues, theUserSuppliedTag, sentOrder, theType, theTime, receivedOrder); } // Similar to the reflectAttributeValues implementations, here we do some minimal // interpretation of the received Interaction (whether it is a fire or detonation // interaction), and add the interaction event to our timeManagedObject, allowing // the main thread of execution to process it as appropriate. void MyFederateAmbassador::receiveInteraction( InteractionClassHandle theInteraction, ParameterHandleValueMap const & theParameterValues, VariableLengthData const & theUserSuppliedTag, OrderType sentOrder, TransportationType theType) throw (InteractionClassNotRecognized, InteractionParameterNotRecognized, InteractionClassNotSubscribed, FederateInternalError) { interactionEvent* receivedInteraction = new interactionEvent( theInteraction, theParameterValues, theUserSuppliedTag, sentOrder, theType ); myData.timeManagedObject.addInteractionEvent(receivedInteraction); } // Simply call the other receiveInteraction callback, dropping the regionHandleSet. void MyFederateAmbassador::receiveInteraction( InteractionClassHandle theInteraction, ParameterHandleValueMap const & theParameterValues, VariableLengthData const & theUserSuppliedTag, OrderType sentOrder, TransportationType theType, RegionHandleSet const & theSentRegionHandleSet) throw (InteractionClassNotRecognized, InteractionParameterNotRecognized, InteractionClassNotSubscribed, FederateInternalError) { receiveInteraction(theInteraction, theParameterValues, theUserSuppliedTag, sentOrder, theType); } // Similar to the other receiveInteraction implementation, with the additional time // stamp information. void MyFederateAmbassador::receiveInteraction( InteractionClassHandle theInteraction, ParameterHandleValueMap const & theParameterValues, VariableLengthData const & theUserSuppliedTag, OrderType sentOrder, TransportationType theType, LogicalTime const & theTime, OrderType receivedOrder) throw (InteractionClassNotRecognized, InteractionParameterNotRecognized, InteractionClassNotSubscribed, FederateInternalError) { interactionEvent::interaction_type interactionType(interactionEvent::Unknown); string munitionString("MunitionObjectIdentifier"); string fireString("FiringObjectIdentifier"); if ( myData.theParamNameHandleMap.find(DtToWString(munitionString.c_str())) != myData.theParamNameHandleMap.end() ) { ParameterHandle munitionHandle = myData.theParamNameHandleMap.find(DtToWString(munitionString.c_str()))->second; ParameterHandleValueMap::const_iterator munitionEntry = theParameterValues.find(munitionHandle); if ( munitionEntry != theParameterValues.end() ) { VariableLengthData munitionData = munitionEntry->second; if ( munitionData.size() == 1 ) { interactionType = interactionEvent::DetonationType; } } } if ( myData.theParamNameHandleMap.find(DtToWString(fireString.c_str())) != myData.theParamNameHandleMap.end()) { ParameterHandle fireHandle = myData.theParamNameHandleMap.find(DtToWString(fireString.c_str()))->second ; ParameterHandleValueMap::const_iterator fireEntry = theParameterValues.find(fireHandle); if ( fireEntry != theParameterValues.end() ) { VariableLengthData fireData = fireEntry->second; if ( fireData.size() == 1 ) { interactionType = interactionEvent::FireType; } } } myData.timeManagedObject.addInteractionEvent(new interactionEvent( theInteraction, theParameterValues, theUserSuppliedTag, sentOrder, theType, theTime, receivedOrder, interactionType )); } // Simply call the other time Mgmt. receiveInteraction callback, // dropping the regionHandleSet. void MyFederateAmbassador::receiveInteraction( InteractionClassHandle theInteraction, ParameterHandleValueMap const & theParameterValues, VariableLengthData const & theUserSuppliedTag, OrderType sentOrder, TransportationType theType, LogicalTime const & theTime, OrderType receivedOrder, RegionHandleSet const & theSentRegionHandleSet) throw (InteractionClassNotRecognized, InteractionParameterNotRecognized, InteractionClassNotSubscribed, FederateInternalError) { receiveInteraction(theInteraction, theParameterValues, theUserSuppliedTag, sentOrder, theType, theTime, receivedOrder); } void MyFederateAmbassador::receiveInteraction( InteractionClassHandle theInteraction, ParameterHandleValueMap const & theParameterValues, VariableLengthData const & theUserSuppliedTag, OrderType sentOrder, TransportationType theType, LogicalTime const & theTime, OrderType receivedOrder, MessageRetractionHandle theHandle) throw (InteractionClassNotRecognized, InteractionParameterNotRecognized, InteractionClassNotSubscribed, InvalidLogicalTime, FederateInternalError) { receiveInteraction(theInteraction, theParameterValues, theUserSuppliedTag, sentOrder, theType, theTime, receivedOrder); } void MyFederateAmbassador::receiveInteraction( InteractionClassHandle theInteraction, ParameterHandleValueMap const & theParameterValues, VariableLengthData const & theUserSuppliedTag, OrderType sentOrder, TransportationType theType, LogicalTime const & theTime, OrderType receivedOrder, MessageRetractionHandle theHandle, RegionHandleSet const & theSentRegionHandleSet) throw (InteractionClassNotRecognized, InteractionParameterNotRecognized, InteractionClassNotSubscribed, InvalidLogicalTime, FederateInternalError) { receiveInteraction(theInteraction, theParameterValues, theUserSuppliedTag, sentOrder, theType, theTime, receivedOrder); } // remove the object instance from our map of object instances. void MyFederateAmbassador::removeObjectInstance( ObjectInstanceHandle theObject, VariableLengthData const & theUserSuppliedTag, OrderType sentOrder) throw ( ObjectInstanceNotKnown, FederateInternalError) { if ( myData.objectInstanceMap.find(theObject) != myData.objectInstanceMap.end() ) myData.objectInstanceMap.erase(theObject); myData.timeManagedObject.reset(); } void MyFederateAmbassador::removeObjectInstance( ObjectInstanceHandle theObject, VariableLengthData const & theUserSuppliedTag, OrderType sentOrder, LogicalTime const & theTime, OrderType receivedOrder) throw ( ObjectInstanceNotKnown, FederateInternalError) { if ( myData.objectInstanceMap.find(theObject) != myData.objectInstanceMap.end() ) myData.objectInstanceMap.erase(theObject); } void MyFederateAmbassador::removeObjectInstance( ObjectInstanceHandle theObject, VariableLengthData const & theUserSuppliedTag, OrderType sentOrder, LogicalTime const & theTime, OrderType receivedOrder, MessageRetractionHandle theHandle) throw ( ObjectInstanceNotKnown, InvalidLogicalTime, FederateInternalError) { if ( myData.objectInstanceMap.find(theObject) != myData.objectInstanceMap.end() ) myData.objectInstanceMap.erase(theObject); } // A request was made for an attribute update from this update, add the request // to our updateRequestMap. void MyFederateAmbassador::provideAttributeValueUpdate( ObjectInstanceHandle theObject, AttributeHandleSet const & theAttributes, VariableLengthData const & theUserSuppliedTag) throw (ObjectInstanceNotKnown, AttributeNotRecognized, AttributeNotOwned, FederateInternalError) { // Construct an attribute handle set AttributeHandleSet* hSet = new AttributeHandleSet(); for ( DtAttrNameHandleMap::iterator iter = myData.theAttrNameHandleMap.begin(); iter != myData.theAttrNameHandleMap.end(); ++iter ) { hSet->insert( iter->second ); } myData.updateRequestMap.insert( std::make_pair(theObject, hSet) ); } // Alert the user and set the isRegulating flag of our shared Object. void MyFederateAmbassador::timeRegulationEnabled(LogicalTime const & theFederateTime) throw (InvalidLogicalTime, NoRequestToEnableTimeRegulationWasPending, FederateInternalError) { std::cout << " This federate is now able to Regulate time\n"; myData.isRegulating = true; } // Alert the user and set the isConstrained flag of our shared Object. void MyFederateAmbassador::timeConstrainedEnabled(LogicalTime const & theFederateTime) throw (InvalidLogicalTime, NoRequestToEnableTimeConstrainedWasPending, FederateInternalError) { std::cout << " This federate is now time Constrained\n"; myData.isConstrained = true; } // Alert the user and set the timeAdvanced flag of our shared Object. void MyFederateAmbassador::timeAdvanceGrant(LogicalTime const & theTime) throw (InvalidLogicalTime, JoinedFederateIsNotInTimeAdvancingState, FederateInternalError) { std::cout << " Federate Time has been advanced to " << DtToString(theTime.toString()) << std::endl; myData.timeAdvanced = true; } void MyFederateAmbassador::requestRetraction(MessageRetractionHandle theHandle) throw (FederateInternalError) { } // set the registerSucceeded flag of our shared object void MyFederateAmbassador::synchronizationPointRegistrationSucceeded( std::wstring const & label) throw (FederateInternalError) { myData.registerSucceeded = true; } // set the registerFailed flag of our shared Object. void MyFederateAmbassador::synchronizationPointRegistrationFailed( std::wstring const & label, SynchronizationFailureReason reason) throw (FederateInternalError) { myData.registerFailed = true; } // We received a callback from the RTI announcing a synchronization point. void MyFederateAmbassador::announceSynchronizationPoint( std::wstring const & label, VariableLengthData const & theUserSuppliedTag) throw (FederateInternalError) { myData.announceSyncReceived = true; std::cout << "Announce Sync Received for label " << DtToString(label.c_str()) << " and tag " << reinterpret_cast<const char*>(theUserSuppliedTag.data()) << endl; } // A previous synchronization point has been achieved by all involved federates. void MyFederateAmbassador::federationSynchronized(std::wstring const & label) throw (FederateInternalError) { myData.federationIsSynchronized = true; std::cout << " My Federation has been synchronized.\n"; }
/******************************************************************************* * Adapted from "Beginning Linux Programming", from Wrox Press -- www.wrox.com *******************************************************************************/ /******************************************************************************* ** $RCSfile: simpleTimeKeyboard.cxx,v $ $Revision: 1.1 $ $State: Exp $ *******************************************************************************/ #include "simpleTimeKeyboard.h" #ifdef WIN32 #include <conio.h> #else #include <unistd.h> #endif #include <iostream> 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' && kbhit()) key = getkey(); if ( key == 'q' || key == 'Q' ) { return -1; } else if ( key == 32 ) { return 1; } else { return 0; } }
/******************************************************************************* ** Copyright (c) 2006 MaK Technologies, Inc. ** All rights reserved. *******************************************************************************/ /******************************************************************************* ** $RCSfile: simpleTimeAttribute1516.cxx,v $ $Revision: 1.3 $ $State: Exp $ *******************************************************************************/ #ifdef DtIFSPEC1516 #ifdef WIN32 #pragma warning(disable: 4251) #pragma warning(disable: 4786) #pragma warning(disable: 4290) #endif #include "simpleTimeAttribute1516.h" #include "simpleTimeStringUtil.h" // A simple container class for an attributeUpdate event // Construct an attributeUpdateEvent, store pertinent information from the reflect callback. attributeUpdateEvent::attributeUpdateEvent( const AttributeHandleValueMap& ahvps, const VariableLengthData& userSuppliedTag, const OrderType sentOrder, const TransportationType theType, const LogicalTime& fedTime ) : myTag(static_cast<const char*>( userSuppliedTag.data() )), myFedTime(DtToString(fedTime.toString())) { AttributeHandleValueMap::const_iterator iter = ahvps.begin(); AttributeHandleValueMap::const_iterator theEnd = ahvps.end(); for ( ; iter != theEnd; ++iter ) { myAhvps.insert(std::make_pair( iter->first, std::string(static_cast<const char*>( iter->second.data())))); } } // Construct an attributeEvent from a non-Time Managed reflectAttributeUpdates callback. attributeUpdateEvent::attributeUpdateEvent( const AttributeHandleValueMap& ahvps, const VariableLengthData& userSuppliedTag, const OrderType sentOrder, const TransportationType theType) : myTag(static_cast<const char*>( userSuppliedTag.data() )) { AttributeHandleValueMap::const_iterator iter = ahvps.begin(); AttributeHandleValueMap::const_iterator theEnd = ahvps.end(); for ( ; iter != theEnd; ++iter ) { myAhvps.insert(std::make_pair( iter->first, std::string(static_cast<const char*>( iter->second.data())))); } } attributeUpdateEvent::~attributeUpdateEvent() {} const std::map<AttributeHandle, std::string>& attributeUpdateEvent::getAhvps() { return myAhvps; } const std::string& attributeUpdateEvent::getFedTime() { return myFedTime; } const std::string& attributeUpdateEvent::getTag() { return myTag; } MessageRetractionHandle attributeUpdateEvent::getRetractionHandle() { return myRetractionHandle; } #endif
/******************************************************************************* ** Copyright (c) 2006 MaK Technologies, Inc. ** All rights reserved. *******************************************************************************/ /******************************************************************************* ** $RCSfile: simpleTimeInteraction1516.cxx,v $ $Revision: 1.2 $ $State: Exp $ *******************************************************************************/ #ifdef WIN32 #pragma warning(disable: 4251) #pragma warning(disable: 4786) #pragma warning(disable: 4290) #endif #include "simpleTimeInteraction1516.h" // Construct an interactionEvent, store pertinent information from the callback. interactionEvent::interactionEvent( const rti1516::InteractionClassHandle theHandle, const rti1516::ParameterHandleValueMap& phvps, const rti1516::VariableLengthData& userSuppliedTag, const rti1516::OrderType sentOrder, const rti1516::TransportationType theType, const rti1516::LogicalTime& fedTime, const rti1516::OrderType receivedOrder, rti1516::MessageRetractionHandle theRetractionHandle, interaction_type theInteractionType ): myHandle(theHandle), myTag(static_cast<const char*>(userSuppliedTag.data())), myRetractionHandle(theRetractionHandle), myInteractionType(theInteractionType) { rti1516::ParameterHandleValueMap::const_iterator iter = phvps.begin(); rti1516::ParameterHandleValueMap::const_iterator theEnd = phvps.end(); for ( ; iter != theEnd; ++iter ) { myPhvps.insert( std::make_pair( iter->first, std::string(static_cast<const char*>( iter->second.data())) ) ); } myFedTime = DtToString(fedTime.toString()); } // Construct an interactionEvent, store pertinent information from the callback. interactionEvent::interactionEvent( const rti1516::InteractionClassHandle theHandle, const rti1516::ParameterHandleValueMap& phvps, const rti1516::VariableLengthData& userSuppliedTag, const rti1516::OrderType sentOrder, const rti1516::TransportationType theType, const rti1516::LogicalTime& fedTime, const rti1516::OrderType receivedOrder, interaction_type theInteractionType ) : myHandle(theHandle), myTag(static_cast<const char*>(userSuppliedTag.data())), myRetractionHandle(), myInteractionType(theInteractionType) { rti1516::ParameterHandleValueMap::const_iterator iter = phvps.begin(); rti1516::ParameterHandleValueMap::const_iterator theEnd = phvps.end(); for ( ; iter != theEnd; ++iter ) { myPhvps.insert( std::make_pair( iter->first, std::string(static_cast<const char*>(iter->second.data())) ) ); } myFedTime = DtToString(fedTime.toString()); } // Construct an interactionEvent from a non-Time Managed callback. interactionEvent::interactionEvent(const rti1516::InteractionClassHandle theHandle, const rti1516::ParameterHandleValueMap& phvps, const rti1516::VariableLengthData& userSuppliedTag, const rti1516::OrderType sentOrder, const rti1516::TransportationType theType, interaction_type theInteractionType ) : myHandle(theHandle), myTag(static_cast<const char*>(userSuppliedTag.data())), myFedTime(""), myRetractionHandle(), myInteractionType(theInteractionType) { rti1516::ParameterHandleValueMap::const_iterator iter = phvps.begin(); rti1516::ParameterHandleValueMap::const_iterator theEnd = phvps.end(); for ( ; iter != theEnd; ++iter ) { myPhvps.insert( std::make_pair( iter->first, std::string(static_cast<const char*>(iter->second.data())) ) ); } } interactionEvent::~interactionEvent() { } rti1516::InteractionClassHandle interactionEvent::getHandle() { return myHandle; } const std::string& interactionEvent::getFedTime() { return myFedTime; } const std::string& interactionEvent::getTag() { return myTag; } const rti1516::MessageRetractionHandle& interactionEvent::getRetractionHandle() { return myRetractionHandle; } bool interactionEvent::isFireInteraction() { return myInteractionType == FireType; } bool interactionEvent::isDetonateInteraction() { return myInteractionType == DetonationType; } int interactionEvent::getTypeOfInteraction() { return myInteractionType; }
/******************************************************************************* ** Copyright (c) 2006 MaK Technologies, Inc. ** All rights reserved. *******************************************************************************/ /******************************************************************************* ** $RCSfile: simpleTimeTimeManagedEntity.cxx,v $ $Revision: 1.3 $ $State: Exp $ *******************************************************************************/ #ifdef WIN32 #pragma warning(disable: 4251) #pragma warning(disable: 4786) #pragma warning(disable: 4290) #endif // A simple object that dictates the behavior of an advancing entity. #include "simpleTimeTimeManagedEntity.h" #include <assert.h> #include <iostream> timeManagedEntity::timeManagedEntity() : myFirePressed(false), myPosition(0), myVelocity(0), myPhysicalState(Alive), myState(Initial), myPhaseLine(150) { } timeManagedEntity::~timeManagedEntity() { while ( attrUpdateWaiting() ) { delete getNextAttrUpdateEvent(); } while ( interactionWaiting() ) { delete getNextInteractionEvent(); } } bool timeManagedEntity::attrUpdateWaiting() { return myAttrUpdateQueue.size() > 0; } bool timeManagedEntity::interactionWaiting() { return myInteractionQueue.size() > 0; } interactionEvent* timeManagedEntity::getNextInteractionEvent() { interactionEvent* retVal = myInteractionQueue.front(); myInteractionQueue.pop(); return retVal; } attributeUpdateEvent* timeManagedEntity::getNextAttrUpdateEvent() { attributeUpdateEvent* retVal = myAttrUpdateQueue.front(); myAttrUpdateQueue.pop(); return retVal; } void timeManagedEntity::addInteractionEvent(interactionEvent* eventToAdd) { myInteractionQueue.push(eventToAdd); } void timeManagedEntity::addAttrUpdateEvent(attributeUpdateEvent* eventToAdd) { myAttrUpdateQueue.push(eventToAdd); } bool timeManagedEntity::shouldFire() { return (myState == Firing ); } void timeManagedEntity::reset() { myState = Initial; myPhysicalState = Alive; myFirePressed = false; } bool timeManagedEntity::shouldDetonate() { return (myState == SendDetonate ); } bool timeManagedEntity::isFiredUpon() { return ( myPhysicalState >= FiredUpon ); } bool timeManagedEntity::isDetonated() { return ( myPhysicalState >= Damaged ); } void timeManagedEntity::setPhaseLine(int phaseLine) { myPhaseLine = phaseLine; } void timeManagedEntity::processEvents() { if ( isDetonated() ) { std::cout << "XXX DEAD XXX\n"; while ( interactionWaiting() ) { delete getNextInteractionEvent(); } while ( attrUpdateWaiting() ) { delete getNextAttrUpdateEvent(); } } else { while ( interactionWaiting() ) { interactionEvent* receivedInteraction = getNextInteractionEvent(); std::string fedTime = receivedInteraction->getFedTime(); std::string tag = receivedInteraction->getTag(); if ( receivedInteraction->getTypeOfInteraction() == interactionEvent::FireType && myPhysicalState < FiredUpon ) { std::cout << " received Fire interaction (" << tag << ") at time " << fedTime.c_str() << " \n" ; myPhysicalState = FiredUpon; } if ( receivedInteraction->getTypeOfInteraction() == interactionEvent::DetonationType && myPhysicalState < Damaged ) { std::cout << " received Detonation interaction (" << tag << ") at time " << fedTime.c_str() << " \n" ; myPhysicalState = Damaged; } delete receivedInteraction; } while ( attrUpdateWaiting() ) { attributeUpdateEvent* receivedAttrUpdate = getNextAttrUpdateEvent(); std::string fedTime = receivedAttrUpdate->getFedTime(); std::string tag = receivedAttrUpdate->getTag(); std::cout << " received attribute update (" << tag << ") at time " << fedTime.c_str() << " \n" ; delete receivedAttrUpdate; } } } void timeManagedEntity::incPosition() { ++myPosition; } void timeManagedEntity::firePressed() { myFirePressed = true; } void timeManagedEntity::tick() { if ( !isDetonated()) { processEvents(); switch ( myState ) { case Initial : if ( myFirePressed || myPosition >= myPhaseLine ) { myState = Firing; } break; case Firing : myState = SendDetonate; break; case SendDetonate : myState = Firing; break; } } else { myState = Idle; myPhysicalState = Dead; } }
/******************************************************************************* ** Copyright (c) 2004 MaK Technologies, Inc. ** All rights reserved. *******************************************************************************/ /******************************************************************************* ** $RCSfile: simpleTimeFedAmb1516.h,v $ $Revision: 1.2 $ $State: Exp $ *******************************************************************************/ #ifndef MyFederateAmbassador_H_ #define MyFederateAmbassador_H_ #ifdef WIN32 #pragma warning(disable: 4251) #pragma warning(disable: 4786) #pragma warning(disable: 4290) #endif #include <RTI/RTI1516.h> #include <RTI/NullFederateAmbassador.h> #include "simpleTimeStringUtil.h" #include "simpleTimeTimeManagedEntity.h" #include <string> #include <map> using namespace rti1516; typedef std::map<std::wstring, AttributeHandle> DtAttrNameHandleMap; typedef std::map<std::wstring, ParameterHandle> DtParamNameHandleMap; class DtTalkAmbData { public: DtTalkAmbData(); ~DtTalkAmbData(); public: bool myNameReservationReturned; bool myNameReservationSucceeded; std::map<ObjectClassHandle, std::wstring> objectClassMap; std::map<ObjectInstanceHandle, std::wstring> objectInstanceMap; std::map<InteractionClassHandle,std::wstring> interactionClassMap; std::map<ObjectInstanceHandle, AttributeHandleSet*> updateRequestMap; // Map between strings and attribute handles DtAttrNameHandleMap theAttrNameHandleMap; // Map between strings and paramterHandles DtParamNameHandleMap theParamNameHandleMap; // The set of Attributes that this federate's published objects will contain. std::set<std::string> ourAttrs; // the Set of Parameters that this federate's published interactions will contain. std::set<std::string> ourParms; // This federation of simple objects has a single master object, (determined by command line arguments) // The master federate will keep the other federates from entering their main loop of execution until // all of numFederates have joined. bool isMaster; // numFederates is the number of federates (including the master) that the master should wait to join the // federation before it allows any federate to enter its main loop. // This variable is only used by the master federate. int numFederates; AttributeHandleValueMap* attrValues; ParameterHandleValueMap* paramValues; bool isConstrained; bool isRegulating; bool timeAdvanced; int otherFederatesReady; bool registerFailed; bool registerSucceeded; bool announceSyncReceived; bool federationIsSynchronized; timeManagedEntity timeManagedObject; }; class MyFederateAmbassador : public NullFederateAmbassador { public: MyFederateAmbassador(DtTalkAmbData & data); virtual ~MyFederateAmbassador() throw (); // 6.3 virtual void objectInstanceNameReservationSucceeded(std::wstring const & theObjectInstanceName) throw (UnknownName, FederateInternalError); virtual void objectInstanceNameReservationFailed(std::wstring const & theObjectInstanceName) throw (UnknownName, FederateInternalError); // 6.5 virtual void discoverObjectInstance ( ObjectInstanceHandle theObject, ObjectClassHandle theObjectClass, std::wstring const & theObjectInstanceName) throw ( CouldNotDiscover, ObjectClassNotKnown, FederateInternalError); // 6.7 virtual void reflectAttributeValues (ObjectInstanceHandle theObject, AttributeHandleValueMap const & theAttributeValues, VariableLengthData const & theUserSuppliedTag, OrderType sentOrder, TransportationType theType) throw (ObjectInstanceNotKnown, AttributeNotRecognized, AttributeNotSubscribed, FederateInternalError); virtual void reflectAttributeValues (ObjectInstanceHandle theObject, AttributeHandleValueMap const & theAttributeValues, VariableLengthData const & theUserSuppliedTag, OrderType sentOrder, TransportationType theType, RegionHandleSet const & theSentRegionHandleSet) throw (ObjectInstanceNotKnown, AttributeNotRecognized, AttributeNotSubscribed, FederateInternalError); virtual void reflectAttributeValues (ObjectInstanceHandle theObject, AttributeHandleValueMap const & theAttributeValues, VariableLengthData const & theUserSuppliedTag, OrderType sentOrder, TransportationType theType, LogicalTime const & theTime, OrderType receivedOrder) throw (ObjectInstanceNotKnown, AttributeNotRecognized, AttributeNotSubscribed, FederateInternalError); virtual void reflectAttributeValues (ObjectInstanceHandle theObject, AttributeHandleValueMap const & theAttributeValues, VariableLengthData const & theUserSuppliedTag, OrderType sentOrder, TransportationType theType, LogicalTime const & theTime, OrderType receivedOrder, RegionHandleSet const & theSentRegionHandleSet) throw (ObjectInstanceNotKnown, AttributeNotRecognized, AttributeNotSubscribed, FederateInternalError); virtual void reflectAttributeValues (ObjectInstanceHandle theObject, AttributeHandleValueMap const & theAttributeValues, VariableLengthData const & theUserSuppliedTag, OrderType sentOrder, TransportationType theType, LogicalTime const & theTime, OrderType receivedOrder, MessageRetractionHandle theHandle) throw (ObjectInstanceNotKnown, AttributeNotRecognized, AttributeNotSubscribed, InvalidLogicalTime, FederateInternalError); virtual void reflectAttributeValues (ObjectInstanceHandle theObject, AttributeHandleValueMap const & theAttributeValues, VariableLengthData const & theUserSuppliedTag, OrderType sentOrder, TransportationType theType, LogicalTime const & theTime, OrderType receivedOrder, MessageRetractionHandle theHandle, RegionHandleSet const & theSentRegionHandleSet) throw (ObjectInstanceNotKnown, AttributeNotRecognized, AttributeNotSubscribed, InvalidLogicalTime, FederateInternalError); // 6.9 virtual void receiveInteraction (InteractionClassHandle theInteraction, ParameterHandleValueMap const & theParameterValues, VariableLengthData const & theUserSuppliedTag, OrderType sentOrder, TransportationType theType) throw (InteractionClassNotRecognized, InteractionParameterNotRecognized, InteractionClassNotSubscribed, FederateInternalError); virtual void receiveInteraction (InteractionClassHandle theInteraction, ParameterHandleValueMap const & theParameterValues, VariableLengthData const & theUserSuppliedTag, OrderType sentOrder, TransportationType theType, RegionHandleSet const & theSentRegionHandleSet) throw (InteractionClassNotRecognized, InteractionParameterNotRecognized, InteractionClassNotSubscribed, FederateInternalError); virtual void receiveInteraction (InteractionClassHandle theInteraction, ParameterHandleValueMap const & theParameterValues, VariableLengthData const & theUserSuppliedTag, OrderType sentOrder, TransportationType theType, LogicalTime const & theTime, OrderType receivedOrder) throw (InteractionClassNotRecognized, InteractionParameterNotRecognized, InteractionClassNotSubscribed, FederateInternalError); virtual void receiveInteraction (InteractionClassHandle theInteraction, ParameterHandleValueMap const & theParameterValues, VariableLengthData const & theUserSuppliedTag, OrderType sentOrder, TransportationType theType, LogicalTime const & theTime, OrderType receivedOrder, RegionHandleSet const & theSentRegionHandleSet) throw (InteractionClassNotRecognized, InteractionParameterNotRecognized, InteractionClassNotSubscribed, FederateInternalError); virtual void receiveInteraction (InteractionClassHandle theInteraction, ParameterHandleValueMap const & theParameterValues, VariableLengthData const & theUserSuppliedTag, OrderType sentOrder, TransportationType theType, LogicalTime const & theTime, OrderType receivedOrder, MessageRetractionHandle theHandle) throw (InteractionClassNotRecognized, InteractionParameterNotRecognized, InteractionClassNotSubscribed, InvalidLogicalTime, FederateInternalError); virtual void receiveInteraction (InteractionClassHandle theInteraction, ParameterHandleValueMap const & theParameterValues, VariableLengthData const & theUserSuppliedTag, OrderType sentOrder, TransportationType theType, LogicalTime const & theTime, OrderType receivedOrder, MessageRetractionHandle theHandle, RegionHandleSet const & theSentRegionHandleSet) throw (InteractionClassNotRecognized, InteractionParameterNotRecognized, InteractionClassNotSubscribed, InvalidLogicalTime, FederateInternalError); virtual void removeObjectInstance(ObjectInstanceHandle theObject, VariableLengthData const & theUserSuppliedTag, OrderType sentOrder) throw (ObjectInstanceNotKnown, FederateInternalError); virtual void removeObjectInstance(ObjectInstanceHandle theObject, VariableLengthData const & theUserSuppliedTag, OrderType sentOrder, LogicalTime const & theTime, OrderType receivedOrder) throw (ObjectInstanceNotKnown, FederateInternalError); virtual void removeObjectInstance(ObjectInstanceHandle theObject, VariableLengthData const & theUserSuppliedTag, OrderType sentOrder, LogicalTime const & theTime, OrderType receivedOrder, MessageRetractionHandle theHandle) throw (ObjectInstanceNotKnown, InvalidLogicalTime, FederateInternalError); virtual void provideAttributeValueUpdate(ObjectInstanceHandle theObject, AttributeHandleSet const & theAttributes, VariableLengthData const & theUserSuppliedTag) throw (ObjectInstanceNotKnown, AttributeNotRecognized, AttributeNotOwned, FederateInternalError); virtual void timeRegulationEnabled(LogicalTime const & theFederateTime) throw (InvalidLogicalTime, NoRequestToEnableTimeRegulationWasPending, FederateInternalError); virtual void timeConstrainedEnabled(LogicalTime const & theFederateTime) throw (InvalidLogicalTime, NoRequestToEnableTimeConstrainedWasPending, FederateInternalError); virtual void timeAdvanceGrant(LogicalTime const & theTime) throw (InvalidLogicalTime, JoinedFederateIsNotInTimeAdvancingState, FederateInternalError); virtual void requestRetraction(MessageRetractionHandle theHandle) throw (FederateInternalError); virtual void synchronizationPointRegistrationSucceeded(std::wstring const & label ) throw (FederateInternalError); virtual void synchronizationPointRegistrationFailed(std::wstring const & label, SynchronizationFailureReason reason) throw (FederateInternalError); virtual void announceSynchronizationPoint(std::wstring const & label, VariableLengthData const & theUserSuppliedTag) throw (FederateInternalError); virtual void federationSynchronized(std::wstring const & label) throw (FederateInternalError); public: DtTalkAmbData & myData; }; #endif
/******************************************************************************* * Adapted from "Beginning Linux Programming", from Wrox Press -- www.wrox.com *******************************************************************************/ /******************************************************************************* ** $RCSfile: simpleTimeKeyboard.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: 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: simpleTimeTimeManagedEntity.h,v $ $Revision: 1.3 $ $State: Exp $ *******************************************************************************/ #ifndef _TIMEMANAGEDOBJECTDEFINITION_ #define _TIMEMANAGEDOBJECTDEFINITION_ // A simple object that dictates the behavior of an advancing entity. #ifdef DtIFSPEC1516 #include "simpleTimeAttribute1516.h" #include "simpleTimeInteraction1516.h" #elif defined(DtIFSPEC1516E) #include "simpleTimeAttribute1516e.h" #include "simpleTimeInteraction1516e.h" #else #ifdef DtIFSPEC13DLC #include "simpleTimeAttribute13dlc.h" #include "simpleTimeInteraction13dlc.h" #else #include "simpleTimeAttribute13.h" #include "simpleTimeInteraction13.h" #endif #endif #include <queue> class timeManagedEntity { public: enum entity_state{ Alive = 0, FiredUpon = 1, Damaged = 2, Dead = 3 }; enum active_state{ Initial = 0, Firing = 1, SendDetonate = 3, Idle = 5}; // constructor and destructor for timeManagedEntity timeManagedEntity(); ~timeManagedEntity(); // Peek at our queue's of attributes and Interaction to see if there // is an event waiting to be processed. bool attrUpdateWaiting(); bool interactionWaiting(); // retreive an event from one of the event queue's attributeUpdateEvent* getNextAttrUpdateEvent(); interactionEvent* getNextInteractionEvent(); // add an event to our event queue. void addAttrUpdateEvent(attributeUpdateEvent*); void addInteractionEvent(interactionEvent*); // access this timeManagedEntity's state. bool shouldFire(); bool shouldDetonate(); bool isFiredUpon(); bool isDetonated(); // Change this timeManagedEntity's state. void setPhaseLine(int phaseLine); void incPosition(); void firePressed(); void reset(); // Sets myState to the correct Value. void tick(); private: void sendFire(); void sendDetonate(); void processEvents(); private: bool myFirePressed; unsigned int myPosition; unsigned int myVelocity; // myPhaseLine acts as a boundary for this federate. When the position of the timeManagedEntity is past // the myPhaseLine, the timeManagedEntity will start firing on other federates. unsigned int myPhaseLine; entity_state myPhysicalState; active_state myState; std::queue< attributeUpdateEvent* > myAttrUpdateQueue; std::queue< interactionEvent* > myInteractionQueue; }; #endif
/******************************************************************************* ** Copyright (c) 2004 MaK Technologies, Inc. ** All rights reserved. *******************************************************************************/ /******************************************************************************* ** $RCSfile: simpleTimeStringUtil.h,v $ $Revision: 1.2 $ $State: Exp $ *******************************************************************************/ #ifndef stringUtil_H_ #define stringUtil_H_ #include <string> #include <sstream> #include <iomanip> #include <iostream> using namespace std; // Convert narrow C string to wide string inline wstring DtToWString(const char * in_val) { wstring temp; while (*in_val != '\0') temp += *in_val++; return temp; } // Convert narrow string to wide string inline string DtToString(const wstring &in_val) { string temp; wstring::const_iterator b = in_val.begin(); const wstring::const_iterator e = in_val.end(); while (b != e) { temp += static_cast<char>(*b); ++b; } return temp; } inline string usage() { ostringstream ostr; ostr << "Usage: simpletime13/1516(d) [-fedFile fedFileName][-m #Federates][-phaseLine #][-sleepTime s][-dedicated][-unManaged]" << endl << endl << setw( 20 ) << " -fedFile " << " Specify the Fed file name \n" << setw ( 24 ) << " " << "Default : MAKsimple.xml/fed. \n" << setw( 20 ) << " -m " << " Specify whether this federate is the master and if so, how many \n" << setw( 24 ) << " " << "total federates it should wait for. \n" << setw( 20 ) << " -phaseLine " << " Specify the boundary, which when this federate\n" << setw( 24 ) << " " << "crosses it, it starts firing.\n" << setw( 24 ) << " " << " Default is 75 units. \n" << setw( 20 ) << " -sleepTime " << " Specify the time in ms to sleep between iterations of the main loop. \n" << setw( 24 ) << " " << " Default is 850 ms. \n" << setw( 20 ) << " -dedicated " << " Specify whether this federate is on a machine dedicated to running\n" << setw( 24 ) << " " << " this federate. Invalidates all sleeps and yields.\n" << setw( 20 ) << " -unManaged " << " Specify whether this federate will respect the synchronization step\n" << setw( 24 ) << " " << " before time advancing.\n" << endl; return ostr.str(); } template< class T > bool convert( const string& param, const string& value, T& dest ) { istringstream convert( value ); convert >> dest; if ( convert.fail() ) { std::cout << "Bad Parameter Value\n" << "Param: " << param << "\tValue: " << value << endl; return false; } return true; } #endif
/******************************************************************************* ** Copyright (c) 2006 MaK Technologies, Inc. ** All rights reserved. *******************************************************************************/ /******************************************************************************* ** $RCSfile: simpleTimeAttribute1516.h,v $ $Revision: 1.1 $ $State: Exp $ *******************************************************************************/ #ifndef _ATTRIBUTE1516DEFINITION_ #define _ATTRIBUTE1516DEFINITION_ #ifdef DtIFSPEC1516 // A simple container class for an attribute update event. #include <map> #include <string> #include <RTI/RTI1516.h> #include <RTI/RTIambassadorFactory.h> #include <iostream> using namespace rti1516; // An attributeUpdateEvent object encapsulates the contents of a // reflectattributeupdates callback. Note, that not all contents of the // callback are stored, only those required for our specific application. // That information can then be stored and later retrieved to be processed. class attributeUpdateEvent { public: attributeUpdateEvent( AttributeHandleValueMap const & ahvps, VariableLengthData const & theUserSuppliedTag, const OrderType sentOrder, const TransportationType theType, LogicalTime const& fedTime ); attributeUpdateEvent( AttributeHandleValueMap const & ahvps, VariableLengthData const & theUserSuppliedTag, const OrderType sentOrder, const TransportationType theType ); ~attributeUpdateEvent(); const std::map<AttributeHandle, std::string>& getAhvps(); const std::string& getFedTime(); const std::string& getTag(); MessageRetractionHandle getRetractionHandle(); private: std::map<AttributeHandle, std::string> myAhvps; std::string myFedTime; std::string myTag; MessageRetractionHandle myRetractionHandle; }; #endif // #ifdef DtIFSPEC1516 #endif // #define _ATTRIBUTE1516DEFINITION_
/******************************************************************************* ** Copyright (c) 2006 MaK Technologies, Inc. ** All rights reserved. *******************************************************************************/ /******************************************************************************* ** $RCSfile: simpleTimeInteraction1516.h,v $ $Revision: 1.2 $ $State: Exp $ *******************************************************************************/ #ifndef _INTERACTIONDEFINITION_ #define _INTERACTIONDEFINITION_ // A simple container class for an interaction event #include <map> #include <string> #include <RTI/RTI1516.h> #include <RTI/RTIambassadorFactory.h> #include "simpleTimeStringUtil.h" // An interactionEvent object encapsulates the contents of a // receiveInteraction callback. Note, that not all contents of the // callback are stored, only those required for our specific application. // That information can then be stored and later retrieved to be processed. class interactionEvent { public: enum interaction_type{ Unknown, FireType, DetonationType }; interactionEvent(const rti1516::InteractionClassHandle theHandle, const rti1516::ParameterHandleValueMap& pvhps, const rti1516::VariableLengthData& userSuppliedTag, const rti1516::OrderType sentOrder, const rti1516::TransportationType theType, const rti1516::LogicalTime& fedTime, const rti1516::OrderType receivedOrder, rti1516::MessageRetractionHandle theRetractionHandle, interaction_type theInteractionType = Unknown ); interactionEvent(const rti1516::InteractionClassHandle theHandle, const rti1516::ParameterHandleValueMap& pvhps, const rti1516::VariableLengthData& userSuppliedTag, const rti1516::OrderType sentOrder, const rti1516::TransportationType theType, const rti1516::LogicalTime& fedTime, const rti1516::OrderType receivedOrder, interaction_type theInteractionType = Unknown ); interactionEvent(const rti1516::InteractionClassHandle theHandle, const rti1516::ParameterHandleValueMap& pvhps, const rti1516::VariableLengthData& userSuppliedTag, const rti1516::OrderType sentOrder, const rti1516::TransportationType theType, interaction_type theInteractionType = Unknown ); ~interactionEvent(); rti1516::InteractionClassHandle getHandle(); // const std::map<rti1516::ParameterHandle, std::string>& getPhvps(); bool isFireInteraction(); bool isDetonateInteraction(); const std::string& getFedTime(); const std::string& getTag(); const rti1516::MessageRetractionHandle& getRetractionHandle(); int getTypeOfInteraction(); private: rti1516::InteractionClassHandle myHandle; std::map<rti1516::ParameterHandle, std::string> myPhvps; std::string myFedTime; std::string myTag; rti1516::MessageRetractionHandle myRetractionHandle; int myInteractionType; }; #endif