X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fhla%2FHLAObjectInstance.cxx;h=f1b7fed07a52085103ae06422646bdf6b9f6c28f;hb=2815688c7ebf2be0dcf3cc0d271bb694dafa8ae7;hp=0324d328b54a3584b6f811984e175007867f32af;hpb=252a539e69bda7cf8cf0c5198f25f38b0a710ee2;p=simgear.git diff --git a/simgear/hla/HLAObjectInstance.cxx b/simgear/hla/HLAObjectInstance.cxx index 0324d328..f1b7fed0 100644 --- a/simgear/hla/HLAObjectInstance.cxx +++ b/simgear/hla/HLAObjectInstance.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de +// Copyright (C) 2009 - 2012 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 @@ -15,115 +15,148 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + #include "HLAObjectInstance.hxx" #include +#include "simgear/debug/logstream.hxx" #include "HLAArrayDataElement.hxx" #include "HLABasicDataElement.hxx" #include "HLADataElement.hxx" #include "HLAEnumeratedDataElement.hxx" +#include "HLAFederate.hxx" #include "HLAFixedRecordDataElement.hxx" #include "HLAObjectClass.hxx" -#include "HLAVariantDataElement.hxx" +#include "HLAVariantRecordDataElement.hxx" #include "RTIObjectClass.hxx" #include "RTIObjectInstance.hxx" namespace simgear { +HLAObjectInstance::UpdateCallback::~UpdateCallback() +{ +} + +HLAObjectInstance::ReflectCallback::~ReflectCallback() +{ +} + HLAObjectInstance::HLAObjectInstance(HLAObjectClass* objectClass) : _objectClass(objectClass) { + if (objectClass) + _federate = objectClass->_federate; } -HLAObjectInstance::HLAObjectInstance(HLAObjectClass* objectClass, RTIObjectInstance* rtiObjectInstance) : - _objectClass(objectClass), - _rtiObjectInstance(rtiObjectInstance) +HLAObjectInstance::~HLAObjectInstance() { - _rtiObjectInstance->_hlaObjectInstance = this; - _name = _rtiObjectInstance->getName(); + _clearRTIObjectInstance(); } -HLAObjectInstance::~HLAObjectInstance() +const std::string& +HLAObjectInstance::getName() const +{ + return _name; +} + +const SGWeakPtr& +HLAObjectInstance::getFederate() const { + return _federate; } -SGSharedPtr +const SGSharedPtr& HLAObjectInstance::getObjectClass() const { - return _objectClass.lock(); + return _objectClass; } unsigned HLAObjectInstance::getNumAttributes() const { - if (!_rtiObjectInstance.valid()) { - SG_LOG(SG_IO, SG_ALERT, "Trying to get number of attributes for inactive object!"); + if (!_objectClass.valid()) return 0; - } - return _rtiObjectInstance->getNumAttributes(); + return _objectClass->getNumAttributes(); } unsigned HLAObjectInstance::getAttributeIndex(const std::string& name) const { - if (!_rtiObjectInstance.valid()) { - SG_LOG(SG_IO, SG_ALERT, "Trying to get attribute index for inactive object!"); - return 0; - } - return _rtiObjectInstance->getAttributeIndex(name); + if (!_objectClass.valid()) + return ~0u; + return _objectClass->getAttributeIndex(name); } std::string HLAObjectInstance::getAttributeName(unsigned index) const { - if (!_rtiObjectInstance.valid()) { - SG_LOG(SG_IO, SG_ALERT, "Trying to get attribute name for inactive object!"); + if (!_objectClass.valid()) return std::string(); - } - return _rtiObjectInstance->getAttributeName(index); + return _objectClass->getAttributeName(index); } -const HLADataType* -HLAObjectInstance::getAttributeDataType(unsigned index) const +bool +HLAObjectInstance::getAttributeOwned(unsigned index) const { - if (!_rtiObjectInstance.valid()) { - SG_LOG(SG_IO, SG_ALERT, "Trying to get attribute index for inactive object!"); - return 0; - } - return _rtiObjectInstance->getAttributeDataType(index); + if (!_rtiObjectInstance.valid()) + return false; + return _rtiObjectInstance->getAttributeOwned(index); } -void -HLAObjectInstance::setAttributeDataElement(unsigned index, SGSharedPtr dataElement) +const HLADataType* +HLAObjectInstance::getAttributeDataType(unsigned index) const { - if (!_rtiObjectInstance.valid()) { - SG_LOG(SG_IO, SG_ALERT, "Trying to set data element for inactive object!"); - return; - } - _rtiObjectInstance->setDataElement(index, dataElement); + if (!_objectClass.valid()) + return 0; + return _objectClass->getAttributeDataType(index); } HLADataElement* HLAObjectInstance::getAttributeDataElement(unsigned index) { - if (!_rtiObjectInstance.valid()) { - SG_LOG(SG_IO, SG_ALERT, "Trying to set data element for inactive object!"); + if (_attributeVector.size() <= index) return 0; - } - return _rtiObjectInstance->getDataElement(index); + return _attributeVector[index]._dataElement.get(); } const HLADataElement* HLAObjectInstance::getAttributeDataElement(unsigned index) const { - if (!_rtiObjectInstance.valid()) { - SG_LOG(SG_IO, SG_ALERT, "Trying to set data element for inactive object!"); + if (_attributeVector.size() <= index) return 0; + return _attributeVector[index]._dataElement.get(); +} + +bool +HLAObjectInstance::getAttributeData(unsigned index, RTIData& data) const +{ + if (!_rtiObjectInstance.valid()) { + SG_LOG(SG_IO, SG_ALERT, "Trying to get raw attribute data without rti object instance for \"" << getName() << "\"!"); + return false; } - return _rtiObjectInstance->getDataElement(index); + return _rtiObjectInstance->getAttributeData(index, data); } -class HLAObjectInstance::DataElementFactoryVisitor : public HLADataTypeVisitor { +void +HLAObjectInstance::setAttributeDataElement(unsigned index, const SGSharedPtr& dataElement) +{ + unsigned numAttributes = getNumAttributes(); + if (numAttributes <= index) + return; + _attributeVector.resize(numAttributes); + if (_attributeVector[index]._dataElement.valid()) + _attributeVector[index]._dataElement->clearStamp(); + _attributeVector[index]._dataElement = dataElement; + if (_attributeVector[index]._dataElement.valid()) + _attributeVector[index]._dataElement->createStamp(); +} + +class HLAObjectInstance::DataElementFactoryVisitor : public HLADataElementFactoryVisitor { public: DataElementFactoryVisitor(const HLAPathElementMap& pathElementMap) : _pathElementMap(pathElementMap) @@ -150,7 +183,7 @@ public: if (_dataElement.valid()) return; - _dataElement = new HLASCharDataElement(&dataType); + HLADataElementFactoryVisitor::apply(dataType); } virtual void apply(const HLAUInt8DataType& dataType) { @@ -158,7 +191,7 @@ public: if (_dataElement.valid()) return; - _dataElement = new HLAUCharDataElement(&dataType); + HLADataElementFactoryVisitor::apply(dataType); } virtual void apply(const HLAInt16DataType& dataType) { @@ -166,7 +199,7 @@ public: if (_dataElement.valid()) return; - _dataElement = new HLAShortDataElement(&dataType); + HLADataElementFactoryVisitor::apply(dataType); } virtual void apply(const HLAUInt16DataType& dataType) { @@ -174,7 +207,7 @@ public: if (_dataElement.valid()) return; - _dataElement = new HLAUShortDataElement(&dataType); + HLADataElementFactoryVisitor::apply(dataType); } virtual void apply(const HLAInt32DataType& dataType) { @@ -182,7 +215,7 @@ public: if (_dataElement.valid()) return; - _dataElement = new HLAIntDataElement(&dataType); + HLADataElementFactoryVisitor::apply(dataType); } virtual void apply(const HLAUInt32DataType& dataType) { @@ -190,7 +223,7 @@ public: if (_dataElement.valid()) return; - _dataElement = new HLAUIntDataElement(&dataType); + HLADataElementFactoryVisitor::apply(dataType); } virtual void apply(const HLAInt64DataType& dataType) { @@ -198,7 +231,7 @@ public: if (_dataElement.valid()) return; - _dataElement = new HLALongDataElement(&dataType); + HLADataElementFactoryVisitor::apply(dataType); } virtual void apply(const HLAUInt64DataType& dataType) { @@ -206,7 +239,7 @@ public: if (_dataElement.valid()) return; - _dataElement = new HLAULongDataElement(&dataType); + HLADataElementFactoryVisitor::apply(dataType); } virtual void apply(const HLAFloat32DataType& dataType) { @@ -214,7 +247,7 @@ public: if (_dataElement.valid()) return; - _dataElement = new HLAFloatDataElement(&dataType); + HLADataElementFactoryVisitor::apply(dataType); } virtual void apply(const HLAFloat64DataType& dataType) { @@ -222,7 +255,7 @@ public: if (_dataElement.valid()) return; - _dataElement = new HLADoubleDataElement(&dataType); + HLADataElementFactoryVisitor::apply(dataType); } class ArrayDataElementFactory : public HLAArrayDataElement::DataElementFactory { @@ -287,7 +320,7 @@ public: if (_dataElement.valid()) return; - _dataElement = new HLAEnumeratedDataElement(&dataType); + HLADataElementFactoryVisitor::apply(dataType); } virtual void apply(const HLAFixedRecordDataType& dataType) @@ -312,9 +345,9 @@ public: _dataElement = recordDataElement; } - class VariantDataElementFactory : public HLAVariantDataElement::DataElementFactory { + class VariantRecordDataElementFactory : public HLAVariantRecordDataElement::DataElementFactory { public: - VariantDataElementFactory(const HLADataElement::Path& path, const HLAPathElementMap& pathElementMap) : + VariantRecordDataElementFactory(const HLADataElement::Path& path, const HLAPathElementMap& pathElementMap) : _path(path) { for (HLAPathElementMap::const_iterator i = pathElementMap.lower_bound(path); @@ -325,9 +358,9 @@ public: _pathElementMap.insert(*i); } } - virtual HLADataElement* createElement(const HLAVariantDataElement& element, unsigned index) + virtual HLADataElement* createElement(const HLAVariantRecordDataElement& element, unsigned index) { - const HLAVariantDataType* dataType = element.getDataType(); + const HLAVariantRecordDataType* dataType = element.getDataType(); if (!dataType) return 0; const HLADataType* alternativeDataType = element.getAlternativeDataType(); @@ -344,22 +377,19 @@ public: HLAPathElementMap _pathElementMap; }; - virtual void apply(const HLAVariantDataType& dataType) + virtual void apply(const HLAVariantRecordDataType& dataType) { _dataElement = createDataElement(_path, dataType); if (_dataElement.valid()) return; - SGSharedPtr variantDataElement; - variantDataElement = new HLAVariantDataElement(&dataType); - variantDataElement->setDataElementFactory(new VariantDataElementFactory(_path, _pathElementMap)); + SGSharedPtr variantRecordDataElement; + variantRecordDataElement = new HLAVariantRecordDataElement(&dataType); + variantRecordDataElement->setDataElementFactory(new VariantRecordDataElementFactory(_path, _pathElementMap)); - _dataElement = variantDataElement; + _dataElement = variantRecordDataElement; } - const SGSharedPtr& getDataElement() const - { return _dataElement; } - private: SGSharedPtr createDataElement(const HLADataElement::Path& path, const HLADataType& dataType) { @@ -381,7 +411,6 @@ private: return dataElement; } - SGSharedPtr _dataElement; const HLAPathElementMap& _pathElementMap; HLADataElement::Path _path; }; @@ -391,8 +420,8 @@ HLAObjectInstance::setAttribute(unsigned index, const HLAPathElementMap& pathEle { const HLADataType* dataType = getAttributeDataType(index); if (!dataType) { - SG_LOG(SG_IO, SG_ALERT, "Cannot get attribute data type for setting attribute at index " - << index << "!"); + SG_LOG(SG_IO, SG_ALERT, "Cannot get attribute data type for setting attribute \"" + << getAttributeName(index) << "\" at index " << index << "!"); return; } @@ -414,47 +443,37 @@ HLAObjectInstance::setAttributes(const HLAAttributePathElementMap& attributePath } void -HLAObjectInstance::requestAttributeUpdate(unsigned index) +HLAObjectInstance::registerInstance() { - if (!_rtiObjectInstance.valid()) { - SG_LOG(SG_IO, SG_ALERT, "Trying to request attribute update for inactive object!"); - return; - } - _rtiObjectInstance->setRequestAttributeUpdate(index, true); + registerInstance(_objectClass.get()); } void -HLAObjectInstance::requestAttributeUpdate() -{ - if (!_rtiObjectInstance.valid()) { - SG_LOG(SG_IO, SG_ALERT, "Trying to request attribute update for inactive object!"); - return; - } - _rtiObjectInstance->setRequestAttributeUpdate(true); -} - -void -HLAObjectInstance::registerInstance() +HLAObjectInstance::registerInstance(HLAObjectClass* objectClass) { if (_rtiObjectInstance.valid()) { SG_LOG(SG_IO, SG_ALERT, "Trying to register object " << getName() << " already known to the RTI!"); return; } - SGSharedPtr objectClass = _objectClass.lock(); - if (!objectClass.valid()) { + if (!objectClass) { SG_LOG(SG_IO, SG_ALERT, "Could not register object with unknown object class!"); return; } + if (_objectClass.valid() && objectClass != _objectClass.get()) { + SG_LOG(SG_IO, SG_ALERT, "Could not change object class while registering!"); + return; + } + _objectClass = objectClass; + _federate = _objectClass->_federate; // This error must have been flagged before - if (!objectClass->_rtiObjectClass.valid()) + if (!_objectClass->_rtiObjectClass.valid()) return; - _rtiObjectInstance = objectClass->_rtiObjectClass->registerObjectInstance(this); + _setRTIObjectInstance(_objectClass->_rtiObjectClass->registerObjectInstance(this)); if (!_rtiObjectInstance.valid()) { SG_LOG(SG_IO, SG_ALERT, "Could not register object at the RTI!"); return; } - _name = _rtiObjectInstance->getName(); - objectClass->registerInstance(*this); + _objectClass->_registerInstance(this); } void @@ -464,81 +483,200 @@ HLAObjectInstance::deleteInstance(const RTIData& tag) SG_LOG(SG_IO, SG_ALERT, "Trying to delete inactive object!"); return; } - SGSharedPtr objectClass = _objectClass.lock(); - if (!objectClass.valid()) + if (!_objectClass.valid()) return; - objectClass->deleteInstance(*this); + _objectClass->_deleteInstance(*this); _rtiObjectInstance->deleteObjectInstance(tag); } void -HLAObjectInstance::localDeleteInstance() +HLAObjectInstance::updateAttributeValues(const RTIData& tag) +{ + if (_updateCallback.valid()) { + _updateCallback->updateAttributeValues(*this, tag); + } else { + encodeAttributeValues(); + sendAttributeValues(tag); + } +} + +void +HLAObjectInstance::updateAttributeValues(const SGTimeStamp& timeStamp, const RTIData& tag) +{ + if (_updateCallback.valid()) { + _updateCallback->updateAttributeValues(*this, timeStamp, tag); + } else { + encodeAttributeValues(); + sendAttributeValues(timeStamp, tag); + } +} + +void +HLAObjectInstance::encodeAttributeValues() +{ + unsigned numAttributes = _attributeVector.size(); + for (unsigned i = 0; i < numAttributes;++i) { + if (_attributeVector[i]._unconditionalUpdate) { + encodeAttributeValue(i); + } else if (_attributeVector[i]._enabledUpdate) { + const HLADataElement* dataElement = getAttributeDataElement(i); + if (dataElement && dataElement->getDirty()) + encodeAttributeValue(i); + } + } +} + +void +HLAObjectInstance::encodeAttributeValue(unsigned index) { if (!_rtiObjectInstance.valid()) { - SG_LOG(SG_IO, SG_ALERT, "Trying to delete inactive object!"); + SG_LOG(SG_IO, SG_INFO, "Not updating inactive object!"); return; } - _rtiObjectInstance->localDeleteObjectInstance(); + HLADataElement* dataElement = getAttributeDataElement(index); + if (!dataElement) + return; + _rtiObjectInstance->encodeAttributeData(index, *dataElement); + dataElement->setDirty(false); } void -HLAObjectInstance::updateAttributeValues(const RTIData& tag) +HLAObjectInstance::sendAttributeValues(const RTIData& tag) { if (!_rtiObjectInstance.valid()) { SG_LOG(SG_IO, SG_INFO, "Not updating inactive object!"); return; } - if (_attributeCallback.valid()) - _attributeCallback->updateAttributeValues(*this, tag); _rtiObjectInstance->updateAttributeValues(tag); } void -HLAObjectInstance::updateAttributeValues(const SGTimeStamp& timeStamp, const RTIData& tag) +HLAObjectInstance::sendAttributeValues(const SGTimeStamp& timeStamp, const RTIData& tag) { if (!_rtiObjectInstance.valid()) { SG_LOG(SG_IO, SG_INFO, "Not updating inactive object!"); return; } - if (_attributeCallback.valid()) - _attributeCallback->updateAttributeValues(*this, tag); _rtiObjectInstance->updateAttributeValues(timeStamp, tag); } void -HLAObjectInstance::reflectQueuedAttributeValues(const SGTimeStamp& timeStamp) +HLAObjectInstance::reflectAttributeValues(const HLAIndexList& indexList, const RTIData& tag) { - if (!_rtiObjectInstance.valid()) { - SG_LOG(SG_IO, SG_INFO, "Not updating inactive object!"); + for (HLAIndexList::const_iterator i = indexList.begin(); i != indexList.end(); ++i) + reflectAttributeValue(*i, tag); +} + +void +HLAObjectInstance::reflectAttributeValues(const HLAIndexList& indexList, + const SGTimeStamp& timeStamp, const RTIData& tag) +{ + for (HLAIndexList::const_iterator i = indexList.begin(); i != indexList.end(); ++i) + reflectAttributeValue(*i, timeStamp, tag); +} + +void +HLAObjectInstance::reflectAttributeValue(unsigned index, const RTIData& tag) +{ + HLADataElement* dataElement = getAttributeDataElement(index); + if (!dataElement) return; - } - _rtiObjectInstance->reflectQueuedAttributeValues(timeStamp); + dataElement->setTimeStampValid(false); + _rtiObjectInstance->decodeAttributeData(index, *dataElement); } void -HLAObjectInstance::removeInstance(const RTIData& tag) +HLAObjectInstance::reflectAttributeValue(unsigned index, const SGTimeStamp& timeStamp, const RTIData& tag) { - SGSharedPtr objectClass = _objectClass.lock(); - if (!objectClass.valid()) + HLADataElement* dataElement = getAttributeDataElement(index); + if (!dataElement) return; - objectClass->removeInstanceCallback(*this, tag); + dataElement->setTimeStamp(timeStamp); + dataElement->setTimeStampValid(true); + _rtiObjectInstance->decodeAttributeData(index, *dataElement); } void -HLAObjectInstance::reflectAttributeValues(const RTIIndexDataPairList& dataPairList, const RTIData& tag) +HLAObjectInstance::_setRTIObjectInstance(RTIObjectInstance* rtiObjectInstance) { - if (!_attributeCallback.valid()) + if (!_objectClass.valid()) return; - _attributeCallback->reflectAttributeValues(*this, dataPairList, tag); + + _rtiObjectInstance = rtiObjectInstance; + _rtiObjectInstance->setObjectInstance(this); + _name = _rtiObjectInstance->getName(); + + unsigned numAttributes = getNumAttributes(); + _attributeVector.resize(numAttributes); + for (unsigned i = 0; i < numAttributes; ++i) { + HLAUpdateType updateType = _objectClass->getAttributeUpdateType(i); + if (getAttributeOwned(i) && updateType != HLAUndefinedUpdate) { + _attributeVector[i]._enabledUpdate = true; + _attributeVector[i]._unconditionalUpdate = (updateType == HLAPeriodicUpdate); + // In case of an owned attribute, now encode its value + encodeAttributeValue(i); + } else { + _attributeVector[i]._enabledUpdate = false; + _attributeVector[i]._unconditionalUpdate = false; + } + } + + // This makes sense with any new object. Even if we registered one, there might be unpublished attributes. + HLAIndexList indexList; + for (unsigned i = 0; i < numAttributes; ++i) { + HLAUpdateType updateType = _objectClass->getAttributeUpdateType(i); + if (getAttributeOwned(i)) + continue; + if (updateType == HLAUndefinedUpdate) + continue; + if (updateType == HLAPeriodicUpdate) + continue; + indexList.push_back(i); + } + _rtiObjectInstance->requestObjectAttributeValueUpdate(indexList); } void -HLAObjectInstance::reflectAttributeValues(const RTIIndexDataPairList& dataPairList, - const SGTimeStamp& timeStamp, const RTIData& tag) +HLAObjectInstance::_clearRTIObjectInstance() +{ + if (!_rtiObjectInstance.valid()) + return; + + for (unsigned i = 0; i < _attributeVector.size(); ++i) { + _attributeVector[i]._enabledUpdate = false; + _attributeVector[i]._unconditionalUpdate = false; + } + + _rtiObjectInstance->setObjectInstance(0); + _rtiObjectInstance = 0; +} + +void +HLAObjectInstance::_removeInstance(const RTIData& tag) { - if (!_attributeCallback.valid()) + if (!_objectClass.valid()) return; - _attributeCallback->reflectAttributeValues(*this, dataPairList, timeStamp, tag); + _objectClass->_removeInstance(*this, tag); +} + +void +HLAObjectInstance::_reflectAttributeValues(const HLAIndexList& indexList, const RTIData& tag) +{ + if (_reflectCallback.valid()) { + _reflectCallback->reflectAttributeValues(*this, indexList, tag); + } else { + reflectAttributeValues(indexList, tag); + } +} + +void +HLAObjectInstance::_reflectAttributeValues(const HLAIndexList& indexList, const SGTimeStamp& timeStamp, const RTIData& tag) +{ + if (_reflectCallback.valid()) { + _reflectCallback->reflectAttributeValues(*this, indexList, timeStamp, tag); + } else { + reflectAttributeValues(indexList, timeStamp, tag); + } } } // namespace simgear