]> git.mxchange.org Git - simgear.git/blob - simgear/hla/RTIObjectInstance.hxx
hla: for rti13 queue all callbacks.
[simgear.git] / simgear / hla / RTIObjectInstance.hxx
1 // Copyright (C) 2009 - 2010  Mathias Froehlich - Mathias.Froehlich@web.de
2 //
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.
7 //
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.
12 //
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.
16 //
17
18 #ifndef RTIObjectInstance_hxx
19 #define RTIObjectInstance_hxx
20
21 #include <list>
22 #include <map>
23 #include <string>
24 #include <vector>
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"
32
33 class SGTimeStamp;
34
35 namespace simgear {
36
37 class RTIObjectClass;
38 class HLAObjectInstance;
39
40 class RTIObjectInstance : public SGReferenced {
41 public:
42     RTIObjectInstance(HLAObjectInstance* hlaObjectInstance);
43     virtual ~RTIObjectInstance();
44
45     virtual const RTIObjectClass* getObjectClass() const = 0;
46
47     virtual std::string getName() const = 0;
48
49     unsigned getNumAttributes() const;
50     unsigned getAttributeIndex(const std::string& name) const;
51     std::string getAttributeName(unsigned index) const;
52
53     virtual void deleteObjectInstance(const RTIData& tag) = 0;
54     virtual void deleteObjectInstance(const SGTimeStamp& timeStamp, const RTIData& tag) = 0;
55     virtual void localDeleteObjectInstance() = 0;
56
57     virtual void requestObjectAttributeValueUpdate() = 0;
58
59     virtual void updateAttributeValues(const RTIData& tag) = 0;
60     virtual void updateAttributeValues(const SGTimeStamp& timeStamp, const RTIData& tag) = 0;
61
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)
66     {
67         if (_attributeData.size() <= i)
68             return;
69         HLADataElement* dataElement = _attributeData[i]._dataElement.get();
70         if (!dataElement)
71             return;
72         HLADecodeStream stream(data);
73         dataElement->decode(stream);
74     }
75
76     const HLADataType* getAttributeDataType(unsigned i) const
77     {
78         return getObjectClass()->getAttributeDataType(i);
79     }
80     HLAUpdateType getAttributeUpdateType(unsigned i) const
81     {
82         return getObjectClass()->getAttributeUpdateType(i);
83     }
84     bool getAttributeSubscribed(unsigned i) const
85     {
86         return getObjectClass()->getAttributeSubscribed(i);
87     }
88     bool getAttributePublished(unsigned i) const
89     {
90         return getObjectClass()->getAttributePublished(i);
91     }
92
93     HLADataElement* getDataElement(unsigned i)
94     {
95         if (_attributeData.size() <= i)
96             return 0;
97         return _attributeData[i]._dataElement.get();
98     }
99     const HLADataElement* getDataElement(unsigned i) const
100     {
101         if (_attributeData.size() <= i)
102             return 0;
103         return _attributeData[i]._dataElement.get();
104     }
105     void setDataElement(unsigned i, HLADataElement* dataElement)
106     {
107         if (_attributeData.size() <= i)
108             return;
109         _attributeData[i]._dataElement = dataElement;
110     }
111
112     void updateAttributesFromClass(bool owned)
113     {
114         // FIXME: rethink that!!!
115         unsigned numAttributes = getNumAttributes();
116         unsigned i = 0;
117         for (; i < _attributeData.size(); ++i) {
118             if (getAttributePublished(i)) {
119             } else {
120                 _attributeData[i].setUpdateEnabled(false);
121                 _attributeData[i].setOwned(false);
122                 if (getAttributeSubscribed(i))
123                     _attributeData[i].setRequestUpdate(true);
124             }
125         }
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);
133             } else {
134                 _attributeData[i].setUpdateEnabled(false);
135                 _attributeData[i].setOwned(false);
136                 if (getAttributeSubscribed(i))
137                     _attributeData[i].setRequestUpdate(true);
138             }
139         }
140     }
141
142     void setAttributeForceUpdate(unsigned i)
143     {
144         if (_attributeData.size() <= i)
145             return;
146         _attributeData[i].setForceUpdate(true);
147     }
148     void setAttributeInScope(unsigned i, bool inScope)
149     {
150         if (_attributeData.size() <= i)
151             return;
152         _attributeData[i].setInScope(inScope);
153     }
154     void setAttributeUpdateEnabled(unsigned i, bool enabled)
155     {
156         if (_attributeData.size() <= i)
157             return;
158         _attributeData[i].setUpdateEnabled(enabled);
159     }
160     void setAttributeUpdated(unsigned i)
161     {
162         if (_attributeData.size() <= i)
163             return;
164         _attributeData[i].setForceUpdate(false);
165     }
166     bool getAttributeEffectiveUpdateEnabled(unsigned i)
167     {
168         if (_attributeData.size() <= i)
169             return false;
170         if (!getAttributePublished(i))
171             return false;
172         if (!_attributeData[i]._updateEnabled)
173             return false;
174         if (!_attributeData[i]._inScope)
175             return false;
176         if (_attributeData[i]._forceUpdate)
177             return true;
178         switch (getAttributeUpdateType(i)) {
179         case HLAPeriodicUpdate:
180             return true;
181         case HLAConditionalUpdate:
182             return true; // FIXME
183         case HLAStaticUpdate:
184             return false;
185         default:
186             return false;
187         }
188     }
189     void setRequestAttributeUpdate(bool request)
190     {
191         for (unsigned i = 0; i < getNumAttributes(); ++i) {
192             if (getAttributeUpdateType(i) == HLAPeriodicUpdate)
193                 continue;
194             setRequestAttributeUpdate(i, request);
195         }
196     }
197     void setRequestAttributeUpdate(unsigned i, bool request)
198     {
199         if (_attributeData.size() <= i)
200             return;
201         _attributeData[i].setRequestUpdate(request);
202         if (request) {
203             if (!_pendingAttributeUpdateRequest) {
204                 _pendingAttributeUpdateRequest = true;
205             }
206         }
207     }
208     bool getRequestAttributeUpdate(unsigned i) const
209     {
210         if (_attributeData.size() <= i)
211             return false;
212         return _attributeData[i]._requestUpdate;
213     }
214
215     void flushPendingRequests()
216     {
217         if (_pendingAttributeUpdateRequest) {
218             requestObjectAttributeValueUpdate();
219             _pendingAttributeUpdateRequest = false;
220         }
221     }
222
223 protected:
224     // The backward reference to the user visible object
225     SGWeakPtr<HLAObjectInstance> _hlaObjectInstance;
226
227     // Is true if we should emit a requestattr
228     bool _pendingAttributeUpdateRequest;
229
230     // Pool of update list entries
231     RTIIndexDataPairList _indexDataPairList;
232
233     // This adds raw storage for attribute index i to the end of the dataPairList.
234     void getDataFromPool(RTIIndexDataPairList& dataPairList)
235     {
236         // Nothing left in the pool - so allocate something
237         if (_indexDataPairList.empty()) {
238             dataPairList.push_back(RTIIndexDataPairList::value_type());
239             return;
240         }
241
242         // Take one from the pool
243         dataPairList.splice(dataPairList.end(), _indexDataPairList, _indexDataPairList.begin());
244     }
245
246     void putDataToPool(RTIIndexDataPairList& dataPairList)
247     {
248         _indexDataPairList.splice(_indexDataPairList.begin(), dataPairList);
249     }
250
251     struct AttributeData {
252         AttributeData() : _owned(false), _inScope(true), _updateEnabled(true), _forceUpdate(false), _requestUpdate(false)
253         { }
254
255         // The hla level data element with tha actual local program
256         // accessible data.
257         SGSharedPtr<HLADataElement> _dataElement;
258         // SGSharedPtr<HLADataElement::TimeStamp> _timeStamp;
259
260         // Pool of already allocated raw data used for reflection of updates
261         RTIIndexDataPairList _indexDataPairList;
262
263         void setOwned(bool owned)
264         { _owned = 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; }
273
274         bool _owned;
275         bool _inScope;
276         bool _updateEnabled;
277         bool _forceUpdate;
278         bool _requestUpdate;
279     };
280     std::vector<AttributeData> _attributeData;
281
282     friend class HLAObjectInstance;
283 };
284
285 }
286
287 #endif