1 // Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Library General Public
5 // License as published by the Free Software Foundation; either
6 // version 2 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Library General Public License for more details.
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software
15 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 #ifndef RTIObjectInstance_hxx
19 #define RTIObjectInstance_hxx
25 #include "simgear/debug/logstream.hxx"
26 #include "simgear/structure/SGReferenced.hxx"
27 #include "simgear/structure/SGWeakPtr.hxx"
28 #include "simgear/timing/timestamp.hxx"
29 #include "RTIData.hxx"
30 #include "RTIObjectClass.hxx"
31 #include "HLADataElement.hxx"
38 class HLAObjectInstance;
40 class RTIObjectInstance : public SGReferenced {
42 RTIObjectInstance(HLAObjectInstance* hlaObjectInstance);
43 virtual ~RTIObjectInstance();
45 virtual const RTIObjectClass* getObjectClass() const = 0;
47 virtual std::string getName() const = 0;
49 unsigned getNumAttributes() const;
50 unsigned getAttributeIndex(const std::string& name) const;
51 std::string getAttributeName(unsigned index) const;
53 virtual void deleteObjectInstance(const RTIData& tag) = 0;
54 virtual void deleteObjectInstance(const SGTimeStamp& timeStamp, const RTIData& tag) = 0;
55 virtual void localDeleteObjectInstance() = 0;
57 virtual void requestObjectAttributeValueUpdate() = 0;
59 virtual void updateAttributeValues(const RTIData& tag) = 0;
60 virtual void updateAttributeValues(const SGTimeStamp& timeStamp, const RTIData& tag) = 0;
62 void removeInstance(const RTIData& tag);
63 void reflectAttributeValues(const RTIIndexDataPairList& dataPairList, const RTIData& tag);
64 void reflectAttributeValues(const RTIIndexDataPairList& dataPairList, const SGTimeStamp& timeStamp, const RTIData& tag);
65 void reflectAttributeValue(unsigned i, const RTIData& data)
67 if (_attributeData.size() <= i)
69 HLADataElement* dataElement = _attributeData[i]._dataElement.get();
72 HLADecodeStream stream(data);
73 dataElement->decode(stream);
76 const HLADataType* getAttributeDataType(unsigned i) const
78 return getObjectClass()->getAttributeDataType(i);
80 HLAUpdateType getAttributeUpdateType(unsigned i) const
82 return getObjectClass()->getAttributeUpdateType(i);
84 bool getAttributeSubscribed(unsigned i) const
86 return getObjectClass()->getAttributeSubscribed(i);
88 bool getAttributePublished(unsigned i) const
90 return getObjectClass()->getAttributePublished(i);
93 HLADataElement* getDataElement(unsigned i)
95 if (_attributeData.size() <= i)
97 return _attributeData[i]._dataElement.get();
99 const HLADataElement* getDataElement(unsigned i) const
101 if (_attributeData.size() <= i)
103 return _attributeData[i]._dataElement.get();
105 void setDataElement(unsigned i, HLADataElement* dataElement)
107 if (_attributeData.size() <= i)
109 _attributeData[i]._dataElement = dataElement;
112 void updateAttributesFromClass(bool owned)
114 // FIXME: rethink that!!!
115 unsigned numAttributes = getNumAttributes();
117 for (; i < _attributeData.size(); ++i) {
118 if (getAttributePublished(i)) {
120 _attributeData[i].setUpdateEnabled(false);
121 _attributeData[i].setOwned(false);
122 if (getAttributeSubscribed(i))
123 _attributeData[i].setRequestUpdate(true);
126 _attributeData.resize(numAttributes);
127 for (; i < numAttributes; ++i) {
128 if (getAttributePublished(i)) {
129 _attributeData[i].setUpdateEnabled(true);
130 _attributeData[i].setOwned(owned);
131 if (!owned && getAttributeSubscribed(i))
132 _attributeData[i].setRequestUpdate(true);
134 _attributeData[i].setUpdateEnabled(false);
135 _attributeData[i].setOwned(false);
136 if (getAttributeSubscribed(i))
137 _attributeData[i].setRequestUpdate(true);
142 void setAttributeForceUpdate(unsigned i)
144 if (_attributeData.size() <= i)
146 _attributeData[i].setForceUpdate(true);
148 void setAttributeInScope(unsigned i, bool inScope)
150 if (_attributeData.size() <= i)
152 _attributeData[i].setInScope(inScope);
154 void setAttributeUpdateEnabled(unsigned i, bool enabled)
156 if (_attributeData.size() <= i)
158 _attributeData[i].setUpdateEnabled(enabled);
160 void setAttributeUpdated(unsigned i)
162 if (_attributeData.size() <= i)
164 _attributeData[i].setForceUpdate(false);
166 bool getAttributeEffectiveUpdateEnabled(unsigned i)
168 if (_attributeData.size() <= i)
170 if (!getAttributePublished(i))
172 if (!_attributeData[i]._updateEnabled)
174 if (!_attributeData[i]._inScope)
176 if (_attributeData[i]._forceUpdate)
178 switch (getAttributeUpdateType(i)) {
179 case HLAPeriodicUpdate:
181 case HLAConditionalUpdate:
182 return true; // FIXME
183 case HLAStaticUpdate:
189 void setRequestAttributeUpdate(bool request)
191 for (unsigned i = 0; i < getNumAttributes(); ++i) {
192 if (getAttributeUpdateType(i) == HLAPeriodicUpdate)
194 setRequestAttributeUpdate(i, request);
197 void setRequestAttributeUpdate(unsigned i, bool request)
199 if (_attributeData.size() <= i)
201 _attributeData[i].setRequestUpdate(request);
203 if (!_pendingAttributeUpdateRequest) {
204 _pendingAttributeUpdateRequest = true;
208 bool getRequestAttributeUpdate(unsigned i) const
210 if (_attributeData.size() <= i)
212 return _attributeData[i]._requestUpdate;
215 void flushPendingRequests()
217 if (_pendingAttributeUpdateRequest) {
218 requestObjectAttributeValueUpdate();
219 _pendingAttributeUpdateRequest = false;
224 // The backward reference to the user visible object
225 SGWeakPtr<HLAObjectInstance> _hlaObjectInstance;
227 // Is true if we should emit a requestattr
228 bool _pendingAttributeUpdateRequest;
230 // Pool of update list entries
231 RTIIndexDataPairList _indexDataPairList;
233 // This adds raw storage for attribute index i to the end of the dataPairList.
234 void getDataFromPool(RTIIndexDataPairList& dataPairList)
236 // Nothing left in the pool - so allocate something
237 if (_indexDataPairList.empty()) {
238 dataPairList.push_back(RTIIndexDataPairList::value_type());
242 // Take one from the pool
243 dataPairList.splice(dataPairList.end(), _indexDataPairList, _indexDataPairList.begin());
246 void putDataToPool(RTIIndexDataPairList& dataPairList)
248 _indexDataPairList.splice(_indexDataPairList.begin(), dataPairList);
251 struct AttributeData {
252 AttributeData() : _owned(false), _inScope(true), _updateEnabled(true), _forceUpdate(false), _requestUpdate(false)
255 // The hla level data element with tha actual local program
257 SGSharedPtr<HLADataElement> _dataElement;
258 // SGSharedPtr<HLADataElement::TimeStamp> _timeStamp;
260 // Pool of already allocated raw data used for reflection of updates
261 RTIIndexDataPairList _indexDataPairList;
263 void setOwned(bool owned)
265 void setInScope(bool inScope)
266 { _inScope = inScope; }
267 void setUpdateEnabled(bool updateEnabled)
268 { _updateEnabled = updateEnabled; }
269 void setForceUpdate(bool forceUpdate)
270 { _forceUpdate = forceUpdate; }
271 void setRequestUpdate(bool requestUpdate)
272 { _requestUpdate = requestUpdate; }
280 std::vector<AttributeData> _attributeData;
282 friend class HLAObjectInstance;