X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fhla%2FRTI13Federate.cxx;h=a9953b9381496c5962f61af16642956eddc6050c;hb=264e336a4941a719362c75b3415a92e9098b2719;hp=8dad3367ab0610b9384bcc2037a6bb0d79b8d596;hpb=baf511684119e219906fa37f3e7c7f43151bb435;p=simgear.git diff --git a/simgear/hla/RTI13Federate.cxx b/simgear/hla/RTI13Federate.cxx index 8dad3367..a9953b93 100644 --- a/simgear/hla/RTI13Federate.cxx +++ b/simgear/hla/RTI13Federate.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de +// Copyright (C) 2009 - 2011 Mathias Froehlich - Mathias.Froehlich@web.de // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Library General Public @@ -21,92 +21,656 @@ namespace simgear { -RTI13Federate::RTI13Federate() : - _tickTimeout(10), - _ambassador(new RTI13Ambassador) +static std::string toStdString(const char* n) { + if (!n) + return std::string(); + return std::string(n); +} + +/// Just the interface class doing the callbacks into the parent class +struct RTI13Federate::FederateAmbassador : public RTI::FederateAmbassador { + FederateAmbassador() : + _timeRegulationEnabled(false), + _timeConstrainedEnabled(false), + _timeAdvancePending(false) + { + } + virtual ~FederateAmbassador() + throw (RTI::FederateInternalError) + { + } + + /// RTI federate ambassador callback functions. + virtual void synchronizationPointRegistrationSucceeded(const char* label) + throw (RTI::FederateInternalError) + { + } + + virtual void synchronizationPointRegistrationFailed(const char* label) + throw (RTI::FederateInternalError) + { + } + + virtual void announceSynchronizationPoint(const char* label, const char* tag) + throw (RTI::FederateInternalError) + { + _pendingSyncLabels.insert(toStdString(label)); + } + + virtual void federationSynchronized(const char* label) + throw (RTI::FederateInternalError) + { + std::string s = toStdString(label); + _pendingSyncLabels.erase(s); + _syncronizedSyncLabels.insert(s); + } + + virtual void initiateFederateSave(const char* label) + throw (RTI::UnableToPerformSave, + RTI::FederateInternalError) + { + } + + virtual void federationSaved() + throw (RTI::FederateInternalError) + { + } + + virtual void federationNotSaved() + throw (RTI::FederateInternalError) + { + } + + virtual void requestFederationRestoreSucceeded(const char* label) + throw (RTI::FederateInternalError) + { + } + + virtual void requestFederationRestoreFailed(const char* label, const char* reason) + throw (RTI::FederateInternalError) + { + } + + virtual void federationRestoreBegun() + throw (RTI::FederateInternalError) + { + } + + virtual void initiateFederateRestore(const char* label, RTI::FederateHandle federateHandle) + throw (RTI::SpecifiedSaveLabelDoesNotExist, + RTI::CouldNotRestore, + RTI::FederateInternalError) + { + } + + virtual void federationRestored() + throw (RTI::FederateInternalError) + { + } + + virtual void federationNotRestored() + throw (RTI::FederateInternalError) + { + } + + // Declaration Management + virtual void startRegistrationForObjectClass(RTI::ObjectClassHandle objectClassHandle) + throw (RTI::ObjectClassNotPublished, + RTI::FederateInternalError) + { + ObjectClassMap::iterator i = _objectClassMap.find(objectClassHandle); + if (i == _objectClassMap.end()) + return; + if (!i->second.valid()) + return; + i->second->startRegistration(); + } + + virtual void stopRegistrationForObjectClass(RTI::ObjectClassHandle objectClassHandle) + throw (RTI::ObjectClassNotPublished, + RTI::FederateInternalError) + { + ObjectClassMap::iterator i = _objectClassMap.find(objectClassHandle); + if (i == _objectClassMap.end()) + return; + if (!i->second.valid()) + return; + i->second->stopRegistration(); + } + + virtual void turnInteractionsOn(RTI::InteractionClassHandle interactionClassHandle) + throw (RTI::InteractionClassNotPublished, + RTI::FederateInternalError) + { + } + + virtual void turnInteractionsOff(RTI::InteractionClassHandle interactionClassHandle) + throw (RTI::InteractionClassNotPublished, + RTI::FederateInternalError) + { + } + + + // Object Management + virtual void discoverObjectInstance(RTI::ObjectHandle objectHandle, RTI::ObjectClassHandle objectClassHandle, const char* tag) + throw (RTI::CouldNotDiscover, + RTI::ObjectClassNotKnown, + RTI::FederateInternalError) + { + ObjectClassMap::iterator i = _objectClassMap.find(objectClassHandle); + if (i == _objectClassMap.end()) + throw RTI::ObjectClassNotKnown("Federate: discoverObjectInstance()!"); + if (!i->second.valid()) + return; + SGSharedPtr objectInstance = new RTI13ObjectInstance(objectHandle, 0, i->second, _rtiAmbassador.get(), false); + _objectInstanceMap[objectHandle] = objectInstance; + _queueCallbackList.push_back(new DiscoverObjectCallback(i->second, objectInstance, tagToData(tag))); + } + + virtual void reflectAttributeValues(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleValuePairSet& attributeValuePairSet, + const RTI::FedTime& fedTime, const char* tag, RTI::EventRetractionHandle eventRetractionHandle) + throw (RTI::ObjectNotKnown, + RTI::AttributeNotKnown, + RTI::FederateOwnsAttributes, + RTI::InvalidFederationTime, + RTI::FederateInternalError) + { + ObjectInstanceMap::iterator i = _objectInstanceMap.find(objectHandle); + if (i == _objectInstanceMap.end()) + throw RTI::ObjectNotKnown("Reflect attributes for unknown object!"); + if (!i->second.valid()) + return; + i->second->reflectAttributeValues(attributeValuePairSet, RTI13Ambassador::toTimeStamp(fedTime), tagToData(tag)); + } + + virtual void reflectAttributeValues(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleValuePairSet& attributeValuePairSet, + const char* tag) + throw (RTI::ObjectNotKnown, + RTI::AttributeNotKnown, + RTI::FederateOwnsAttributes, + RTI::FederateInternalError) + { + ObjectInstanceMap::iterator i = _objectInstanceMap.find(objectHandle); + if (i == _objectInstanceMap.end()) + throw RTI::ObjectNotKnown("Reflect attributes for unknown object!"); + if (!i->second.valid()) + return; + i->second->reflectAttributeValues(attributeValuePairSet, tagToData(tag)); + } + + virtual void receiveInteraction(RTI::InteractionClassHandle interactionClassHandle, const RTI::ParameterHandleValuePairSet& parameters, + const RTI::FedTime& fedTime, const char* tag, RTI::EventRetractionHandle eventRetractionHandle) + throw (RTI::InteractionClassNotKnown, + RTI::InteractionParameterNotKnown, + RTI::InvalidFederationTime, + RTI::FederateInternalError) + { + } + + virtual void receiveInteraction(RTI::InteractionClassHandle interactionClassHandle, + const RTI::ParameterHandleValuePairSet& parameters, const char* tag) + throw (RTI::InteractionClassNotKnown, + RTI::InteractionParameterNotKnown, + RTI::FederateInternalError) + { + } + + virtual void removeObjectInstance(RTI::ObjectHandle objectHandle, const RTI::FedTime& fedTime, + const char* tag, RTI::EventRetractionHandle eventRetractionHandle) + throw (RTI::ObjectNotKnown, + RTI::InvalidFederationTime, + RTI::FederateInternalError) + { + ObjectInstanceMap::iterator i = _objectInstanceMap.find(objectHandle); + if (i == _objectInstanceMap.end()) + throw RTI::ObjectNotKnown("Federate: removeObjectInstance()!"); + if (i->second.valid()) + _queueCallbackList.push_back(new RemoveObjectCallback(i->second, tagToData(tag))); + _objectInstanceMap.erase(i); + } + + virtual void removeObjectInstance(RTI::ObjectHandle objectHandle, const char* tag) + throw (RTI::ObjectNotKnown, + RTI::FederateInternalError) + { + ObjectInstanceMap::iterator i = _objectInstanceMap.find(objectHandle); + if (i == _objectInstanceMap.end()) + throw RTI::ObjectNotKnown("Federate: removeObjectInstance()!"); + if (i->second.valid()) + _queueCallbackList.push_back(new RemoveObjectCallback(i->second, tagToData(tag))); + _objectInstanceMap.erase(i); + } + + virtual void attributesInScope(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleSet& attributes) + throw (RTI::ObjectNotKnown, + RTI::AttributeNotKnown, + RTI::FederateInternalError) + { + ObjectInstanceMap::iterator i = _objectInstanceMap.find(objectHandle); + if (i == _objectInstanceMap.end()) + throw RTI::ObjectNotKnown("Attributes in scope for unknown object!"); + if (!i->second.valid()) + return; + i->second->attributesInScope(attributes); + } + + virtual void attributesOutOfScope(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleSet& attributes) + throw (RTI::ObjectNotKnown, + RTI::AttributeNotKnown, + RTI::FederateInternalError) + { + ObjectInstanceMap::iterator i = _objectInstanceMap.find(objectHandle); + if (i == _objectInstanceMap.end()) + throw RTI::ObjectNotKnown("Attributes in scope for unknown object!"); + if (!i->second.valid()) + return; + i->second->attributesOutOfScope(attributes); + } + + virtual void provideAttributeValueUpdate(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleSet& attributes) + throw (RTI::ObjectNotKnown, + RTI::AttributeNotKnown, + RTI::AttributeNotOwned, + RTI::FederateInternalError) + { + ObjectInstanceMap::iterator i = _objectInstanceMap.find(objectHandle); + if (i == _objectInstanceMap.end()) + throw RTI::ObjectNotKnown("Reflect attributes for unknown object!"); + if (!i->second.valid()) + return; + i->second->provideAttributeValueUpdate(attributes); + } + + virtual void turnUpdatesOnForObjectInstance(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleSet& attributes) + throw (RTI::ObjectNotKnown, + RTI::AttributeNotOwned, + RTI::FederateInternalError) + { + ObjectInstanceMap::iterator i = _objectInstanceMap.find(objectHandle); + if (i == _objectInstanceMap.end()) + throw RTI::ObjectNotKnown("Turn on attributes for unknown object!"); + if (!i->second.valid()) + return; + i->second->turnUpdatesOnForObjectInstance(attributes); + } + + virtual void turnUpdatesOffForObjectInstance(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleSet& attributes) + throw (RTI::ObjectNotKnown, + RTI::AttributeNotOwned, + RTI::FederateInternalError) + { + ObjectInstanceMap::iterator i = _objectInstanceMap.find(objectHandle); + if (i == _objectInstanceMap.end()) + throw RTI::ObjectNotKnown("Turn off attributes for unknown object!"); + if (!i->second.valid()) + return; + i->second->turnUpdatesOffForObjectInstance(attributes); + } + + // Ownership Management + virtual void requestAttributeOwnershipAssumption(RTI::ObjectHandle objectHandle, + const RTI::AttributeHandleSet& attributes, const char* tag) + throw (RTI::ObjectNotKnown, + RTI::AttributeNotKnown, + RTI::AttributeAlreadyOwned, + RTI::AttributeNotPublished, + RTI::FederateInternalError) + { + ObjectInstanceMap::iterator i = _objectInstanceMap.find(objectHandle); + if (i == _objectInstanceMap.end()) + throw RTI::ObjectNotKnown("requestAttributeOwnershipAssumption for unknown object!"); + if (!i->second.valid()) + return; + i->second->requestAttributeOwnershipAssumption(attributes, tagToData(tag)); + } + + virtual void attributeOwnershipDivestitureNotification(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleSet& attributes) + throw (RTI::ObjectNotKnown, + RTI::AttributeNotKnown, + RTI::AttributeNotOwned, + RTI::AttributeDivestitureWasNotRequested, + RTI::FederateInternalError) + { + ObjectInstanceMap::iterator i = _objectInstanceMap.find(objectHandle); + if (i == _objectInstanceMap.end()) + throw RTI::ObjectNotKnown("attributeOwnershipDivestitureNotification for unknown object!"); + if (!i->second.valid()) + return; + i->second->attributeOwnershipDivestitureNotification(attributes); + } + + virtual void attributeOwnershipAcquisitionNotification(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleSet& attributes) + throw (RTI::ObjectNotKnown, + RTI::AttributeNotKnown, + RTI::AttributeAcquisitionWasNotRequested, + RTI::AttributeAlreadyOwned, + RTI::AttributeNotPublished, + RTI::FederateInternalError) + { + ObjectInstanceMap::iterator i = _objectInstanceMap.find(objectHandle); + if (i == _objectInstanceMap.end()) + throw RTI::ObjectNotKnown("attributeOwnershipAcquisitionNotification for unknown object!"); + if (!i->second.valid()) + return; + i->second->attributeOwnershipAcquisitionNotification(attributes); + } + + virtual void attributeOwnershipUnavailable(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleSet& attributes) + throw (RTI::ObjectNotKnown, + RTI::AttributeNotKnown, + RTI::AttributeAlreadyOwned, + RTI::AttributeAcquisitionWasNotRequested, + RTI::FederateInternalError) + { + ObjectInstanceMap::iterator i = _objectInstanceMap.find(objectHandle); + if (i == _objectInstanceMap.end()) + throw RTI::ObjectNotKnown("attributeOwnershipUnavailable for unknown object!"); + if (!i->second.valid()) + return; + i->second->attributeOwnershipUnavailable(attributes); + } + + virtual void requestAttributeOwnershipRelease(RTI::ObjectHandle objectHandle, + const RTI::AttributeHandleSet& attributes, const char* tag) + throw (RTI::ObjectNotKnown, + RTI::AttributeNotKnown, + RTI::AttributeNotOwned, + RTI::FederateInternalError) + { + ObjectInstanceMap::iterator i = _objectInstanceMap.find(objectHandle); + if (i == _objectInstanceMap.end()) + throw RTI::ObjectNotKnown("requestAttributeOwnershipRelease for unknown object!"); + if (!i->second.valid()) + return; + i->second->requestAttributeOwnershipRelease(attributes, tagToData(tag)); + } + + virtual void confirmAttributeOwnershipAcquisitionCancellation(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleSet& attributes) + throw (RTI::ObjectNotKnown, + RTI::AttributeNotKnown, + RTI::AttributeAlreadyOwned, + RTI::AttributeAcquisitionWasNotCanceled, + RTI::FederateInternalError) + { + ObjectInstanceMap::iterator i = _objectInstanceMap.find(objectHandle); + if (i == _objectInstanceMap.end()) + throw RTI::ObjectNotKnown("confirmAttributeOwnershipAcquisitionCancellation for unknown object!"); + if (!i->second.valid()) + return; + i->second->confirmAttributeOwnershipAcquisitionCancellation(attributes); + } + + virtual void informAttributeOwnership(RTI::ObjectHandle objectHandle, RTI::AttributeHandle attributeHandle, + RTI::FederateHandle federateHandle) + throw (RTI::ObjectNotKnown, + RTI::AttributeNotKnown, + RTI::FederateInternalError) + { + ObjectInstanceMap::iterator i = _objectInstanceMap.find(objectHandle); + if (i == _objectInstanceMap.end()) + throw RTI::ObjectNotKnown("informAttributeOwnership for unknown object!"); + if (!i->second.valid()) + return; + i->second->informAttributeOwnership(attributeHandle, federateHandle); + } + + virtual void attributeIsNotOwned(RTI::ObjectHandle objectHandle, RTI::AttributeHandle attributeHandle) + throw (RTI::ObjectNotKnown, + RTI::AttributeNotKnown, + RTI::FederateInternalError) + { + ObjectInstanceMap::iterator i = _objectInstanceMap.find(objectHandle); + if (i == _objectInstanceMap.end()) + throw RTI::ObjectNotKnown("attributeIsNotOwned for unknown object!"); + if (!i->second.valid()) + return; + i->second->attributeIsNotOwned(attributeHandle); + } + + virtual void attributeOwnedByRTI(RTI::ObjectHandle objectHandle, RTI::AttributeHandle attributeHandle) + throw (RTI::ObjectNotKnown, + RTI::AttributeNotKnown, + RTI::FederateInternalError) + { + ObjectInstanceMap::iterator i = _objectInstanceMap.find(objectHandle); + if (i == _objectInstanceMap.end()) + throw RTI::ObjectNotKnown("attributeOwnedByRTI for unknown object!"); + if (!i->second.valid()) + return; + i->second->attributeOwnedByRTI(attributeHandle); + } + + // Time Management + virtual void timeRegulationEnabled(const RTI::FedTime& fedTime) + throw (RTI::InvalidFederationTime, + RTI::EnableTimeRegulationWasNotPending, + RTI::FederateInternalError) + { + _timeRegulationEnabled = true; + _federateTime = RTI13Ambassador::toTimeStamp(fedTime); + SG_LOG(SG_NETWORK, SG_INFO, "RTI: timeRegulationEnabled: " << _federateTime); + } + + virtual void timeConstrainedEnabled(const RTI::FedTime& fedTime) + throw (RTI::InvalidFederationTime, + RTI::EnableTimeConstrainedWasNotPending, + RTI::FederateInternalError) + { + _timeConstrainedEnabled = true; + _federateTime = RTI13Ambassador::toTimeStamp(fedTime); + SG_LOG(SG_NETWORK, SG_INFO, "RTI: timeConstrainedEnabled: " << _federateTime); + } + + virtual void timeAdvanceGrant(const RTI::FedTime& fedTime) + throw (RTI::InvalidFederationTime, + RTI::TimeAdvanceWasNotInProgress, + RTI::FederateInternalError) + { + _federateTime = RTI13Ambassador::toTimeStamp(fedTime); + _timeAdvancePending = false; + SG_LOG(SG_NETWORK, SG_INFO, "RTI: timeAdvanceGrant: " << _federateTime); + } + + virtual void requestRetraction(RTI::EventRetractionHandle eventRetractionHandle) + throw (RTI::EventNotKnown, + RTI::FederateInternalError) + { + // No retraction concept yet + } + + // processes the queues that filled up during the past + void processQueues() + { + while (!_queueCallbackList.empty()) { + (*_queueCallbackList.front())(); + _queueCallbackList.pop_front(); + } + } + + bool getFederationSynchronizationPointAnnounced(const std::string& label) + { return _pendingSyncLabels.find(label) != _pendingSyncLabels.end(); } + bool getFederationSynchronized(const std::string& label) + { + std::set::iterator i = _syncronizedSyncLabels.find(label); + if (i == _syncronizedSyncLabels.end()) + return false; + _syncronizedSyncLabels.erase(i); + return true; + } + + /// Generic callback to execute some notification on objects in a way that they are not prone to + /// ConcurrentAccess exceptions. + class QueueCallback : public SGReferenced { + public: + virtual ~QueueCallback() {} + virtual void operator()() = 0; + }; + + class DiscoverObjectCallback : public QueueCallback { + public: + DiscoverObjectCallback(SGSharedPtr objectClass, SGSharedPtr objectInstance, const RTIData& tag) : + _objectClass(objectClass), + _objectInstance(objectInstance), + _tag(tag) + { } + virtual void operator()() + { + _objectClass->discoverInstance(_objectInstance.get(), _tag); + _objectInstance->requestObjectAttributeValueUpdate(); + } + private: + SGSharedPtr _objectClass; + SGSharedPtr _objectInstance; + RTIData _tag; + }; + class RemoveObjectCallback : public QueueCallback { + public: + RemoveObjectCallback(SGSharedPtr objectInstance, const RTIData& tag) : + _objectInstance(objectInstance), + _tag(tag) + { } + virtual void operator()() + { + _objectInstance->removeInstance(_tag); + } + private: + SGSharedPtr _objectInstance; + RTIData _tag; + }; + + // The rtiambassador to issue requests + SGSharedPtr _rtiAmbassador; + + // All the sync labels we got an announcement for + std::set _pendingSyncLabels; + std::set _syncronizedSyncLabels; + + // All that calls back into user code is just queued. + // That is to make sure we do not call recursively into the RTI + typedef std::list > QueueCallbackList; + QueueCallbackList _queueCallbackList; + + // Top level information for dispatching federate object attribute updates + typedef std::map > ObjectInstanceMap; + // Map of all available objects + ObjectInstanceMap _objectInstanceMap; + + // Top level information for dispatching creation of federate objects + typedef std::map > ObjectClassMap; + ObjectClassMap _objectClassMap; + + bool _timeRegulationEnabled; + bool _timeConstrainedEnabled; + bool _timeAdvancePending; + SGTimeStamp _federateTime; + +private: + const RTIData& tagToData(const char* tag) + { + if (tag) + _cachedTag.setData(tag, std::strlen(tag) + 1); + else + _cachedTag.setData("", 1); + return _cachedTag; + } + RTIData _cachedTag; +}; + +RTI13Federate::RTI13Federate(const std::list& stringList) : + _joined(false), + _ambassador(new RTI13Ambassador), + _federateAmbassador(new FederateAmbassador) +{ + _ambassador->_federate = this; + _federateAmbassador->_rtiAmbassador = _ambassador; + if (stringList.empty()) { + SG_LOG(SG_NETWORK, SG_WARN, "RTI: Ignoring non empty connect arguments while connecting to an RTI13 federation!"); + } } RTI13Federate::~RTI13Federate() { + if (_joined) + _ambassador->resignFederationExecution(); + delete _federateAmbassador; } -bool +RTI13Federate::FederationManagementResult RTI13Federate::createFederationExecution(const std::string& federationName, const std::string& objectModel) { try { _ambassador->createFederationExecution(federationName, objectModel); - return true; + return FederationManagementSuccess; } catch (RTI::FederationExecutionAlreadyExists& e) { - return true; + return FederationManagementFail; } catch (RTI::CouldNotOpenFED& e) { SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not create federation execution: " << e._name << " " << e._reason); - return false; + return FederationManagementFatal; } catch (RTI::ErrorReadingFED& e) { SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not create federation execution: " << e._name << " " << e._reason); - return false; + return FederationManagementFatal; } catch (RTI::ConcurrentAccessAttempted& e) { SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not create federation execution: " << e._name << " " << e._reason); - return false; + return FederationManagementFatal; } catch (RTI::RTIinternalError& e) { SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not create federation execution: " << e._name << " " << e._reason); - return false; + return FederationManagementFatal; } } -bool +RTI13Federate::FederationManagementResult RTI13Federate::destroyFederationExecution(const std::string& federation) { try { _ambassador->destroyFederationExecution(federation); - return true; + return FederationManagementSuccess; } catch (RTI::FederatesCurrentlyJoined& e) { - return true; + return FederationManagementFail; } catch (RTI::FederationExecutionDoesNotExist& e) { - return true; + return FederationManagementFail; } catch (RTI::ConcurrentAccessAttempted& e) { SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not destroy federation execution: " << e._name << " " << e._reason); - return false; + return FederationManagementFatal; } catch (RTI::RTIinternalError& e) { SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not destroy federation execution: " << e._name << " " << e._reason); - return false; + return FederationManagementFatal; } } -bool +RTI13Federate::FederationManagementResult RTI13Federate::join(const std::string& federateType, const std::string& federationName) { try { - _federateHandle = _ambassador->joinFederationExecution(federateType, federationName); + _federateHandle = _ambassador->joinFederationExecution(federateType, federationName, _federateAmbassador); SG_LOG(SG_NETWORK, SG_INFO, "RTI: Joined federation \"" << federationName << "\" as \"" << federateType << "\""); - setFederateType(federateType); - setFederationName(federationName); - return true; + _joined = true; + return FederationManagementSuccess; } catch (RTI::FederateAlreadyExecutionMember& e) { SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not join federation execution: " << e._name << " " << e._reason); - return false; + return FederationManagementFatal; } catch (RTI::FederationExecutionDoesNotExist& e) { SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not join federation execution: " << e._name << " " << e._reason); - return false; + return FederationManagementFail; } catch (RTI::CouldNotOpenFED& e) { SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not join federation execution: " << e._name << " " << e._reason); - return false; + return FederationManagementFatal; } catch (RTI::ErrorReadingFED& e) { SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not join federation execution: " << e._name << " " << e._reason); - return false; + return FederationManagementFatal; } catch (RTI::ConcurrentAccessAttempted& e) { SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not join federation execution: " << e._name << " " << e._reason); - return false; + return FederationManagementFatal; } catch (RTI::SaveInProgress& e) { SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not join federation execution: " << e._name << " " << e._reason); - return false; + return FederationManagementFatal; } catch (RTI::RestoreInProgress& e) { SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not join federation execution: " << e._name << " " << e._reason); - return false; + return FederationManagementFatal; } catch (RTI::RTIinternalError& e) { SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not join federation execution: " << e._name << " " << e._reason); - return false; + return FederationManagementFatal; } } @@ -116,6 +680,7 @@ RTI13Federate::resign() try { _ambassador->resignFederationExecution(); SG_LOG(SG_NETWORK, SG_INFO, "RTI: Resigned from federation."); + _joined = false; _federateHandle = -1; return true; } catch (RTI::FederateOwnsAttributes& e) { @@ -136,6 +701,12 @@ RTI13Federate::resign() } } +bool +RTI13Federate::getJoined() const +{ + return _joined; +} + bool RTI13Federate::registerFederationSynchronizationPoint(const std::string& label, const RTIData& tag) { @@ -162,13 +733,9 @@ RTI13Federate::registerFederationSynchronizationPoint(const std::string& label, } bool -RTI13Federate::waitForFederationSynchronizationPointAnnounced(const std::string& label) +RTI13Federate::getFederationSynchronizationPointAnnounced(const std::string& label) { - while (!_ambassador->getFederationSynchronizationPointAnnounced(label)) { - _ambassador->tick(_tickTimeout, 0); - _ambassador->processQueues(); - } - return true; + return _federateAmbassador->getFederationSynchronizationPointAnnounced(label); } bool @@ -200,13 +767,9 @@ RTI13Federate::synchronizationPointAchieved(const std::string& label) } bool -RTI13Federate::waitForFederationSynchronized(const std::string& label) +RTI13Federate::getFederationSynchronized(const std::string& label) { - while (!_ambassador->getFederationSynchronized(label)) { - _ambassador->tick(_tickTimeout, 0); - _ambassador->processQueues(); - } - return true; + return _federateAmbassador->getFederationSynchronized(label); } bool @@ -217,7 +780,7 @@ RTI13Federate::enableTimeConstrained() return false; } - if (_ambassador->getTimeConstrainedEnabled()) { + if (_federateAmbassador->_timeConstrainedEnabled) { SG_LOG(SG_NETWORK, SG_WARN, "RTI: Time constrained is already enabled."); return false; } @@ -250,11 +813,6 @@ RTI13Federate::enableTimeConstrained() return false; } - while (!_ambassador->getTimeConstrainedEnabled()) { - _ambassador->tick(_tickTimeout, 0); - _ambassador->processQueues(); - } - return true; } @@ -266,13 +824,14 @@ RTI13Federate::disableTimeConstrained() return false; } - if (!_ambassador->getTimeConstrainedEnabled()) { + if (!_federateAmbassador->_timeConstrainedEnabled) { SG_LOG(SG_NETWORK, SG_WARN, "RTI: Time constrained is not enabled."); return false; } try { _ambassador->disableTimeConstrained(); + _federateAmbassador->_timeConstrainedEnabled = false; } catch (RTI::TimeConstrainedWasNotEnabled& e) { SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason); return false; @@ -296,6 +855,12 @@ RTI13Federate::disableTimeConstrained() return true; } +bool +RTI13Federate::getTimeConstrainedEnabled() +{ + return _federateAmbassador->_timeConstrainedEnabled; +} + bool RTI13Federate::enableTimeRegulation(const SGTimeStamp& lookahead) { @@ -304,13 +869,13 @@ RTI13Federate::enableTimeRegulation(const SGTimeStamp& lookahead) return false; } - if (_ambassador->getTimeRegulationEnabled()) { + if (_federateAmbassador->_timeRegulationEnabled) { SG_LOG(SG_NETWORK, SG_WARN, "RTI: Time regulation already enabled."); return false; } try { - _ambassador->enableTimeRegulation(SGTimeStamp(), lookahead); + _ambassador->enableTimeRegulation(lookahead); } catch (RTI::TimeRegulationAlreadyEnabled& e) { SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason); return false; @@ -343,11 +908,6 @@ RTI13Federate::enableTimeRegulation(const SGTimeStamp& lookahead) return false; } - while (!_ambassador->getTimeRegulationEnabled()) { - _ambassador->tick(_tickTimeout, 0); - _ambassador->processQueues(); - } - return true; } @@ -359,13 +919,14 @@ RTI13Federate::disableTimeRegulation() return false; } - if (!_ambassador->getTimeRegulationEnabled()) { + if (!_federateAmbassador->_timeRegulationEnabled) { SG_LOG(SG_NETWORK, SG_WARN, "RTI: Time regulation is not enabled."); return false; } try { _ambassador->disableTimeRegulation(); + _federateAmbassador->_timeRegulationEnabled = false; } catch (RTI::TimeRegulationWasNotEnabled& e) { SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason); return false; @@ -390,19 +951,90 @@ RTI13Federate::disableTimeRegulation() } bool -RTI13Federate::timeAdvanceRequestBy(const SGTimeStamp& dt) +RTI13Federate::modifyLookahead(const SGTimeStamp& timeStamp) +{ + if (!_ambassador.valid()) { + SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not modify lookahead."); + return false; + } + try { + _ambassador->modifyLookahead(timeStamp); + } catch (RTI::InvalidLookahead& e) { + SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not modify lookahead: " << e._name << " " << e._reason); + return false; + } catch (RTI::FederateNotExecutionMember& e) { + SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not modify lookahead: " << e._name << " " << e._reason); + return false; + } catch (RTI::ConcurrentAccessAttempted& e) { + SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not modify lookahead: " << e._name << " " << e._reason); + return false; + } catch (RTI::SaveInProgress& e) { + SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not modify lookahead: " << e._name << " " << e._reason); + return false; + } catch (RTI::RestoreInProgress& e) { + SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not modify lookahead: " << e._name << " " << e._reason); + return false; + } catch (RTI::RTIinternalError& e) { + SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not modify lookahead: " << e._name << " " << e._reason); + return false; + } + return true; +} + +bool +RTI13Federate::getTimeRegulationEnabled() +{ + return _federateAmbassador->_timeRegulationEnabled; +} + +bool +RTI13Federate::timeAdvanceRequest(const SGTimeStamp& timeStamp) { if (!_ambassador.valid()) { SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not disable time regulation at unconnected federate."); return false; } - SGTimeStamp fedTime = _ambassador->getCurrentLogicalTime() + dt; - return timeAdvanceRequest(fedTime); + try { + _ambassador->timeAdvanceRequest(timeStamp); + _federateAmbassador->_timeAdvancePending = true; + } catch (RTI::InvalidFederationTime& e) { + SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason); + return false; + } catch (RTI::FederationTimeAlreadyPassed& e) { + SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason); + return false; + } catch (RTI::TimeAdvanceAlreadyInProgress& e) { + SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason); + return false; + } catch (RTI::EnableTimeRegulationPending& e) { + SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason); + return false; + } catch (RTI::EnableTimeConstrainedPending& e) { + SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason); + return false; + } catch (RTI::FederateNotExecutionMember& e) { + SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason); + return false; + } catch (RTI::ConcurrentAccessAttempted& e) { + SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason); + return false; + } catch (RTI::SaveInProgress& e) { + SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason); + return false; + } catch (RTI::RestoreInProgress& e) { + SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason); + return false; + } catch (RTI::RTIinternalError& e) { + SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason); + return false; + } + + return true; } bool -RTI13Federate::timeAdvanceRequest(const SGTimeStamp& fedTime) +RTI13Federate::timeAdvanceRequestAvailable(const SGTimeStamp& timeStamp) { if (!_ambassador.valid()) { SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not disable time regulation at unconnected federate."); @@ -410,7 +1042,8 @@ RTI13Federate::timeAdvanceRequest(const SGTimeStamp& fedTime) } try { - _ambassador->timeAdvanceRequest(fedTime); + _ambassador->timeAdvanceRequestAvailable(timeStamp); + _federateAmbassador->_timeAdvancePending = true; } catch (RTI::InvalidFederationTime& e) { SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not resign federation execution: " << e._name << " " << e._reason); return false; @@ -443,27 +1076,151 @@ RTI13Federate::timeAdvanceRequest(const SGTimeStamp& fedTime) return false; } - while (_ambassador->getTimeAdvancePending()) { - _ambassador->tick(_tickTimeout, 0); - _ambassador->processQueues(); + return true; +} + +bool +RTI13Federate::getTimeAdvancePending() +{ + return _federateAmbassador->_timeAdvancePending; +} + +bool +RTI13Federate::queryFederateTime(SGTimeStamp& timeStamp) +{ + if (!_ambassador.valid()) { + SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not query federate time."); + return false; + } + + try { + _ambassador->queryFederateTime(timeStamp); + } catch (RTI::FederateNotExecutionMember& e) { + SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not query federate time: " << e._name << " " << e._reason); + return false; + } catch (RTI::ConcurrentAccessAttempted& e) { + SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not query federate time: " << e._name << " " << e._reason); + return false; + } catch (RTI::SaveInProgress& e) { + SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not query federate time: " << e._name << " " << e._reason); + return false; + } catch (RTI::RestoreInProgress& e) { + SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not query federate time: " << e._name << " " << e._reason); + return false; + } catch (RTI::RTIinternalError& e) { + SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not query federate time: " << e._name << " " << e._reason); + return false; + } + return true; +} + +bool +RTI13Federate::queryLookahead(SGTimeStamp& timeStamp) +{ + if (!_ambassador.valid()) { + SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not query lookahead."); + return false; + } + + try { + _ambassador->queryLookahead(timeStamp); + } catch (RTI::FederateNotExecutionMember& e) { + SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not query lookahead: " << e._name << " " << e._reason); + return false; + } catch (RTI::ConcurrentAccessAttempted& e) { + SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not query lookahead: " << e._name << " " << e._reason); + return false; + } catch (RTI::SaveInProgress& e) { + SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not query lookahead: " << e._name << " " << e._reason); + return false; + } catch (RTI::RestoreInProgress& e) { + SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not query lookahead: " << e._name << " " << e._reason); + return false; + } catch (RTI::RTIinternalError& e) { + SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not query lookahead: " << e._name << " " << e._reason); + return false; + } + return true; +} + +bool +RTI13Federate::queryGALT(SGTimeStamp& timeStamp) +{ + if (!_ambassador.valid()) { + SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not query GALT."); + return false; + } + + try { + return _ambassador->queryGALT(timeStamp); + } catch (RTI::FederateNotExecutionMember& e) { + SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not query GALT: " << e._name << " " << e._reason); + return false; + } catch (RTI::ConcurrentAccessAttempted& e) { + SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not query GALT: " << e._name << " " << e._reason); + return false; + } catch (RTI::SaveInProgress& e) { + SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not query GALT: " << e._name << " " << e._reason); + return false; + } catch (RTI::RestoreInProgress& e) { + SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not query GALT: " << e._name << " " << e._reason); + return false; + } catch (RTI::RTIinternalError& e) { + SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not query GALT: " << e._name << " " << e._reason); + return false; } + return true; +} +bool +RTI13Federate::queryLITS(SGTimeStamp& timeStamp) +{ + if (!_ambassador.valid()) { + SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not query LITS."); + return false; + } + + try { + return _ambassador->queryLITS(timeStamp); + } catch (RTI::FederateNotExecutionMember& e) { + SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not query LITS: " << e._name << " " << e._reason); + return false; + } catch (RTI::ConcurrentAccessAttempted& e) { + SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not query LITS: " << e._name << " " << e._reason); + return false; + } catch (RTI::SaveInProgress& e) { + SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not query LITS: " << e._name << " " << e._reason); + return false; + } catch (RTI::RestoreInProgress& e) { + SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not query LITS: " << e._name << " " << e._reason); + return false; + } catch (RTI::RTIinternalError& e) { + SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not query LITS: " << e._name << " " << e._reason); + return false; + } return true; } bool -RTI13Federate::tick() +RTI13Federate::processMessage() { bool result = _ambassador->tick(); - _ambassador->processQueues(); + _federateAmbassador->processQueues(); return result; } bool -RTI13Federate::tick(const double& minimum, const double& maximum) +RTI13Federate::processMessages(const double& minimum, const double& maximum) { - bool result = _ambassador->tick(minimum, maximum); - _ambassador->processQueues(); + bool result = _ambassador->tick(minimum, 0); + _federateAmbassador->processQueues(); + if (!result) + return false; + SGTimeStamp timeStamp = SGTimeStamp::now() + SGTimeStamp::fromSec(maximum); + do { + result = _ambassador->tick(0, 0); + _federateAmbassador->processQueues(); + } while (result && SGTimeStamp::now() <= timeStamp); return result; } @@ -471,7 +1228,16 @@ RTI13ObjectClass* RTI13Federate::createObjectClass(const std::string& objectClassName, HLAObjectClass* hlaObjectClass) { try { - return _ambassador->createObjectClass(objectClassName, hlaObjectClass); + RTI::ObjectClassHandle objectClassHandle; + objectClassHandle = _ambassador->getObjectClassHandle(objectClassName); + if (_federateAmbassador->_objectClassMap.find(objectClassHandle) != _federateAmbassador->_objectClassMap.end()) { + SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not create object class, object class already exists!"); + return 0; + } + RTI13ObjectClass* rtiObjectClass; + rtiObjectClass = new RTI13ObjectClass(hlaObjectClass, objectClassHandle, _ambassador.get()); + _federateAmbassador->_objectClassMap[objectClassHandle] = rtiObjectClass; + return rtiObjectClass; } catch (RTI::NameNotFound& e) { SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class: " << e._name << " " << e._reason); return 0; @@ -491,7 +1257,14 @@ RTI13ObjectInstance* RTI13Federate::getObjectInstance(const std::string& objectInstanceName) { try { - return _ambassador->getObjectInstance(objectInstanceName); + RTI::ObjectHandle objectHandle; + objectHandle = _ambassador->getObjectInstanceHandle(objectInstanceName); + FederateAmbassador::ObjectInstanceMap::iterator i = _federateAmbassador->_objectInstanceMap.find(objectHandle); + if (i == _federateAmbassador->_objectInstanceMap.end()) { + SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class: ObjectInstance not found."); + return 0; + } + return i->second; } catch (RTI::ObjectNotKnown& e) { SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object class: " << e._name << " " << e._reason); return 0; @@ -507,4 +1280,10 @@ RTI13Federate::getObjectInstance(const std::string& objectInstanceName) } } +void +RTI13Federate::insertObjectInstance(RTI13ObjectInstance* objectInstance) +{ + _federateAmbassador->_objectInstanceMap[objectInstance->getHandle()] = objectInstance; +} + }