X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fhla%2FHLAObjectInstance.cxx;h=a163c5953dbb12331ea3069d5736f7e42927c9ce;hb=098441f5fbbcff41508b9411ecf2904f84a7eb81;hp=1644d938c3c6be01ba57dd7ea03912640a0a9f24;hpb=08cb2039c53cff49e93e621621a9796b1c43f574;p=simgear.git diff --git a/simgear/hla/HLAObjectInstance.cxx b/simgear/hla/HLAObjectInstance.cxx index 1644d938..a163c595 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 @@ -18,109 +18,109 @@ #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::HLAObjectInstance(HLAObjectClass* objectClass) : - _objectClass(objectClass) +HLAObjectInstance::UpdateCallback::~UpdateCallback() { } -HLAObjectInstance::HLAObjectInstance(HLAObjectClass* objectClass, RTIObjectInstance* rtiObjectInstance) : - _objectClass(objectClass), - _rtiObjectInstance(rtiObjectInstance) +HLAObjectInstance::ReflectCallback::~ReflectCallback() { - _rtiObjectInstance->_hlaObjectInstance = this; - _name = _rtiObjectInstance->getName(); } -HLAObjectInstance::~HLAObjectInstance() +HLAObjectInstance::HLAObjectInstance(HLAObjectClass* objectClass) : + _federate(objectClass->_federate), + _objectClass(objectClass) { } -SGSharedPtr -HLAObjectInstance::getObjectClass() const +HLAObjectInstance::~HLAObjectInstance() { - return _objectClass.lock(); + _clearRTIObjectInstance(); } unsigned HLAObjectInstance::getNumAttributes() const { - if (!_rtiObjectInstance.valid()) { - SG_LOG(SG_IO, SG_ALERT, "Trying to get number of attributes for inactive object!"); - 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); + 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!"); - 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); + 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); +} + +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 { @@ -312,9 +312,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 +325,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,17 +344,17 @@ 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; } private: @@ -387,8 +387,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; } @@ -416,21 +416,19 @@ HLAObjectInstance::registerInstance() 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.valid()) { SG_LOG(SG_IO, SG_ALERT, "Could not register object with unknown object class!"); return; } // 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 @@ -440,61 +438,221 @@ 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::updateAttributeValues(const RTIData& tag) +{ + if (_attributeCallback.valid()) + _attributeCallback->updateAttributeValues(*this, tag); + if (_updateCallback.valid()) { + _updateCallback->updateAttributeValues(*this, tag); + } else { + encodeAttributeValues(); + sendAttributeValues(tag); + } +} + +void +HLAObjectInstance::updateAttributeValues(const SGTimeStamp& timeStamp, const RTIData& tag) +{ + if (_attributeCallback.valid()) + _attributeCallback->updateAttributeValues(*this, 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_INFO, "Not updating inactive object!"); + return; + } + HLADataElement* dataElement = getAttributeDataElement(index); + if (!dataElement) + return; + _rtiObjectInstance->encodeAttributeData(index, *dataElement); + dataElement->setDirty(false); +} + +void +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::removeInstance(const RTIData& tag) +HLAObjectInstance::reflectAttributeValues(const HLAIndexList& indexList, const RTIData& tag) +{ + 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) { - SGSharedPtr objectClass = _objectClass.lock(); - if (!objectClass.valid()) + HLADataElement* dataElement = getAttributeDataElement(index); + if (!dataElement) return; - objectClass->removeInstanceCallback(*this, tag); + dataElement->setTimeStampValid(false); + _rtiObjectInstance->decodeAttributeData(index, *dataElement); } void -HLAObjectInstance::reflectAttributeValues(const RTIIndexDataPairList& dataPairList, const RTIData& tag) +HLAObjectInstance::reflectAttributeValue(unsigned index, const SGTimeStamp& timeStamp, const RTIData& tag) { - if (!_attributeCallback.valid()) + HLADataElement* dataElement = getAttributeDataElement(index); + if (!dataElement) return; - _attributeCallback->reflectAttributeValues(*this, dataPairList, tag); + dataElement->setTimeStamp(timeStamp); + dataElement->setTimeStampValid(true); + _rtiObjectInstance->decodeAttributeData(index, *dataElement); } void -HLAObjectInstance::reflectAttributeValues(const RTIIndexDataPairList& dataPairList, - const SGTimeStamp& timeStamp, const RTIData& tag) +HLAObjectInstance::_setRTIObjectInstance(RTIObjectInstance* rtiObjectInstance) { - if (!_attributeCallback.valid()) + _rtiObjectInstance = rtiObjectInstance; + _rtiObjectInstance->setObjectInstance(this); + _name = _rtiObjectInstance->getName(); + + unsigned numAttributes = getNumAttributes(); + _attributeVector.resize(numAttributes); + for (unsigned i = 0; i < numAttributes; ++i) { + HLAUpdateType updateType = getObjectClass()->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 = getObjectClass()->getAttributeUpdateType(i); + if (getAttributeOwned(i)) + continue; + if (updateType == HLAUndefinedUpdate) + continue; + if (updateType == HLAPeriodicUpdate) + continue; + indexList.push_back(i); + } + _rtiObjectInstance->requestObjectAttributeValueUpdate(indexList); +} + +void +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 (!_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 if (_attributeCallback.valid()) { + reflectAttributeValues(indexList, tag); + + RTIIndexDataPairList dataPairList; + for (HLAIndexList::const_iterator i = indexList.begin(); i != indexList.end(); ++i) { + dataPairList.push_back(RTIIndexDataPair()); + dataPairList.back().first = *i; + getAttributeData(*i, dataPairList.back().second); + } + _attributeCallback->reflectAttributeValues(*this, dataPairList, 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 if (_attributeCallback.valid()) { + reflectAttributeValues(indexList, timeStamp, tag); + + RTIIndexDataPairList dataPairList; + for (HLAIndexList::const_iterator i = indexList.begin(); i != indexList.end(); ++i) { + dataPairList.push_back(RTIIndexDataPair()); + dataPairList.back().first = *i; + getAttributeData(*i, dataPairList.back().second); + } + _attributeCallback->reflectAttributeValues(*this, dataPairList, timeStamp, tag); + } else { + reflectAttributeValues(indexList, timeStamp, tag); + } } } // namespace simgear