]> git.mxchange.org Git - simgear.git/blobdiff - simgear/hla/RTIObjectInstance.hxx
Merge branch 'timoore/optimizations' into next
[simgear.git] / simgear / hla / RTIObjectInstance.hxx
index fb8f096a39546324ef7235466149fd9bb6e9deef..00f22a1d1e5c0c06cc615fba7e729af258ade6e8 100644 (file)
 #ifndef RTIObjectInstance_hxx
 #define RTIObjectInstance_hxx
 
-#include <list>
-#include <map>
 #include <string>
 #include <vector>
-#include "simgear/debug/logstream.hxx"
 #include "simgear/structure/SGReferenced.hxx"
-#include "simgear/structure/SGWeakPtr.hxx"
 #include "simgear/timing/timestamp.hxx"
 #include "RTIData.hxx"
 #include "RTIObjectClass.hxx"
@@ -39,314 +35,117 @@ class HLAObjectInstance;
 
 class RTIObjectInstance : public SGReferenced {
 public:
-    RTIObjectInstance(HLAObjectInstance* hlaObjectInstance);
+    RTIObjectInstance(HLAObjectInstance* objectInstance);
     virtual ~RTIObjectInstance();
 
+    void setObjectInstance(HLAObjectInstance* objectInstance)
+    { _objectInstance = objectInstance; }
+
     virtual const RTIObjectClass* getObjectClass() const = 0;
 
     virtual std::string getName() const = 0;
 
     unsigned getNumAttributes() const;
-    unsigned getAttributeIndex(const std::string& name) const;
-    std::string getAttributeName(unsigned index) const;
-
-    // FIXME: factor out an ambassador base
-    virtual void addToRequestQueue() = 0;
 
     virtual void deleteObjectInstance(const RTIData& tag) = 0;
     virtual void deleteObjectInstance(const SGTimeStamp& timeStamp, const RTIData& tag) = 0;
     virtual void localDeleteObjectInstance() = 0;
 
-    virtual void requestObjectAttributeValueUpdate() = 0;
+    virtual void requestObjectAttributeValueUpdate(const HLAIndexList& indexList) = 0;
 
     virtual void updateAttributeValues(const RTIData& tag) = 0;
     virtual void updateAttributeValues(const SGTimeStamp& timeStamp, const RTIData& tag) = 0;
 
+    virtual bool isAttributeOwnedByFederate(unsigned index) const = 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)
-    {
-        if (_attributeData.size() <= i)
-            return;
-        HLADataElement* dataElement = _attributeData[i]._dataElement.get();
-        if (!dataElement)
-            return;
-        HLADecodeStream stream(data);
-        dataElement->decode(stream);
-    }
+    void reflectAttributeValues(const HLAIndexList& indexList, const RTIData& tag);
+    void reflectAttributeValues(const HLAIndexList& indexList, const SGTimeStamp& timeStamp, const RTIData& tag);
 
-    const HLADataType* getAttributeDataType(unsigned i) const
-    {
-        return getObjectClass()->getAttributeDataType(i);
-    }
-    HLAUpdateType getAttributeUpdateType(unsigned i) const
-    {
-        return getObjectClass()->getAttributeUpdateType(i);
-    }
-    bool getAttributeSubscribed(unsigned i) const
+    bool encodeAttributeData(unsigned index, const HLADataElement& dataElement)
     {
-        return getObjectClass()->getAttributeSubscribed(i);
-    }
-    bool getAttributePublished(unsigned i) const
-    {
-        return getObjectClass()->getAttributePublished(i);
+        if (_attributeData.size() <= index)
+            return false;
+        return _attributeData[index].encodeAttributeData(dataElement);
     }
 
-    HLADataElement* getDataElement(unsigned i)
-    {
-        if (_attributeData.size() <= i)
-            return 0;
-        return _attributeData[i]._dataElement.get();
-    }
-    const HLADataElement* getDataElement(unsigned i) const
-    {
-        if (_attributeData.size() <= i)
-            return 0;
-        return _attributeData[i]._dataElement.get();
-    }
-    void setDataElement(unsigned i, HLADataElement* dataElement)
+    bool decodeAttributeData(unsigned index, HLADataElement& dataElement) const
     {
-        if (_attributeData.size() <= i)
-            return;
-        _attributeData[i]._dataElement = dataElement;
+        if (_attributeData.size() <= index)
+            return false;
+        return _attributeData[index].decodeAttributeData(dataElement);
     }
 
-    void updateAttributesFromClass(bool owned)
+    bool getAttributeData(unsigned index, RTIData& data) const
     {
-        // FIXME: rethink that!!!
-        unsigned numAttributes = getNumAttributes();
-        unsigned i = 0;
-        for (; i < _attributeData.size(); ++i) {
-            if (getAttributePublished(i)) {
-            } else {
-                _attributeData[i].setUpdateEnabled(false);
-                _attributeData[i].setOwned(false);
-            }
-        }
-        _attributeData.resize(numAttributes);
-        for (; i < numAttributes; ++i) {
-            if (getAttributePublished(i)) {
-                _attributeData[i].setUpdateEnabled(true);
-                _attributeData[i].setOwned(owned);
-            } else {
-                _attributeData[i].setUpdateEnabled(false);
-                _attributeData[i].setOwned(false);
-            }
-        }
+        if (_attributeData.size() <= index)
+            return false;
+        data = _attributeData[index]._data;
+        return true;
     }
 
