]> git.mxchange.org Git - simgear.git/blobdiff - simgear/hla/HLAObjectInstance.cxx
HTTP: Rename urlretrieve/urlload to save/load.
[simgear.git] / simgear / hla / HLAObjectInstance.cxx
index 56ccf78e556640f5d209108f5877e715ce2cd68d..d1f4fac5e4c8a7786e506f5ded3ceb3d140db43e 100644 (file)
 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 //
 
+#ifdef HAVE_CONFIG_H
+#  include <simgear_config.h>
+#endif
+
+#include <simgear/compiler.h>
+
 #include "HLAObjectInstance.hxx"
 
 #include <algorithm>
@@ -41,9 +47,10 @@ HLAObjectInstance::ReflectCallback::~ReflectCallback()
 }
 
 HLAObjectInstance::HLAObjectInstance(HLAObjectClass* objectClass) :
-    _federate(objectClass->_federate),
     _objectClass(objectClass)
 {
+    if (objectClass)
+        _federate = objectClass->_federate;
 }
 
 HLAObjectInstance::~HLAObjectInstance()
@@ -72,18 +79,24 @@ HLAObjectInstance::getObjectClass() const
 unsigned
 HLAObjectInstance::getNumAttributes() const
 {
+    if (!_objectClass.valid())
+        return 0;
     return _objectClass->getNumAttributes();
 }
 
 unsigned
 HLAObjectInstance::getAttributeIndex(const std::string& name) const
 {
+    if (!_objectClass.valid())
+        return ~0u;
     return _objectClass->getAttributeIndex(name);
 }
 
 std::string
 HLAObjectInstance::getAttributeName(unsigned index) const
 {
+    if (!_objectClass.valid())
+        return std::string();
     return _objectClass->getAttributeName(index);
 }
 
@@ -98,6 +111,8 @@ HLAObjectInstance::getAttributeOwned(unsigned index) const
 const HLADataType*
 HLAObjectInstance::getAttributeDataType(unsigned index) const
 {
+    if (!_objectClass.valid())
+        return 0;
     return _objectClass->getAttributeDataType(index);
 }
 
@@ -141,303 +156,142 @@ HLAObjectInstance::setAttributeDataElement(unsigned index, const SGSharedPtr<HLA
         _attributeVector[index]._dataElement->createStamp();
 }
 
