From 85e58b4a49d3c3b74afed3c766b47b65a6a95a66 Mon Sep 17 00:00:00 2001 From: Mathias Froehlich Date: Sat, 8 Oct 2011 17:44:53 +0200 Subject: [PATCH] hla: for rti13 queue all callbacks. This is to avoid running into the rti13 ambassadors recursion guards. Newer rti standards will not requires this. --- simgear/hla/RTI13Federate.cxx | 453 +++++++++++++++++++++++----- simgear/hla/RTI13ObjectInstance.cxx | 105 ++++--- simgear/hla/RTI13ObjectInstance.hxx | 29 +- simgear/hla/RTIData.hxx | 7 + simgear/hla/RTIObjectClass.cxx | 1 + simgear/hla/RTIObjectInstance.hxx | 81 +---- 6 files changed, 465 insertions(+), 211 deletions(-) diff --git a/simgear/hla/RTI13Federate.cxx b/simgear/hla/RTI13Federate.cxx index 1eece869..08dbdd86 100644 --- a/simgear/hla/RTI13Federate.cxx +++ b/simgear/hla/RTI13Federate.cxx @@ -41,6 +41,27 @@ struct RTI13Federate::FederateAmbassador : public RTI::FederateAmbassador { { } + /// 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()(FederateAmbassador& self) = 0; + }; + class TagQueueCallback : public QueueCallback { + public: + TagQueueCallback(const char* tag) + { + if (tag) + _tag.setData(tag, std::strlen(tag) + 1); + else + _tag.setData("", 1); + } + virtual ~TagQueueCallback() + { } + RTIData _tag; + }; + /// RTI federate ambassador callback functions. virtual void synchronizationPointRegistrationSucceeded(const char* label) throw (RTI::FederateInternalError) @@ -115,9 +136,21 @@ struct RTI13Federate::FederateAmbassador : public RTI::FederateAmbassador { } // Declaration Management + class StartRegistrationForObjectClassCallback : public QueueCallback { + public: + StartRegistrationForObjectClassCallback(RTI::ObjectClassHandle objectClassHandle) : + _objectClassHandle(objectClassHandle) + { } + virtual void operator()(FederateAmbassador& self) + { self.startRegistrationForObjectClassCallback(_objectClassHandle); } + private: + RTI::ObjectClassHandle _objectClassHandle; + }; virtual void startRegistrationForObjectClass(RTI::ObjectClassHandle objectClassHandle) throw (RTI::ObjectClassNotPublished, RTI::FederateInternalError) + { _queueCallbackList.push_back(new StartRegistrationForObjectClassCallback(objectClassHandle)); } + void startRegistrationForObjectClassCallback(RTI::ObjectClassHandle objectClassHandle) { ObjectClassMap::iterator i = _objectClassMap.find(objectClassHandle); if (i == _objectClassMap.end()) @@ -127,9 +160,21 @@ struct RTI13Federate::FederateAmbassador : public RTI::FederateAmbassador { i->second->startRegistration(); } + class StopRegistrationForObjectClassCallback : public QueueCallback { + public: + StopRegistrationForObjectClassCallback(RTI::ObjectClassHandle objectClassHandle) : + _objectClassHandle(objectClassHandle) + { } + virtual void operator()(FederateAmbassador& self) + { self.stopRegistrationForObjectClassCallback(_objectClassHandle); } + private: + RTI::ObjectClassHandle _objectClassHandle; + }; virtual void stopRegistrationForObjectClass(RTI::ObjectClassHandle objectClassHandle) throw (RTI::ObjectClassNotPublished, RTI::FederateInternalError) + { _queueCallbackList.push_back(new StopRegistrationForObjectClassCallback(objectClassHandle)); } + void stopRegistrationForObjectClassCallback(RTI::ObjectClassHandle objectClassHandle) { ObjectClassMap::iterator i = _objectClassMap.find(objectClassHandle); if (i == _objectClassMap.end()) @@ -151,23 +196,58 @@ struct RTI13Federate::FederateAmbassador : public RTI::FederateAmbassador { { } - // Object Management + class DiscoverObjectCallback : public TagQueueCallback { + public: + DiscoverObjectCallback(RTI::ObjectHandle objectHandle, RTI::ObjectClassHandle objectClassHandle, const char *tag) : + TagQueueCallback(tag), + _objectHandle(objectHandle), + _objectClassHandle(objectClassHandle) + { } + virtual void operator()(FederateAmbassador& self) + { self.discoverObjectInstanceCallback(_objectHandle, _objectClassHandle, _tag); } + private: + RTI::ObjectHandle _objectHandle; + RTI::ObjectClassHandle _objectClassHandle; + }; virtual void discoverObjectInstance(RTI::ObjectHandle objectHandle, RTI::ObjectClassHandle objectClassHandle, const char* tag) throw (RTI::CouldNotDiscover, RTI::ObjectClassNotKnown, RTI::FederateInternalError) + { _queueCallbackList.push_back(new DiscoverObjectCallback(objectHandle, objectClassHandle, tag)); } + void discoverObjectInstanceCallback(RTI::ObjectHandle objectHandle, RTI::ObjectClassHandle objectClassHandle, const RTIData& tag) { ObjectClassMap::iterator i = _objectClassMap.find(objectClassHandle); if (i == _objectClassMap.end()) - throw RTI::ObjectClassNotKnown("Federate: discoverObjectInstance()!"); + return; 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))); + i->second->discoverInstance(objectInstance.get(), tag); } + class ReflectAttributeValuesTimestampCallback : public TagQueueCallback { + public: + ReflectAttributeValuesTimestampCallback(RTI::ObjectHandle objectHandle, + RTI13AttributeHandleDataPairList& attributeHandleDataPairList, + const SGTimeStamp& timeStamp, const char *tag) : + TagQueueCallback(tag), + _objectHandle(objectHandle), + _timeStamp(timeStamp) + { + _attributeHandleDataPairList.swap(attributeHandleDataPairList); + } + virtual void operator()(FederateAmbassador& self) + { + self.reflectAttributeValuesCallback(_objectHandle, _attributeHandleDataPairList, _timeStamp, _tag); + self.freeAttributeHandleDataPairList(_attributeHandleDataPairList); + } + private: + RTI::ObjectHandle _objectHandle; + RTI13AttributeHandleDataPairList _attributeHandleDataPairList; + SGTimeStamp _timeStamp; + }; virtual void reflectAttributeValues(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleValuePairSet& attributeValuePairSet, const RTI::FedTime& fedTime, const char* tag, RTI::EventRetractionHandle eventRetractionHandle) throw (RTI::ObjectNotKnown, @@ -175,28 +255,79 @@ struct RTI13Federate::FederateAmbassador : public RTI::FederateAmbassador { RTI::FederateOwnsAttributes, RTI::InvalidFederationTime, RTI::FederateInternalError) + { + RTI13AttributeHandleDataPairList attributeHandleDataPairList; + + RTI::ULong numAttribs = attributeValuePairSet.size(); + for (RTI::ULong i = 0; i < numAttribs; ++i) { + appendAttributeHandleDataPair(attributeHandleDataPairList); + attributeHandleDataPairList.back().first = attributeValuePairSet.getHandle(i); + RTI::ULong length = attributeValuePairSet.getValueLength(i); + attributeHandleDataPairList.back().second.resize(length); + attributeValuePairSet.getValue(i, attributeHandleDataPairList.back().second.data(), length); + } + + _queueCallbackList.push_back(new ReflectAttributeValuesTimestampCallback(objectHandle, attributeHandleDataPairList, + RTI13Ambassador::toTimeStamp(fedTime), tag)); + } + void reflectAttributeValuesCallback(RTI::ObjectHandle objectHandle, RTI13AttributeHandleDataPairList& attributeHandleDataPairList, + const SGTimeStamp& timeStamp, const RTIData& tag) { ObjectInstanceMap::iterator i = _objectInstanceMap.find(objectHandle); if (i == _objectInstanceMap.end()) - throw RTI::ObjectNotKnown("Reflect attributes for unknown object!"); + return; if (!i->second.valid()) return; - i->second->reflectAttributeValues(attributeValuePairSet, RTI13Ambassador::toTimeStamp(fedTime), tagToData(tag)); + i->second->reflectAttributeValues(attributeHandleDataPairList, timeStamp, tag); } + class ReflectAttributeValuesCallback : public TagQueueCallback { + public: + ReflectAttributeValuesCallback(RTI::ObjectHandle objectHandle, RTI13AttributeHandleDataPairList& attributeHandleDataPairList, + const char *tag) : + TagQueueCallback(tag), + _objectHandle(objectHandle) + { + _attributeHandleDataPairList.swap(attributeHandleDataPairList); + } + virtual void operator()(FederateAmbassador& self) + { + self.reflectAttributeValuesCallback(_objectHandle, _attributeHandleDataPairList, _tag); + self.freeAttributeHandleDataPairList(_attributeHandleDataPairList); + } + private: + RTI::ObjectHandle _objectHandle; + RTI13AttributeHandleDataPairList _attributeHandleDataPairList; + }; virtual void reflectAttributeValues(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleValuePairSet& attributeValuePairSet, const char* tag) throw (RTI::ObjectNotKnown, RTI::AttributeNotKnown, RTI::FederateOwnsAttributes, RTI::FederateInternalError) + { + RTI13AttributeHandleDataPairList attributeHandleDataPairList; + + RTI::ULong numAttribs = attributeValuePairSet.size(); + for (RTI::ULong i = 0; i < numAttribs; ++i) { + appendAttributeHandleDataPair(attributeHandleDataPairList); + attributeHandleDataPairList.back().first = attributeValuePairSet.getHandle(i); + RTI::ULong length = attributeValuePairSet.getValueLength(i); + attributeHandleDataPairList.back().second.resize(length); + attributeValuePairSet.getValue(i, attributeHandleDataPairList.back().second.data(), length); + } + + _queueCallbackList.push_back(new ReflectAttributeValuesCallback(objectHandle, attributeHandleDataPairList, tag)); + } + void reflectAttributeValuesCallback(RTI::ObjectHandle objectHandle, RTI13AttributeHandleDataPairList& attributeHandleDataPairList, + const RTIData& tag) { ObjectInstanceMap::iterator i = _objectInstanceMap.find(objectHandle); if (i == _objectInstanceMap.end()) - throw RTI::ObjectNotKnown("Reflect attributes for unknown object!"); + return; if (!i->second.valid()) return; - i->second->reflectAttributeValues(attributeValuePairSet, tagToData(tag)); + i->second->reflectAttributeValues(attributeHandleDataPairList, tag); } virtual void receiveInteraction(RTI::InteractionClassHandle interactionClassHandle, const RTI::ParameterHandleValuePairSet& parameters, @@ -216,99 +347,202 @@ struct RTI13Federate::FederateAmbassador : public RTI::FederateAmbassador { { } + class RemoveObjectTimestampCallback : public TagQueueCallback { + public: + RemoveObjectTimestampCallback(RTI::ObjectHandle objectHandle, const SGTimeStamp& timeStamp, const char* tag) : + TagQueueCallback(tag), + _objectHandle(objectHandle), + _timeStamp(timeStamp) + { } + virtual void operator()(FederateAmbassador& self) + { self.removeObjectInstanceCallback(_objectHandle, _timeStamp, _tag); } + private: + RTI::ObjectHandle _objectHandle; + SGTimeStamp _timeStamp; + }; virtual void removeObjectInstance(RTI::ObjectHandle objectHandle, const RTI::FedTime& fedTime, const char* tag, RTI::EventRetractionHandle eventRetractionHandle) throw (RTI::ObjectNotKnown, RTI::InvalidFederationTime, RTI::FederateInternalError) + { _queueCallbackList.push_back(new RemoveObjectTimestampCallback(objectHandle, RTI13Ambassador::toTimeStamp(fedTime), tag)); } + void removeObjectInstanceCallback(RTI::ObjectHandle objectHandle, const SGTimeStamp& timeStamp, const RTIData& tag) { ObjectInstanceMap::iterator i = _objectInstanceMap.find(objectHandle); if (i == _objectInstanceMap.end()) - throw RTI::ObjectNotKnown("Federate: removeObjectInstance()!"); + return; if (i->second.valid()) - _queueCallbackList.push_back(new RemoveObjectCallback(i->second, tagToData(tag))); + i->second->removeInstance(tag); _objectInstanceMap.erase(i); } + class RemoveObjectCallback : public TagQueueCallback { + public: + RemoveObjectCallback(RTI::ObjectHandle objectHandle, const char* tag) : + TagQueueCallback(tag), + _objectHandle(objectHandle) + { } + virtual void operator()(FederateAmbassador& self) + { self.removeObjectInstanceCallback(_objectHandle, _tag); } + private: + RTI::ObjectHandle _objectHandle; + }; virtual void removeObjectInstance(RTI::ObjectHandle objectHandle, const char* tag) throw (RTI::ObjectNotKnown, RTI::FederateInternalError) + { _queueCallbackList.push_back(new RemoveObjectCallback(objectHandle, tag)); } + void removeObjectInstanceCallback(RTI::ObjectHandle objectHandle, const RTIData& tag) { ObjectInstanceMap::iterator i = _objectInstanceMap.find(objectHandle); if (i == _objectInstanceMap.end()) - throw RTI::ObjectNotKnown("Federate: removeObjectInstance()!"); + return; if (i->second.valid()) - _queueCallbackList.push_back(new RemoveObjectCallback(i->second, tagToData(tag))); + i->second->removeInstance(tag); _objectInstanceMap.erase(i); } + class AttributeHandleSetCallback : public QueueCallback { + public: + AttributeHandleSetCallback(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleSet& attributeHandleSet) : + _objectHandle(objectHandle) + { + RTI::ULong numAttribs = attributeHandleSet.size(); + _attributes.reserve(numAttribs); + for (RTI::ULong i = 0; i < numAttribs; ++i) + _attributes.push_back(attributeHandleSet.getHandle(i)); + } + protected: + RTI::ObjectHandle _objectHandle; + std::vector _attributes; + }; + class AttributesInScopeCallback : public AttributeHandleSetCallback { + public: + AttributesInScopeCallback(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleSet& attributes) : + AttributeHandleSetCallback(objectHandle, attributes) + { } + virtual void operator()(FederateAmbassador& self) + { self.attributesInScopeCallback(_objectHandle, _attributes); } + }; virtual void attributesInScope(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleSet& attributes) throw (RTI::ObjectNotKnown, RTI::AttributeNotKnown, RTI::FederateInternalError) + { _queueCallbackList.push_back(new AttributesInScopeCallback(objectHandle, attributes)); } + void attributesInScopeCallback(RTI::ObjectHandle objectHandle, const std::vector& attributes) { ObjectInstanceMap::iterator i = _objectInstanceMap.find(objectHandle); if (i == _objectInstanceMap.end()) - throw RTI::ObjectNotKnown("Attributes in scope for unknown object!"); + return; if (!i->second.valid()) return; i->second->attributesInScope(attributes); } + class AttributesOutOfScopeCallback : public AttributeHandleSetCallback { + public: + AttributesOutOfScopeCallback(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleSet& attributes) : + AttributeHandleSetCallback(objectHandle, attributes) + { } + virtual void operator()(FederateAmbassador& self) + { self.attributesOutOfScopeCallback(_objectHandle, _attributes); } + }; virtual void attributesOutOfScope(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleSet& attributes) throw (RTI::ObjectNotKnown, RTI::AttributeNotKnown, RTI::FederateInternalError) + { _queueCallbackList.push_back(new AttributesOutOfScopeCallback(objectHandle, attributes)); } + void attributesOutOfScopeCallback(RTI::ObjectHandle objectHandle, const std::vector& attributes) { ObjectInstanceMap::iterator i = _objectInstanceMap.find(objectHandle); if (i == _objectInstanceMap.end()) - throw RTI::ObjectNotKnown("Attributes in scope for unknown object!"); + return; if (!i->second.valid()) return; i->second->attributesOutOfScope(attributes); } + class ProvideAttributeValueUpdateCallback : public AttributeHandleSetCallback { + public: + ProvideAttributeValueUpdateCallback(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleSet& attributes) : + AttributeHandleSetCallback(objectHandle, attributes) + { } + virtual void operator()(FederateAmbassador& self) + { self.provideAttributeValueUpdateCallback(_objectHandle, _attributes); } + }; virtual void provideAttributeValueUpdate(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleSet& attributes) throw (RTI::ObjectNotKnown, RTI::AttributeNotKnown, RTI::AttributeNotOwned, RTI::FederateInternalError) + { _queueCallbackList.push_back(new ProvideAttributeValueUpdateCallback(objectHandle, attributes)); } + void provideAttributeValueUpdateCallback(RTI::ObjectHandle objectHandle, const std::vector& attributes) { ObjectInstanceMap::iterator i = _objectInstanceMap.find(objectHandle); if (i == _objectInstanceMap.end()) - throw RTI::ObjectNotKnown("Reflect attributes for unknown object!"); + return; if (!i->second.valid()) return; i->second->provideAttributeValueUpdate(attributes); } + class TurnUpdatesOnForObjectInstanceCallback : public AttributeHandleSetCallback { + public: + TurnUpdatesOnForObjectInstanceCallback(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleSet& attributes) : + AttributeHandleSetCallback(objectHandle, attributes) + { } + virtual void operator()(FederateAmbassador& self) + { self.turnUpdatesOnForObjectInstanceCallback(_objectHandle, _attributes); } + }; virtual void turnUpdatesOnForObjectInstance(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleSet& attributes) throw (RTI::ObjectNotKnown, RTI::AttributeNotOwned, RTI::FederateInternalError) + { _queueCallbackList.push_back(new TurnUpdatesOnForObjectInstanceCallback(objectHandle, attributes)); } + void turnUpdatesOnForObjectInstanceCallback(RTI::ObjectHandle objectHandle, const std::vector& attributes) { ObjectInstanceMap::iterator i = _objectInstanceMap.find(objectHandle); if (i == _objectInstanceMap.end()) - throw RTI::ObjectNotKnown("Turn on attributes for unknown object!"); + return; if (!i->second.valid()) return; i->second->turnUpdatesOnForObjectInstance(attributes); } + class TurnUpdatesOffForObjectInstanceCallback : public AttributeHandleSetCallback { + public: + TurnUpdatesOffForObjectInstanceCallback(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleSet& attributes) : + AttributeHandleSetCallback(objectHandle, attributes) + { } + virtual void operator()(FederateAmbassador& self) + { self.turnUpdatesOffForObjectInstanceCallback(_objectHandle, _attributes); } + }; virtual void turnUpdatesOffForObjectInstance(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleSet& attributes) throw (RTI::ObjectNotKnown, RTI::AttributeNotOwned, RTI::FederateInternalError) + { _queueCallbackList.push_back(new TurnUpdatesOffForObjectInstanceCallback(objectHandle, attributes)); } + void turnUpdatesOffForObjectInstanceCallback(RTI::ObjectHandle objectHandle, const std::vector& attributes) { ObjectInstanceMap::iterator i = _objectInstanceMap.find(objectHandle); if (i == _objectInstanceMap.end()) - throw RTI::ObjectNotKnown("Turn off attributes for unknown object!"); + return; if (!i->second.valid()) return; i->second->turnUpdatesOffForObjectInstance(attributes); } // Ownership Management + class RequestAttributeOwnershipAssumptionCallback : public AttributeHandleSetCallback { + public: + RequestAttributeOwnershipAssumptionCallback(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleSet& attributes, const RTIData& tag) : + AttributeHandleSetCallback(objectHandle, attributes), + _tag(tag) + { } + virtual void operator()(FederateAmbassador& self) + { self.requestAttributeOwnershipAssumptionCallback(_objectHandle, _attributes, _tag); } + protected: + RTIData _tag; + }; virtual void requestAttributeOwnershipAssumption(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleSet& attributes, const char* tag) throw (RTI::ObjectNotKnown, @@ -316,30 +550,50 @@ struct RTI13Federate::FederateAmbassador : public RTI::FederateAmbassador { RTI::AttributeAlreadyOwned, RTI::AttributeNotPublished, RTI::FederateInternalError) + { _queueCallbackList.push_back(new RequestAttributeOwnershipAssumptionCallback(objectHandle, attributes, tagToData(tag))); } + void requestAttributeOwnershipAssumptionCallback(RTI::ObjectHandle objectHandle, std::vector& attributes, const RTIData& tag) { ObjectInstanceMap::iterator i = _objectInstanceMap.find(objectHandle); if (i == _objectInstanceMap.end()) - throw RTI::ObjectNotKnown("requestAttributeOwnershipAssumption for unknown object!"); + return; if (!i->second.valid()) return; - i->second->requestAttributeOwnershipAssumption(attributes, tagToData(tag)); + i->second->requestAttributeOwnershipAssumption(attributes, tag); } + class AttributeOwnershipDivestitureNotificationCallback : public AttributeHandleSetCallback { + public: + AttributeOwnershipDivestitureNotificationCallback(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleSet& attributes) : + AttributeHandleSetCallback(objectHandle, attributes) + { } + virtual void operator()(FederateAmbassador& self) + { self.attributeOwnershipDivestitureNotificationCallback(_objectHandle, _attributes); } + }; virtual void attributeOwnershipDivestitureNotification(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleSet& attributes) throw (RTI::ObjectNotKnown, RTI::AttributeNotKnown, RTI::AttributeNotOwned, RTI::AttributeDivestitureWasNotRequested, RTI::FederateInternalError) + { _queueCallbackList.push_back(new AttributeOwnershipDivestitureNotificationCallback(objectHandle, attributes)); } + void attributeOwnershipDivestitureNotificationCallback(RTI::ObjectHandle objectHandle, const std::vector& attributes) { ObjectInstanceMap::iterator i = _objectInstanceMap.find(objectHandle); if (i == _objectInstanceMap.end()) - throw RTI::ObjectNotKnown("attributeOwnershipDivestitureNotification for unknown object!"); + return; if (!i->second.valid()) return; i->second->attributeOwnershipDivestitureNotification(attributes); } + class AttributeOwnershipAcquisitionNotificationCallback : public AttributeHandleSetCallback { + public: + AttributeOwnershipAcquisitionNotificationCallback(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleSet& attributes) : + AttributeHandleSetCallback(objectHandle, attributes) + { } + virtual void operator()(FederateAmbassador& self) + { self.attributeOwnershipAcquisitionNotificationCallback(_objectHandle, _attributes); } + }; virtual void attributeOwnershipAcquisitionNotification(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleSet& attributes) throw (RTI::ObjectNotKnown, RTI::AttributeNotKnown, @@ -347,95 +601,174 @@ struct RTI13Federate::FederateAmbassador : public RTI::FederateAmbassador { RTI::AttributeAlreadyOwned, RTI::AttributeNotPublished, RTI::FederateInternalError) + { _queueCallbackList.push_back(new AttributeOwnershipAcquisitionNotificationCallback(objectHandle, attributes)); } + void attributeOwnershipAcquisitionNotificationCallback(RTI::ObjectHandle objectHandle, const std::vector& attributes) { ObjectInstanceMap::iterator i = _objectInstanceMap.find(objectHandle); if (i == _objectInstanceMap.end()) - throw RTI::ObjectNotKnown("attributeOwnershipAcquisitionNotification for unknown object!"); + return; if (!i->second.valid()) return; i->second->attributeOwnershipAcquisitionNotification(attributes); } + class AttributeOwnershipUnavailableCallback : public AttributeHandleSetCallback { + public: + AttributeOwnershipUnavailableCallback(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleSet& attributes) : + AttributeHandleSetCallback(objectHandle, attributes) + { } + virtual void operator()(FederateAmbassador& self) + { self.attributeOwnershipUnavailableCallback(_objectHandle, _attributes); } + }; virtual void attributeOwnershipUnavailable(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleSet& attributes) throw (RTI::ObjectNotKnown, RTI::AttributeNotKnown, RTI::AttributeAlreadyOwned, RTI::AttributeAcquisitionWasNotRequested, RTI::FederateInternalError) + { _queueCallbackList.push_back(new AttributeOwnershipUnavailableCallback(objectHandle, attributes)); } + void attributeOwnershipUnavailableCallback(RTI::ObjectHandle objectHandle, const std::vector& attributes) { ObjectInstanceMap::iterator i = _objectInstanceMap.find(objectHandle); if (i == _objectInstanceMap.end()) - throw RTI::ObjectNotKnown("attributeOwnershipUnavailable for unknown object!"); + return; if (!i->second.valid()) return; i->second->attributeOwnershipUnavailable(attributes); } + class RequestAttributeOwnershipReleaseCallback : public AttributeHandleSetCallback { + public: + RequestAttributeOwnershipReleaseCallback(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleSet& attributes, const RTIData& tag) : + AttributeHandleSetCallback(objectHandle, attributes), + _tag(tag) + { } + virtual void operator()(FederateAmbassador& self) + { self.requestAttributeOwnershipReleaseCallback(_objectHandle, _attributes, _tag); } + protected: + RTIData _tag; + }; virtual void requestAttributeOwnershipRelease(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleSet& attributes, const char* tag) throw (RTI::ObjectNotKnown, RTI::AttributeNotKnown, RTI::AttributeNotOwned, RTI::FederateInternalError) + { _queueCallbackList.push_back(new RequestAttributeOwnershipReleaseCallback(objectHandle, attributes, tagToData(tag))); } + void requestAttributeOwnershipReleaseCallback(RTI::ObjectHandle objectHandle, std::vector& attributes, const RTIData& tag) { ObjectInstanceMap::iterator i = _objectInstanceMap.find(objectHandle); if (i == _objectInstanceMap.end()) - throw RTI::ObjectNotKnown("requestAttributeOwnershipRelease for unknown object!"); + return; if (!i->second.valid()) return; - i->second->requestAttributeOwnershipRelease(attributes, tagToData(tag)); + i->second->requestAttributeOwnershipRelease(attributes, tag); } + class ConfirmAttributeOwnershipAcquisitionCancellationCallback : public AttributeHandleSetCallback { + public: + ConfirmAttributeOwnershipAcquisitionCancellationCallback(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleSet& attributes) : + AttributeHandleSetCallback(objectHandle, attributes) + { } + virtual void operator()(FederateAmbassador& self) + { self.confirmAttributeOwnershipAcquisitionCancellationCallback(_objectHandle, _attributes); } + }; virtual void confirmAttributeOwnershipAcquisitionCancellation(RTI::ObjectHandle objectHandle, const RTI::AttributeHandleSet& attributes) throw (RTI::ObjectNotKnown, RTI::AttributeNotKnown, RTI::AttributeAlreadyOwned, RTI::AttributeAcquisitionWasNotCanceled, RTI::FederateInternalError) + { _queueCallbackList.push_back(new ConfirmAttributeOwnershipAcquisitionCancellationCallback(objectHandle, attributes)); } + void confirmAttributeOwnershipAcquisitionCancellationCallback(RTI::ObjectHandle objectHandle, const std::vector& attributes) { ObjectInstanceMap::iterator i = _objectInstanceMap.find(objectHandle); if (i == _objectInstanceMap.end()) - throw RTI::ObjectNotKnown("confirmAttributeOwnershipAcquisitionCancellation for unknown object!"); + return; if (!i->second.valid()) return; i->second->confirmAttributeOwnershipAcquisitionCancellation(attributes); } + class InformAttributeOwnershipCallback : public QueueCallback { + public: + InformAttributeOwnershipCallback(RTI::ObjectHandle objectHandle, RTI::AttributeHandle attributeHandle, RTI::FederateHandle federateHandle) : + _objectHandle(objectHandle), + _attributeHandle(attributeHandle), + _federateHandle(federateHandle) + { } + virtual void operator()(FederateAmbassador& self) + { self.informAttributeOwnershipCallback(_objectHandle, _attributeHandle, _federateHandle); } + private: + RTI::ObjectHandle _objectHandle; + RTI::AttributeHandle _attributeHandle; + RTI::FederateHandle _federateHandle; + }; virtual void informAttributeOwnership(RTI::ObjectHandle objectHandle, RTI::AttributeHandle attributeHandle, RTI::FederateHandle federateHandle) throw (RTI::ObjectNotKnown, RTI::AttributeNotKnown, RTI::FederateInternalError) + { _queueCallbackList.push_back(new InformAttributeOwnershipCallback(objectHandle, attributeHandle, federateHandle)); } + void informAttributeOwnershipCallback(RTI::ObjectHandle objectHandle, RTI::AttributeHandle attributeHandle, RTI::FederateHandle federateHandle) { ObjectInstanceMap::iterator i = _objectInstanceMap.find(objectHandle); if (i == _objectInstanceMap.end()) - throw RTI::ObjectNotKnown("informAttributeOwnership for unknown object!"); + return; if (!i->second.valid()) return; i->second->informAttributeOwnership(attributeHandle, federateHandle); } + class AttributeIsNotOwnedCallback : public QueueCallback { + public: + AttributeIsNotOwnedCallback(RTI::ObjectHandle objectHandle, RTI::AttributeHandle attributeHandle) : + _objectHandle(objectHandle), + _attributeHandle(attributeHandle) + { } + virtual void operator()(FederateAmbassador& self) + { self.attributeIsNotOwnedCallback(_objectHandle, _attributeHandle); } + private: + RTI::ObjectHandle _objectHandle; + RTI::AttributeHandle _attributeHandle; + }; virtual void attributeIsNotOwned(RTI::ObjectHandle objectHandle, RTI::AttributeHandle attributeHandle) throw (RTI::ObjectNotKnown, RTI::AttributeNotKnown, RTI::FederateInternalError) + { _queueCallbackList.push_back(new AttributeIsNotOwnedCallback(objectHandle, attributeHandle)); } + void attributeIsNotOwnedCallback(RTI::ObjectHandle objectHandle, RTI::AttributeHandle attributeHandle) { ObjectInstanceMap::iterator i = _objectInstanceMap.find(objectHandle); if (i == _objectInstanceMap.end()) - throw RTI::ObjectNotKnown("attributeIsNotOwned for unknown object!"); + return; if (!i->second.valid()) return; i->second->attributeIsNotOwned(attributeHandle); } + class AttributeOwnedByRTICallback : public QueueCallback { + public: + AttributeOwnedByRTICallback(RTI::ObjectHandle objectHandle, RTI::AttributeHandle attributeHandle) : + _objectHandle(objectHandle), + _attributeHandle(attributeHandle) + { } + virtual void operator()(FederateAmbassador& self) + { self.attributeOwnedByRTICallback(_objectHandle, _attributeHandle); } + private: + RTI::ObjectHandle _objectHandle; + RTI::AttributeHandle _attributeHandle; + }; virtual void attributeOwnedByRTI(RTI::ObjectHandle objectHandle, RTI::AttributeHandle attributeHandle) throw (RTI::ObjectNotKnown, RTI::AttributeNotKnown, RTI::FederateInternalError) + { _queueCallbackList.push_back(new AttributeOwnedByRTICallback(objectHandle, attributeHandle)); } + void attributeOwnedByRTICallback(RTI::ObjectHandle objectHandle, RTI::AttributeHandle attributeHandle) { ObjectInstanceMap::iterator i = _objectInstanceMap.find(objectHandle); if (i == _objectInstanceMap.end()) - throw RTI::ObjectNotKnown("attributeOwnedByRTI for unknown object!"); + return; if (!i->second.valid()) return; i->second->attributeOwnedByRTI(attributeHandle); @@ -448,8 +781,7 @@ struct RTI13Federate::FederateAmbassador : public RTI::FederateAmbassador { RTI::FederateInternalError) { _timeRegulationEnabled = true; - _federateTime = RTI13Ambassador::toTimeStamp(fedTime); - SG_LOG(SG_NETWORK, SG_INFO, "RTI: timeRegulationEnabled: " << _federateTime); + SG_LOG(SG_NETWORK, SG_INFO, "RTI: timeRegulationEnabled: " << RTI13Ambassador::toTimeStamp(fedTime)); } virtual void timeConstrainedEnabled(const RTI::FedTime& fedTime) @@ -458,8 +790,7 @@ struct RTI13Federate::FederateAmbassador : public RTI::FederateAmbassador { RTI::FederateInternalError) { _timeConstrainedEnabled = true; - _federateTime = RTI13Ambassador::toTimeStamp(fedTime); - SG_LOG(SG_NETWORK, SG_INFO, "RTI: timeConstrainedEnabled: " << _federateTime); + SG_LOG(SG_NETWORK, SG_INFO, "RTI: timeConstrainedEnabled: " << RTI13Ambassador::toTimeStamp(fedTime)); } virtual void timeAdvanceGrant(const RTI::FedTime& fedTime) @@ -467,9 +798,8 @@ struct RTI13Federate::FederateAmbassador : public RTI::FederateAmbassador { RTI::TimeAdvanceWasNotInProgress, RTI::FederateInternalError) { - _federateTime = RTI13Ambassador::toTimeStamp(fedTime); _timeAdvancePending = false; - SG_LOG(SG_NETWORK, SG_INFO, "RTI: timeAdvanceGrant: " << _federateTime); + // SG_LOG(SG_NETWORK, SG_INFO, "RTI: timeAdvanceGrant: " << RTI13Ambassador::toTimeStamp(fedTime)); } virtual void requestRetraction(RTI::EventRetractionHandle eventRetractionHandle) @@ -483,7 +813,8 @@ struct RTI13Federate::FederateAmbassador : public RTI::FederateAmbassador { void processQueues() { while (!_queueCallbackList.empty()) { - (*_queueCallbackList.front())(); + (*_queueCallbackList.front())(*this); + // _queueCallbackListPool.splice(); _queueCallbackList.pop_front(); } } @@ -499,46 +830,6 @@ struct RTI13Federate::FederateAmbassador : public RTI::FederateAmbassador { 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; @@ -550,6 +841,19 @@ struct RTI13Federate::FederateAmbassador : public RTI::FederateAmbassador { // That is to make sure we do not call recursively into the RTI typedef std::list > QueueCallbackList; QueueCallbackList _queueCallbackList; + // QueueCallbackList _queueCallbackListPool; + + RTI13AttributeHandleDataPairList _attributeHandleDataPairPool; + void appendAttributeHandleDataPair(RTI13AttributeHandleDataPairList& attributeHandleDataPairList) + { + if (_attributeHandleDataPairPool.empty()) + attributeHandleDataPairList.push_back(RTI13AttributeHandleDataPair()); + else + attributeHandleDataPairList.splice(attributeHandleDataPairList.end(), + _attributeHandleDataPairPool, _attributeHandleDataPairPool.begin()); + } + void freeAttributeHandleDataPairList(RTI13AttributeHandleDataPairList& attributeHandleDataPairList) + { _attributeHandleDataPairPool.splice(_attributeHandleDataPairPool.end(), attributeHandleDataPairList); } // Top level information for dispatching federate object attribute updates typedef std::map > ObjectInstanceMap; @@ -563,7 +867,6 @@ struct RTI13Federate::FederateAmbassador : public RTI::FederateAmbassador { bool _timeRegulationEnabled; bool _timeConstrainedEnabled; bool _timeAdvancePending; - SGTimeStamp _federateTime; private: const RTIData& tagToData(const char* tag) diff --git a/simgear/hla/RTI13ObjectInstance.cxx b/simgear/hla/RTI13ObjectInstance.cxx index 723f9b17..f8ba657f 100644 --- a/simgear/hla/RTI13ObjectInstance.cxx +++ b/simgear/hla/RTI13ObjectInstance.cxx @@ -177,47 +177,56 @@ RTI13ObjectInstance::localDeleteObjectInstance() } void -RTI13ObjectInstance::reflectAttributeValues(const RTI::AttributeHandleValuePairSet& attributeValuePairSet, const RTIData& tag) +RTI13ObjectInstance::reflectAttributeValues(RTI13AttributeHandleDataPairList& attributeHandleDataPairList, const RTIData& tag) { // Retrieve an empty update struct from the memory pool - UpdateList updateList; - getUpdateFromPool(updateList); - - RTI::ULong numAttribs = attributeValuePairSet.size(); - for (RTI::ULong i = 0; i < numAttribs; ++i) { - unsigned index = getAttributeIndex(attributeValuePairSet.getHandle(i)); + RTIIndexDataPairList indexDataPairList; + for (RTI13AttributeHandleDataPairList::iterator i = attributeHandleDataPairList.begin(); + i != attributeHandleDataPairList.end(); ++i) { + unsigned index = getAttributeIndex(i->first); // Get a RTIData from the data pool - getDataFromPool(index, updateList.back()._indexDataPairList); - RTI::ULong length = attributeValuePairSet.getValueLength(i); - updateList.back()._indexDataPairList.back().second.resize(length); - attributeValuePairSet.getValue(i, updateList.back()._indexDataPairList.back().second.data(), length); - updateList.back()._tag = tag; + getDataFromPool(indexDataPairList); + indexDataPairList.back().first = index; + indexDataPairList.back().second.swap(i->second); + } + + RTIObjectInstance::reflectAttributeValues(indexDataPairList, tag); + + RTIIndexDataPairList::iterator j = indexDataPairList.begin(); + for (RTI13AttributeHandleDataPairList::iterator i = attributeHandleDataPairList.begin(); + i != attributeHandleDataPairList.end(); ++i, ++j) { + i->second.swap(j->second); } - RTIObjectInstance::reflectAttributeValues(updateList.front()._indexDataPairList, tag); // Return the update data back to the pool - putUpdateToPool(updateList); + putDataToPool(indexDataPairList); } void -RTI13ObjectInstance::reflectAttributeValues(const RTI::AttributeHandleValuePairSet& attributeValuePairSet, const SGTimeStamp& timeStamp, const RTIData& tag) +RTI13ObjectInstance::reflectAttributeValues(RTI13AttributeHandleDataPairList& attributeHandleDataPairList, + const SGTimeStamp& timeStamp, const RTIData& tag) { // Retrieve an empty update struct from the memory pool - UpdateList updateList; - getUpdateFromPool(updateList); - - RTI::ULong numAttribs = attributeValuePairSet.size(); - for (RTI::ULong i = 0; i < numAttribs; ++i) { - unsigned index = getAttributeIndex(attributeValuePairSet.getHandle(i)); + RTIIndexDataPairList indexDataPairList; + for (RTI13AttributeHandleDataPairList::iterator i = attributeHandleDataPairList.begin(); + i != attributeHandleDataPairList.end(); ++i) { + unsigned index = getAttributeIndex(i->first); // Get a RTIData from the data pool - getDataFromPool(index, updateList.back()._indexDataPairList); - RTI::ULong length = attributeValuePairSet.getValueLength(i); - updateList.back()._indexDataPairList.back().second.resize(length); - attributeValuePairSet.getValue(i, updateList.back()._indexDataPairList.back().second.data(), length); - updateList.back()._tag = tag; + getDataFromPool(indexDataPairList); + indexDataPairList.back().first = index; + indexDataPairList.back().second.swap(i->second); } - scheduleUpdates(timeStamp, updateList); + RTIObjectInstance::reflectAttributeValues(indexDataPairList, timeStamp, tag); + + RTIIndexDataPairList::iterator j = indexDataPairList.begin(); + for (RTI13AttributeHandleDataPairList::iterator i = attributeHandleDataPairList.begin(); + i != attributeHandleDataPairList.end(); ++i, ++j) { + i->second.swap(j->second); + } + + // Return the update data back to the pool + putDataToPool(indexDataPairList); } void @@ -273,12 +282,12 @@ RTI13ObjectInstance::requestObjectAttributeValueUpdate() } void -RTI13ObjectInstance::provideAttributeValueUpdate(const RTI::AttributeHandleSet& attributes) +RTI13ObjectInstance::provideAttributeValueUpdate(const std::vector& attributeHandleSet) { // Called from the ambassador. Just marks some instance attributes dirty so that they are sent with the next update - RTI::ULong numAttribs = attributes.size(); + size_t numAttribs = attributeHandleSet.size(); for (RTI::ULong i = 0; i < numAttribs; ++i) { - unsigned index = getAttributeIndex(attributes.getHandle(i)); + unsigned index = getAttributeIndex(attributeHandleSet[i]); setAttributeForceUpdate(index); } } @@ -400,72 +409,72 @@ RTI13ObjectInstance::updateAttributeValues(const SGTimeStamp& timeStamp, const R } void -RTI13ObjectInstance::attributesInScope(const RTI::AttributeHandleSet& attributeHandleSet) +RTI13ObjectInstance::attributesInScope(const std::vector& attributeHandleSet) { - RTI::ULong numAttribs = attributeHandleSet.size(); + size_t numAttribs = attributeHandleSet.size(); for (RTI::ULong i = 0; i < numAttribs; ++i) { - RTI::AttributeHandle attributeHandle = attributeHandleSet.getHandle(i); + RTI::AttributeHandle attributeHandle = attributeHandleSet[i]; setAttributeInScope(getAttributeIndex(attributeHandle), true); } } void -RTI13ObjectInstance::attributesOutOfScope(const RTI::AttributeHandleSet& attributeHandleSet) +RTI13ObjectInstance::attributesOutOfScope(const std::vector& attributeHandleSet) { - RTI::ULong numAttribs = attributeHandleSet.size(); + size_t numAttribs = attributeHandleSet.size(); for (RTI::ULong i = 0; i < numAttribs; ++i) { - RTI::AttributeHandle attributeHandle = attributeHandleSet.getHandle(i); + RTI::AttributeHandle attributeHandle = attributeHandleSet[i]; setAttributeInScope(getAttributeIndex(attributeHandle), false); } } void -RTI13ObjectInstance::turnUpdatesOnForObjectInstance(const RTI::AttributeHandleSet& attributeHandleSet) +RTI13ObjectInstance::turnUpdatesOnForObjectInstance(const std::vector& attributeHandleSet) { - RTI::ULong numAttribs = attributeHandleSet.size(); + size_t numAttribs = attributeHandleSet.size(); for (RTI::ULong i = 0; i < numAttribs; ++i) { - RTI::AttributeHandle attributeHandle = attributeHandleSet.getHandle(i); + RTI::AttributeHandle attributeHandle = attributeHandleSet[i]; setAttributeUpdateEnabled(getAttributeIndex(attributeHandle), true); } } void -RTI13ObjectInstance::turnUpdatesOffForObjectInstance(const RTI::AttributeHandleSet& attributeHandleSet) +RTI13ObjectInstance::turnUpdatesOffForObjectInstance(const std::vector& attributeHandleSet) { - RTI::ULong numAttribs = attributeHandleSet.size(); + size_t numAttribs = attributeHandleSet.size(); for (RTI::ULong i = 0; i < numAttribs; ++i) { - RTI::AttributeHandle attributeHandle = attributeHandleSet.getHandle(i); + RTI::AttributeHandle attributeHandle = attributeHandleSet[i]; setAttributeUpdateEnabled(getAttributeIndex(attributeHandle), false); } } void -RTI13ObjectInstance::requestAttributeOwnershipAssumption(const RTI::AttributeHandleSet& attributes, const RTIData& tag) +RTI13ObjectInstance::requestAttributeOwnershipAssumption(const std::vector& attributes, const RTIData& tag) { } void -RTI13ObjectInstance::attributeOwnershipDivestitureNotification(const RTI::AttributeHandleSet& attributes) +RTI13ObjectInstance::attributeOwnershipDivestitureNotification(const std::vector& attributes) { } void -RTI13ObjectInstance::attributeOwnershipAcquisitionNotification(const RTI::AttributeHandleSet& attributes) +RTI13ObjectInstance::attributeOwnershipAcquisitionNotification(const std::vector& attributes) { } void -RTI13ObjectInstance::attributeOwnershipUnavailable(const RTI::AttributeHandleSet& attributes) +RTI13ObjectInstance::attributeOwnershipUnavailable(const std::vector& attributes) { } void -RTI13ObjectInstance::requestAttributeOwnershipRelease(const RTI::AttributeHandleSet& attributes, const RTIData& tag) +RTI13ObjectInstance::requestAttributeOwnershipRelease(const std::vector& attributes, const RTIData& tag) { } void -RTI13ObjectInstance::confirmAttributeOwnershipAcquisitionCancellation(const RTI::AttributeHandleSet& attributes) +RTI13ObjectInstance::confirmAttributeOwnershipAcquisitionCancellation(const std::vector& attributes) { } diff --git a/simgear/hla/RTI13ObjectInstance.hxx b/simgear/hla/RTI13ObjectInstance.hxx index 654bff92..38fd92b2 100644 --- a/simgear/hla/RTI13ObjectInstance.hxx +++ b/simgear/hla/RTI13ObjectInstance.hxx @@ -37,6 +37,9 @@ namespace simgear { class RTI13Ambassador; class RTI13ObjectClass; +typedef std::pair RTI13AttributeHandleDataPair; +typedef std::list RTI13AttributeHandleDataPairList; + class RTI13ObjectInstance : public RTIObjectInstance { public: RTI13ObjectInstance(const RTI::ObjectHandle& handle, HLAObjectInstance* hlaObjectInstance, const RTI13ObjectClass* objectClass, RTI13Ambassador* ambassador, bool owned); @@ -65,27 +68,27 @@ public: virtual void deleteObjectInstance(const SGTimeStamp& timeStamp, const RTIData& tag); virtual void localDeleteObjectInstance(); - void reflectAttributeValues(const RTI::AttributeHandleValuePairSet& attributeValuePairSet, const RTIData& tag); - void reflectAttributeValues(const RTI::AttributeHandleValuePairSet& attributeValuePairSet, const SGTimeStamp& timeStamp, const RTIData& tag); + void reflectAttributeValues(RTI13AttributeHandleDataPairList& attributeHandleDataPairList, const RTIData& tag); + void reflectAttributeValues(RTI13AttributeHandleDataPairList& attributeHandleDataPairList, const SGTimeStamp& timeStamp, const RTIData& tag); virtual void requestObjectAttributeValueUpdate(); - void provideAttributeValueUpdate(const RTI::AttributeHandleSet& attributes); + void provideAttributeValueUpdate(const std::vector& attributes); virtual void updateAttributeValues(const RTIData& tag); virtual void updateAttributeValues(const SGTimeStamp& timeStamp, const RTIData& tag); - void attributesInScope(const RTI::AttributeHandleSet& attributes); - void attributesOutOfScope(const RTI::AttributeHandleSet& attributes); + void attributesInScope(const std::vector& attributes); + void attributesOutOfScope(const std::vector& attributes); - void turnUpdatesOnForObjectInstance(const RTI::AttributeHandleSet& attributes); - void turnUpdatesOffForObjectInstance(const RTI::AttributeHandleSet& attributes); + void turnUpdatesOnForObjectInstance(const std::vector& attributes); + void turnUpdatesOffForObjectInstance(const std::vector& attributes); // Not yet sure what to do here. But the dispatch functions are already there - void requestAttributeOwnershipAssumption(const RTI::AttributeHandleSet& attributes, const RTIData& tag); - void attributeOwnershipDivestitureNotification(const RTI::AttributeHandleSet& attributes); - void attributeOwnershipAcquisitionNotification(const RTI::AttributeHandleSet& attributes); - void attributeOwnershipUnavailable(const RTI::AttributeHandleSet& attributes); - void requestAttributeOwnershipRelease(const RTI::AttributeHandleSet& attributes, const RTIData& tag); - void confirmAttributeOwnershipAcquisitionCancellation(const RTI::AttributeHandleSet& attributes); + void requestAttributeOwnershipAssumption(const std::vector& attributes, const RTIData& tag); + void attributeOwnershipDivestitureNotification(const std::vector& attributes); + void attributeOwnershipAcquisitionNotification(const std::vector& attributes); + void attributeOwnershipUnavailable(const std::vector& attributes); + void requestAttributeOwnershipRelease(const std::vector& attributes, const RTIData& tag); + void confirmAttributeOwnershipAcquisitionCancellation(const std::vector& attributes); void informAttributeOwnership(RTI::AttributeHandle attributeHandle, RTI::FederateHandle federateHandle); void attributeIsNotOwned(RTI::AttributeHandle attributeHandle); void attributeOwnedByRTI(RTI::AttributeHandle attributeHandle); diff --git a/simgear/hla/RTIData.hxx b/simgear/hla/RTIData.hxx index dff66dbf..2dc32b06 100644 --- a/simgear/hla/RTIData.hxx +++ b/simgear/hla/RTIData.hxx @@ -115,6 +115,13 @@ public: ensureCapacity(capacity); } + void swap(RTIData& data) + { + std::swap(_data, data._data); + std::swap(_size, data._size); + std::swap(_capacity, data._capacity); + } + void setData(char* data, unsigned size) { if (_capacity) diff --git a/simgear/hla/RTIObjectClass.cxx b/simgear/hla/RTIObjectClass.cxx index 98618cfc..dceb3029 100644 --- a/simgear/hla/RTIObjectClass.cxx +++ b/simgear/hla/RTIObjectClass.cxx @@ -39,6 +39,7 @@ RTIObjectClass::discoverInstance(RTIObjectInstance* objectInstance, const RTIDat return; } hlaObjectClass->discoverInstance(objectInstance, tag); + objectInstance->requestObjectAttributeValueUpdate(); } void diff --git a/simgear/hla/RTIObjectInstance.hxx b/simgear/hla/RTIObjectInstance.hxx index e3e37b6d..61ff9328 100644 --- a/simgear/hla/RTIObjectInstance.hxx +++ b/simgear/hla/RTIObjectInstance.hxx @@ -60,20 +60,6 @@ public: virtual void updateAttributeValues(const SGTimeStamp& timeStamp, const RTIData& tag) = 0; void removeInstance(const RTIData& tag); - // Call this if you want to roll up the queued timestamed updates - // and reflect that into the attached data elements. - void reflectQueuedAttributeValues(const SGTimeStamp& timeStamp) - { - // replay all updates up to the given timestamp - UpdateListMap::iterator last = _updateListMap.upper_bound(timeStamp); - for (UpdateListMap::iterator i = _updateListMap.begin(); i != last; ++i) { - for (UpdateList::iterator j = i->second.begin(); j != i->second.end(); ++j) { - // FIXME have a variant that takes the timestamp? - reflectAttributeValues(j->_indexDataPairList, j->_tag); - } - putUpdateToPool(i->second); - } - } void reflectAttributeValues(const RTIIndexDataPairList& dataPairList, const RTIData& tag); void reflectAttributeValues(const RTIIndexDataPairList& dataPairList, const SGTimeStamp& timeStamp, const RTIData& tag); void reflectAttributeValue(unsigned i, const RTIData& data) @@ -241,80 +227,25 @@ protected: // Is true if we should emit a requestattr bool _pendingAttributeUpdateRequest; - // Contains a full update as it came in from the RTI - struct Update { - RTIIndexDataPairList _indexDataPairList; - RTIData _tag; - }; - // A bunch of updates for the same timestamp - typedef std::list UpdateList; - // The timestamp sorted list of updates - typedef std::map UpdateListMap; - - // The timestamped updates sorted by timestamp - UpdateListMap _updateListMap; - - // The pool of unused updates so that we do not need to malloc/free each time - UpdateList _updateList; - - void getUpdateFromPool(UpdateList& updateList) - { - if (_updateList.empty()) - updateList.push_back(Update()); - else - updateList.splice(updateList.end(), _updateList, _updateList.begin()); - } - void putUpdateToPool(UpdateList& updateList) - { - for (UpdateList::iterator i = updateList.begin(); i != updateList.end(); ++i) - putDataToPool(i->_indexDataPairList); - _updateList.splice(_updateList.end(), updateList); - } - - // Appends the updates in the list to the given timestamps updates - void scheduleUpdates(const SGTimeStamp& timeStamp, UpdateList& updateList) - { - UpdateListMap::iterator i = _updateListMap.find(timeStamp); - if (i == _updateListMap.end()) - i = _updateListMap.insert(UpdateListMap::value_type(timeStamp, UpdateList())).first; - i->second.splice(i->second.end(), updateList); - } + // Pool of update list entries + RTIIndexDataPairList _indexDataPairList; // This adds raw storage for attribute index i to the end of the dataPairList. - void getDataFromPool(unsigned i, RTIIndexDataPairList& dataPairList) + void getDataFromPool(RTIIndexDataPairList& dataPairList) { - if (_attributeData.size() <= i) { - SG_LOG(SG_NETWORK, SG_WARN, "RTI: Invalid object attribute index!"); - return; - } - // Nothing left in the pool - so allocate something - if (_attributeData[i]._indexDataPairList.empty()) { + if (_indexDataPairList.empty()) { dataPairList.push_back(RTIIndexDataPairList::value_type()); - dataPairList.back().first = i; return; } // Take one from the pool - dataPairList.splice(dataPairList.end(), - _attributeData[i]._indexDataPairList, - _attributeData[i]._indexDataPairList.begin()); + dataPairList.splice(dataPairList.end(), _indexDataPairList, _indexDataPairList.begin()); } void putDataToPool(RTIIndexDataPairList& dataPairList) { - while (!dataPairList.empty()) { - // Put back into the pool - unsigned i = dataPairList.front().first; - if (_attributeData.size() <= i) { - // should not happen!!! - SG_LOG(SG_NETWORK, SG_WARN, "RTI: Invalid object attribute index!"); - dataPairList.pop_front(); - } else { - _attributeData[i]._indexDataPairList.splice(_attributeData[i]._indexDataPairList.begin(), - dataPairList, dataPairList.begin()); - } - } + _indexDataPairList.splice(_indexDataPairList.begin(), dataPairList); } struct AttributeData { -- 2.39.2