-    void setAttributeForceUpdate(unsigned i)
+    bool getAttributeOwned(unsigned index) const
     {
-        if (_attributeData.size() <= i)
-            return;
-        _attributeData[i].setForceUpdate(true);
+        if (_attributeData.size() <= index)
+            return false;
+        return _attributeData[index]._owned;
     }
+
     void setAttributeInScope(unsigned i, bool inScope)
     {
         if (_attributeData.size() <= i)
             return;
-        _attributeData[i].setInScope(inScope);
+        _attributeData[i]._inScope = inScope;
     }
     void setAttributeUpdateEnabled(unsigned i, bool enabled)
     {
         if (_attributeData.size() <= i)
             return;
-        _attributeData[i].setUpdateEnabled(enabled);
-    }
-    void setAttributeUpdated(unsigned i)
-    {
-        if (_attributeData.size() <= i)
-            return;
-        _attributeData[i].setForceUpdate(false);
-    }
-    bool getAttributeEffectiveUpdateEnabled(unsigned i)
-    {
-        if (_attributeData.size() <= i)
-            return false;
-        if (!getAttributePublished(i))
-            return false;
-        if (!_attributeData[i]._updateEnabled)
-            return false;
-        if (!_attributeData[i]._inScope)
-            return false;
-        if (_attributeData[i]._forceUpdate)
-            return true;
-        switch (getAttributeUpdateType(i)) {
-        case HLAPeriodicUpdate:
-            return true;
-        case HLAConditionalUpdate:
-            return true; // FIXME
-        case HLAStaticUpdate:
-            return false;
-        default:
-            return false;
-        }
-    }
-    void setRequestAttributeUpdate(bool request)
-    {
-        for (unsigned i = 0; i < getNumAttributes(); ++i) {
-            if (getAttributeUpdateType(i) == HLAPeriodicUpdate)
-                continue;
-            setRequestAttributeUpdate(i, request);
-        }
-    }
-    void setRequestAttributeUpdate(unsigned i, bool request)
-    {
-        if (_attributeData.size() <= i)
-            return;
-        _attributeData[i].setRequestUpdate(request);
-        if (request) {
-            if (!_pendingAttributeUpdateRequest) {
-                _pendingAttributeUpdateRequest = true;
-                addToRequestQueue();
-            }
-        }
-    }
-    bool getRequestAttributeUpdate(unsigned i) const
-    {
-        if (_attributeData.size() <= i)
-            return false;
-        return _attributeData[i]._requestUpdate;
-    }
-
-    void flushPendingRequests()
-    {
-        if (_pendingAttributeUpdateRequest) {
-            requestObjectAttributeValueUpdate();
-            _pendingAttributeUpdateRequest = false;
-        }
+        _attributeData[i]._updateEnabled = enabled;
     }
 
 protected:
-    // The backward reference to the user visible object
-    SGWeakPtr<HLAObjectInstance> _hlaObjectInstance;
-
-    // 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<Update> UpdateList;
-    // The timestamp sorted list of updates
-    typedef std::map<SGTimeStamp, UpdateList> 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)
+    // Initially set the number of attributes, do an initial query for the attribute ownership
+    void _setNumAttributes(unsigned numAttributes)
     {
-        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);
-    }
-
-    // This adds raw storage for attribute index i to the end of the dataPairList.
-    void getDataFromPool(unsigned i, 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()) {
-            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());
+        _attributeData.resize(numAttributes);
+        for (unsigned i = 0; i < numAttributes; ++i)
+            _attributeData[i]._owned = isAttributeOwnedByFederate(i);
     }
 
-    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());
-            }
-        }
-    }
+    // The backward reference to the user visible object
+    HLAObjectInstance* _objectInstance;
 
     struct AttributeData {
-        AttributeData() : _owned(false), _inScope(true), _updateEnabled(true), _forceUpdate(false), _requestUpdate(false)
+        AttributeData() : _owned(false), _inScope(true), _updateEnabled(true), _dirty(false)
         { }
 
-        // The hla level data element with tha actual local program
-        // accessible data.
-        SGSharedPtr<HLADataElement> _dataElement;
-        // SGSharedPtr<HLADataElement::TimeStamp> _timeStamp;
+        bool encodeAttributeData(const HLADataElement& dataElement)
+        {
+            _dirty = true;
+            _data.resize(0);
+            HLAEncodeStream stream(_data);
+            return dataElement.encode(stream);
+        }
 
-        // Pool of already allocated raw data used for reflection of updates
-        RTIIndexDataPairList _indexDataPairList;
+        bool decodeAttributeData(HLADataElement& dataElement) const
+        {
+            HLADecodeStream stream(_data);
+            return dataElement.decode(stream);
+        }
 
-        void setOwned(bool owned)
-        { _owned = owned; }
-        void setInScope(bool inScope)
-        { _inScope = inScope; }
-        void setUpdateEnabled(bool updateEnabled)
-        { _updateEnabled = updateEnabled; }
-        void setForceUpdate(bool forceUpdate)
-        { _forceUpdate = forceUpdate; }
-        void setRequestUpdate(bool requestUpdate)
-        { _requestUpdate = requestUpdate; }
+        // The rti level raw data element
+        RTIData _data;
 
+        // The state of the attribute as tracked from the rti.
         bool _owned;
         bool _inScope;
         bool _updateEnabled;
-        bool _forceUpdate;
-        bool _requestUpdate;
+
+        // Is set to true if _data has be reencoded
+        bool _dirty;
     };
     std::vector<AttributeData> _attributeData;
-
-    friend class HLAObjectInstance;
 };
 
 }