-class HLAObjectInstance::DataElementFactoryVisitor : public HLADataElementFactoryVisitor {
-public:
-    DataElementFactoryVisitor(const HLAPathElementMap& pathElementMap) :
-        _pathElementMap(pathElementMap)
-    { }
-    DataElementFactoryVisitor(const HLADataElement::Path& path, const HLAPathElementMap& pathElementMap) :
-        _pathElementMap(pathElementMap),
-        _path(path)
-    { }
-    virtual ~DataElementFactoryVisitor() {}
-
-    virtual void apply(const HLADataType& dataType)
-    {
-        _dataElement = createDataElement(_path, dataType);
-        if (_dataElement.valid())
-            return;
-
-        SG_LOG(SG_NETWORK, SG_ALERT, "HLA: Can not find a suitable data element for data type \""
-               << dataType.getName() << "\"");
-    }
-
-    virtual void apply(const HLAInt8DataType& dataType)
-    {
-        _dataElement = createDataElement(_path, dataType);
-        if (_dataElement.valid())
-            return;
-
-        HLADataElementFactoryVisitor::apply(dataType);
-    }
-    virtual void apply(const HLAUInt8DataType& dataType)
-    {
-        _dataElement = createDataElement(_path, dataType);
-        if (_dataElement.valid())
-            return;
-
-        HLADataElementFactoryVisitor::apply(dataType);
-    }
-    virtual void apply(const HLAInt16DataType& dataType)
-    {
-        _dataElement = createDataElement(_path, dataType);
-        if (_dataElement.valid())
-            return;
-
-        HLADataElementFactoryVisitor::apply(dataType);
-    }
-    virtual void apply(const HLAUInt16DataType& dataType)
-    {
-        _dataElement = createDataElement(_path, dataType);
-        if (_dataElement.valid())
-            return;
-
-        HLADataElementFactoryVisitor::apply(dataType);
-    }
-    virtual void apply(const HLAInt32DataType& dataType)
-    {
-        _dataElement = createDataElement(_path, dataType);
-        if (_dataElement.valid())
-            return;
-
-        HLADataElementFactoryVisitor::apply(dataType);
-    }
-    virtual void apply(const HLAUInt32DataType& dataType)
-    {
-        _dataElement = createDataElement(_path, dataType);
-        if (_dataElement.valid())
-            return;
-
-        HLADataElementFactoryVisitor::apply(dataType);
-    }
-    virtual void apply(const HLAInt64DataType& dataType)
-    {
-        _dataElement = createDataElement(_path, dataType);
-        if (_dataElement.valid())
-            return;
-
-        HLADataElementFactoryVisitor::apply(dataType);
-    }
-    virtual void apply(const HLAUInt64DataType& dataType)
-    {
-        _dataElement = createDataElement(_path, dataType);
-        if (_dataElement.valid())
-            return;
-
-        HLADataElementFactoryVisitor::apply(dataType);
-    }
-    virtual void apply(const HLAFloat32DataType& dataType)
-    {
-        _dataElement = createDataElement(_path, dataType);
-        if (_dataElement.valid())
-            return;
-
-        HLADataElementFactoryVisitor::apply(dataType);
-    }
-    virtual void apply(const HLAFloat64DataType& dataType)
-    {
-        _dataElement = createDataElement(_path, dataType);
-        if (_dataElement.valid())
-            return;
-
-        HLADataElementFactoryVisitor::apply(dataType);
-    }
-
-    class ArrayDataElementFactory : public HLAArrayDataElement::DataElementFactory {
-    public:
-        ArrayDataElementFactory(const HLADataElement::Path& path, const HLAPathElementMap& pathElementMap) :
-            _path(path)
-        {
-            for (HLAPathElementMap::const_iterator i = pathElementMap.lower_bound(path);
-                 i != pathElementMap.end(); ++i) {
-                if (i->first.begin() != std::search(i->first.begin(), i->first.end(),
-                                                    path.begin(), path.end()))
-                    break;
-                _pathElementMap.insert(*i);
-            }
-        }
-        virtual HLADataElement* createElement(const HLAArrayDataElement& element, unsigned index)
-        {
-            const HLADataType* dataType = element.getElementDataType();
-            if (!dataType)
-                return 0;
-            HLADataElement::Path path = _path;
-            path.push_back(HLADataElement::PathElement(index));
-            DataElementFactoryVisitor visitor(path, _pathElementMap);
-            dataType->accept(visitor);
-            return visitor._dataElement.release();
-        }
-    private:
-        HLADataElement::Path _path;
-        HLAPathElementMap _pathElementMap;
-    };
-
-    virtual void apply(const HLAFixedArrayDataType& dataType)
-    {
-        _dataElement = createDataElement(_path, dataType);
-        if (_dataElement.valid())
-            return;
-
-        SGSharedPtr<HLAArrayDataElement> arrayDataElement;
-        arrayDataElement = new HLAArrayDataElement(&dataType);
-        arrayDataElement->setDataElementFactory(new ArrayDataElementFactory(_path, _pathElementMap));
-        arrayDataElement->setNumElements(dataType.getNumElements());
-
-        _dataElement = arrayDataElement;
+bool
+HLAObjectInstance::getDataElementIndex(HLADataElementIndex& index, const std::string& path) const
+{
+    HLAObjectClass* objectClass = getObjectClass().get();
+    if (!objectClass) {
+        SG_LOG(SG_IO, SG_ALERT, "Could not get the data element index of an object instance with unknown class!");
+        return false;
     }
+    return objectClass->getDataElementIndex(index, path);
+}
 
-    virtual void apply(const HLAVariableArrayDataType& dataType)
-    {
-        _dataElement = createDataElement(_path, dataType);
-        if (_dataElement.valid())
-            return;
+HLADataElementIndex
+HLAObjectInstance::getDataElementIndex(const std::string& path) const
+{
+    HLADataElementIndex dataElementIndex;
+    getDataElementIndex(dataElementIndex, path);
+    return dataElementIndex;
+}
 
-        SGSharedPtr<HLAArrayDataElement> arrayDataElement;
-        arrayDataElement = new HLAArrayDataElement(&dataType);
-        arrayDataElement->setDataElementFactory(new ArrayDataElementFactory(_path, _pathElementMap));
+HLADataElement*
+HLAObjectInstance::getAttributeDataElement(const HLADataElementIndex& index)
+{
+    if (index.empty())
+        return 0;
+    HLADataElement* dataElement = getAttributeDataElement(index[0]);
+    if (!dataElement)
+        return 0;
+    return dataElement->getDataElement(index.begin() + 1, index.end());
+}
 
-        _dataElement = arrayDataElement;
-    }
+const HLADataElement*
+HLAObjectInstance::getAttributeDataElement(const HLADataElementIndex& index) const
+{
+    if (index.empty())
+        return 0;
+    const HLADataElement* dataElement = getAttributeDataElement(index[0]);
+    if (!dataElement)
+        return 0;
+    return dataElement->getDataElement(index.begin() + 1, index.end());
+}
 
-    virtual void apply(const HLAEnumeratedDataType& dataType)
-    {
-        _dataElement = createDataElement(_path, dataType);
-        if (_dataElement.valid())
+void
+HLAObjectInstance::setAttributeDataElement(const HLADataElementIndex& index, const SGSharedPtr<HLADataElement>& dataElement)
+{
+    if (index.empty())
+        return;
+    if (index.size() == 1) {
+        if (!getAttributeDataType(index[0]))
             return;
-
-        HLADataElementFactoryVisitor::apply(dataType);
-    }
-
-    virtual void apply(const HLAFixedRecordDataType& dataType)
-    {
-        _dataElement = createDataElement(_path, dataType);
-        if (_dataElement.valid())
+        if (dataElement.valid() && !dataElement->setDataType(getAttributeDataType(index[0])))
             return;
-
-        SGSharedPtr<HLAFixedRecordDataElement> recordDataElement;
-        recordDataElement = new HLAFixedRecordDataElement(&dataType);
-
-        unsigned numFields = dataType.getNumFields();
-        for (unsigned i = 0; i < numFields; ++i) {
-
-            _path.push_back(HLADataElement::PathElement(dataType.getFieldName(i)));
-
-            dataType.getFieldDataType(i)->accept(*this);
-            recordDataElement->setField(i, _dataElement.release());
-
-            _path.pop_back();
-        }
-        _dataElement = recordDataElement;
-    }
-
-    class VariantRecordDataElementFactory : public HLAVariantRecordDataElement::DataElementFactory {
-    public:
-        VariantRecordDataElementFactory(const HLADataElement::Path& path, const HLAPathElementMap& pathElementMap) :
-            _path(path)
-        {
-            for (HLAPathElementMap::const_iterator i = pathElementMap.lower_bound(path);
-                 i != pathElementMap.end(); ++i) {
-                if (i->first.begin() != std::search(i->first.begin(), i->first.end(),
-                                                    path.begin(), path.end()))
-                    break;
-                _pathElementMap.insert(*i);
-            }
-        }
-        virtual HLADataElement* createElement(const HLAVariantRecordDataElement& element, unsigned index)
-        {
-            const HLAVariantRecordDataType* dataType = element.getDataType();
-            if (!dataType)
-                return 0;
-            const HLADataType* alternativeDataType = element.getAlternativeDataType();
-            if (!alternativeDataType)
-                return 0;
-            HLADataElement::Path path = _path;
-            path.push_back(HLADataElement::PathElement(dataType->getAlternativeName(index)));
-            DataElementFactoryVisitor visitor(path, _pathElementMap);
-            alternativeDataType->accept(visitor);
-            return visitor._dataElement.release();
+        setAttributeDataElement(index[0], dataElement);
+    } else {
+        SGSharedPtr<HLADataElement> attributeDataElement = getAttributeDataElement(index[0]);
+        if (!attributeDataElement.valid()) {
+            createAndSetAttributeDataElement(index[0]);
+            attributeDataElement = getAttributeDataElement(index[0]);
         }
-    private:
-        HLADataElement::Path _path;
-        HLAPathElementMap _pathElementMap;
-    };
-
-    virtual void apply(const HLAVariantRecordDataType& dataType)
-    {
-        _dataElement = createDataElement(_path, dataType);
-        if (_dataElement.valid())
+        if (!attributeDataElement.valid())
             return;
-
-        SGSharedPtr<HLAVariantRecordDataElement> variantRecordDataElement;
-        variantRecordDataElement = new HLAVariantRecordDataElement(&dataType);
-        variantRecordDataElement->setDataElementFactory(new VariantRecordDataElementFactory(_path, _pathElementMap));
-
-        _dataElement = variantRecordDataElement;
+        attributeDataElement->setDataElement(index.begin() + 1, index.end(), dataElement.get());
     }
+}
 
-private:
-    SGSharedPtr<HLADataElement> createDataElement(const HLADataElement::Path& path, const HLADataType& dataType)
-    {
-        HLAPathElementMap::const_iterator i = _pathElementMap.find(path);
-        if (i == _pathElementMap.end()) {
-            SG_LOG(SG_IO, SG_WARN, "No dataElement provided for \""
-                   << HLADataElement::toString(path) << "\".");
+HLADataElement*
+HLAObjectInstance::getAttributeDataElement(const std::string& path)
+{
+    HLADataElementIndex index;
+    if (!getDataElementIndex(index, path))
+        return 0;
+    return getAttributeDataElement(index); 
+}
 
-            return 0;
-        }
-        SGSharedPtr<HLADataElement> dataElement = i->second.getDataElement(path);
-        if (!dataElement->setDataType(&dataType)) {
-            SG_LOG(SG_IO, SG_ALERT, "Cannot set data type for data element at \""
-                   << HLADataElement::toString(path) <<  "\"!");
-            return 0;
-        }
-        SG_LOG(SG_IO, SG_DEBUG, "Using provided dataElement for \""
-               << HLADataElement::toString(path) << "\".");
-        return dataElement;
-    }
+const HLADataElement*
+HLAObjectInstance::getAttributeDataElement(const std::string& path) const
+{
+    HLADataElementIndex index;
+    if (!getDataElementIndex(index, path))
+        return 0;
+    return getAttributeDataElement(index); 
+}
 
-    const HLAPathElementMap& _pathElementMap;
-    HLADataElement::Path _path;
-};
+void
+HLAObjectInstance::setAttributeDataElement(const std::string& path, const SGSharedPtr<HLADataElement>& dataElement)
+{
+    HLADataElementIndex index;
+    if (!getDataElementIndex(index, path))
+        return;
+    setAttributeDataElement(index, dataElement); 
+}
 
 void
-HLAObjectInstance::setAttribute(unsigned index, const HLAPathElementMap& pathElementMap)
+HLAObjectInstance::discoverInstance(const RTIData& tag)
 {
-    const HLADataType* dataType = getAttributeDataType(index);
-    if (!dataType) {
-        SG_LOG(SG_IO, SG_ALERT, "Cannot get attribute data type for setting attribute \""
-               << getAttributeName(index) << "\" at index " << index << "!");
+    HLAObjectClass* objectClass = getObjectClass().get();
+    if (!objectClass) {
+        SG_LOG(SG_IO, SG_ALERT, "Could not discover instance of unknown object class!");
         return;
     }
-
-    SG_LOG(SG_IO, SG_DEBUG, "Setting DataElement for attribute \""
-           << getAttributeName(index) << "\".");
-
-    DataElementFactoryVisitor visitor(pathElementMap);
-    dataType->accept(visitor);
-    setAttributeDataElement(index, visitor.getDataElement());
+    objectClass->discoverInstance(*this, tag);
 }
 
 void
-HLAObjectInstance::setAttributes(const HLAAttributePathElementMap& attributePathElementMap)
+HLAObjectInstance::removeInstance(const RTIData& tag)
 {
-    for (HLAAttributePathElementMap::const_iterator i = attributePathElementMap.begin();
-         i != attributePathElementMap.end(); ++i) {
-        setAttribute(i->first, i->second);
+    HLAObjectClass* objectClass = getObjectClass().get();
+    if (!objectClass) {
+        SG_LOG(SG_IO, SG_ALERT, "Could not remove instance of unknown object class!");
+        return;
     }
+    objectClass->removeInstance(*this, tag);
 }
 
 void
 HLAObjectInstance::registerInstance()
+{
+    registerInstance(_objectClass.get());
+}
+
+void
+HLAObjectInstance::registerInstance(HLAObjectClass* objectClass)
 {
     if (_rtiObjectInstance.valid()) {
         SG_LOG(SG_IO, SG_ALERT, "Trying to register object " << getName() << " already known to the RTI!");
         return;
     }
-    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())
         return;
@@ -462,11 +316,43 @@ HLAObjectInstance::deleteInstance(const RTIData& tag)
     _rtiObjectInstance->deleteObjectInstance(tag);
 }
 
+void
+HLAObjectInstance::createAttributeDataElements()
+{
+    HLAObjectClass* objectClass = getObjectClass().get();
+    if (!objectClass) {
+        SG_LOG(SG_IO, SG_ALERT, "Could not create data elements for instance of unknown object class!");
+        return;
+    }
+    objectClass->createAttributeDataElements(*this);
+}
+
+void
+HLAObjectInstance::createAndSetAttributeDataElement(unsigned index)
+{
+    if (getAttributeDataElement(index)) {
+        SG_LOG(SG_IO, SG_DEBUG, "Attribute data element for attribute \""
+               << getAttributeName(index) << "\" is already set.");
+        return;
+    }
+    SGSharedPtr<HLADataElement> dataElement = createAttributeDataElement(index);
+    setAttributeDataElement(index, dataElement);
+}
+
+HLADataElement*
+HLAObjectInstance::createAttributeDataElement(unsigned index)
+{
+    HLAObjectClass* objectClass = getObjectClass().get();
+    if (!objectClass) {
+        SG_LOG(SG_IO, SG_ALERT, "Could not create data element for instance of unknown object class!");
+        return 0;
+    }
+    return objectClass->createAttributeDataElement(*this, index);
+}
+
 void
 HLAObjectInstance::updateAttributeValues(const RTIData& tag)
 {
-    if (_attributeCallback.valid())
-        _attributeCallback->updateAttributeValues(*this, tag);
     if (_updateCallback.valid()) {
         _updateCallback->updateAttributeValues(*this, tag);
     } else {
@@ -478,8 +364,6 @@ HLAObjectInstance::updateAttributeValues(const RTIData& 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 {
@@ -576,6 +460,9 @@ HLAObjectInstance::reflectAttributeValue(unsigned index, const SGTimeStamp& time
 void
 HLAObjectInstance::_setRTIObjectInstance(RTIObjectInstance* rtiObjectInstance)
 {
+    if (!_objectClass.valid())
+        return;
+
     _rtiObjectInstance = rtiObjectInstance;
     _rtiObjectInstance->setObjectInstance(this);
     _name = _rtiObjectInstance->getName();
@@ -583,7 +470,7 @@ HLAObjectInstance::_setRTIObjectInstance(RTIObjectInstance* rtiObjectInstance)
     unsigned numAttributes = getNumAttributes();
     _attributeVector.resize(numAttributes);
     for (unsigned i = 0; i < numAttributes; ++i) {
-        HLAUpdateType updateType = getObjectClass()->getAttributeUpdateType(i);
+        HLAUpdateType updateType = _objectClass->getAttributeUpdateType(i);
         if (getAttributeOwned(i) && updateType != HLAUndefinedUpdate) {
             _attributeVector[i]._enabledUpdate = true;
             _attributeVector[i]._unconditionalUpdate = (updateType == HLAPeriodicUpdate);
@@ -598,7 +485,7 @@ HLAObjectInstance::_setRTIObjectInstance(RTIObjectInstance* rtiObjectInstance)
     // 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);
+        HLAUpdateType updateType = _objectClass->getAttributeUpdateType(i);
         if (getAttributeOwned(i))
             continue;
         if (updateType == HLAUndefinedUpdate)
@@ -638,16 +525,6 @@ HLAObjectInstance::_reflectAttributeValues(const HLAIndexList& indexList, const
 {
     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);
     }
@@ -658,16 +535,6 @@ HLAObjectInstance::_reflectAttributeValues(const HLAIndexList& indexList, const
 {
     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);
     }