]> git.mxchange.org Git - simgear.git/blob - simgear/hla/RTI13ObjectInstance.cxx
Add an initial implementation of a rti/hla dispatcher.
[simgear.git] / simgear / hla / RTI13ObjectInstance.cxx
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 #include "RTIObjectInstance.hxx"
19 #include "RTI13Ambassador.hxx"
20
21 namespace simgear {
22
23 RTI13ObjectInstance::RTI13ObjectInstance(const RTI::ObjectHandle& handle, HLAObjectInstance* hlaObjectInstance,
24                                          const RTI13ObjectClass* objectClass, RTI13Ambassador* ambassador, bool owned) :
25     RTIObjectInstance(hlaObjectInstance),
26     _handle(handle),
27     _objectClass(objectClass),
28     _ambassador(ambassador),
29     _attributeValuePairSet(RTI::AttributeSetFactory::create(objectClass->getNumAttributes()))
30 {
31     updateAttributesFromClass(owned);
32 }
33
34 RTI13ObjectInstance::~RTI13ObjectInstance()
35 {
36 }
37
38 const RTIObjectClass*
39 RTI13ObjectInstance::getObjectClass() const
40 {
41     return _objectClass.get();
42 }
43
44 const RTI13ObjectClass*
45 RTI13ObjectInstance::get13ObjectClass() const
46 {
47     return _objectClass.get();
48 }
49
50 std::string
51 RTI13ObjectInstance::getName() const
52 {
53     SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
54     if (!ambassador.valid()) {
55         SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
56         return std::string();
57     }
58
59     try {
60         return ambassador->getObjectInstanceName(_handle);
61     } catch (RTI::ObjectNotKnown& e) {
62         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object name: " << e._name << " " << e._reason);
63         return std::string();
64     } catch (RTI::FederateNotExecutionMember& e) {
65         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object name: " << e._name << " " << e._reason);
66         return std::string();
67     } catch (RTI::ConcurrentAccessAttempted& e) {
68         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object name: " << e._name << " " << e._reason);
69         return std::string();
70     } catch (RTI::RTIinternalError& e) {
71         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object name: " << e._name << " " << e._reason);
72         return std::string();
73     } catch (...) {
74         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not get object name.");
75         return std::string();
76     }
77 }
78
79 void
80 RTI13ObjectInstance::addToRequestQueue()
81 {
82     SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
83     if (!ambassador.valid()) {
84         SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
85         return;
86     }
87
88     ambassador->addObjectInstanceForCallback(this);
89 }
90
91 void
92 RTI13ObjectInstance::deleteObjectInstance(const RTIData& tag)
93 {
94     SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
95     if (!ambassador.valid()) {
96         SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
97         return;
98     }
99
100     try {
101         ambassador->deleteObjectInstance(_handle, tag);
102     } catch (RTI::ObjectNotKnown& e) {
103         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
104     } catch (RTI::DeletePrivilegeNotHeld& e) {
105         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
106     } catch (RTI::FederateNotExecutionMember& e) {
107         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
108     } catch (RTI::ConcurrentAccessAttempted& e) {
109         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
110     } catch (RTI::SaveInProgress& e) {
111         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
112     } catch (RTI::RestoreInProgress& e) {
113         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
114     } catch (RTI::RTIinternalError& e) {
115         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
116     }
117 }
118
119 void
120 RTI13ObjectInstance::deleteObjectInstance(const SGTimeStamp& timeStamp, const RTIData& tag)
121 {
122     SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
123     if (!ambassador.valid()) {
124         SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
125         return;
126     }
127
128     try {
129         ambassador->deleteObjectInstance(_handle, timeStamp, tag);
130     } catch (RTI::ObjectNotKnown& e) {
131         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
132     } catch (RTI::DeletePrivilegeNotHeld& e) {
133         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
134     } catch (RTI::InvalidFederationTime& e) {
135         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
136     } catch (RTI::FederateNotExecutionMember& e) {
137         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
138     } catch (RTI::ConcurrentAccessAttempted& e) {
139         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
140     } catch (RTI::SaveInProgress& e) {
141         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
142     } catch (RTI::RestoreInProgress& e) {
143         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
144     } catch (RTI::RTIinternalError& e) {
145         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
146     }
147 }
148
149 void
150 RTI13ObjectInstance::localDeleteObjectInstance()
151 {
152     SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
153     if (!ambassador.valid()) {
154         SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
155         return;
156     }
157
158     try {
159         ambassador->localDeleteObjectInstance(_handle);
160     } catch (RTI::ObjectNotKnown& e) {
161         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
162     } catch (RTI::FederateOwnsAttributes& e) {
163         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
164     } catch (RTI::FederateNotExecutionMember& e) {
165         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
166     } catch (RTI::ConcurrentAccessAttempted& e) {
167         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
168     } catch (RTI::SaveInProgress& e) {
169         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
170     } catch (RTI::RestoreInProgress& e) {
171         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
172     } catch (RTI::RTIinternalError& e) {
173         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
174     }
175 }
176
177 void
178 RTI13ObjectInstance::reflectAttributeValues(const RTI::AttributeHandleValuePairSet& attributeValuePairSet, const RTIData& tag)
179 {
180     // Retrieve an empty update struct from the memory pool
181     UpdateList updateList;
182     getUpdateFromPool(updateList);
183
184     RTI::ULong numAttribs = attributeValuePairSet.size();
185     for (RTI::ULong i = 0; i < numAttribs; ++i) {
186         unsigned index = getAttributeIndex(attributeValuePairSet.getHandle(i));
187         // Get a RTIData from the data pool
188         getDataFromPool(index, updateList.back()._indexDataPairList);
189         RTI::ULong length = attributeValuePairSet.getValueLength(i);
190         updateList.back()._indexDataPairList.back().second.resize(length);
191         attributeValuePairSet.getValue(i, updateList.back()._indexDataPairList.back().second.data(), length);
192         updateList.back()._tag = tag;
193     }
194
195     RTIObjectInstance::reflectAttributeValues(updateList.front()._indexDataPairList, tag);
196     // Return the update data back to the pool
197     putUpdateToPool(updateList);
198 }
199
200 void
201 RTI13ObjectInstance::reflectAttributeValues(const RTI::AttributeHandleValuePairSet& attributeValuePairSet, const SGTimeStamp& timeStamp, const RTIData& tag)
202 {
203     // Retrieve an empty update struct from the memory pool
204     UpdateList updateList;
205     getUpdateFromPool(updateList);
206
207     RTI::ULong numAttribs = attributeValuePairSet.size();
208     for (RTI::ULong i = 0; i < numAttribs; ++i) {
209         unsigned index = getAttributeIndex(attributeValuePairSet.getHandle(i));
210         // Get a RTIData from the data pool
211         getDataFromPool(index, updateList.back()._indexDataPairList);
212         RTI::ULong length = attributeValuePairSet.getValueLength(i);
213         updateList.back()._indexDataPairList.back().second.resize(length);
214         attributeValuePairSet.getValue(i, updateList.back()._indexDataPairList.back().second.data(), length);
215         updateList.back()._tag = tag;
216     }
217
218     scheduleUpdates(timeStamp, updateList);
219 }
220
221 void
222 RTI13ObjectInstance::requestObjectAttributeValueUpdate()
223 {
224     SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
225     if (!ambassador.valid()) {
226         SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
227         return;
228     }
229
230     try {
231         unsigned numAttributes = getNumAttributes();
232         std::auto_ptr<RTI::AttributeHandleSet> attributeHandleSet(RTI::AttributeHandleSetFactory::create(numAttributes));
233         for (unsigned i = 0; i < numAttributes; ++i) {
234             if (!getRequestAttributeUpdate(i))
235                 continue;
236             attributeHandleSet->add(getAttributeHandle(i));
237         }
238         if (!attributeHandleSet->size())
239             return;
240
241         ambassador->requestObjectAttributeValueUpdate(_handle, *attributeHandleSet);
242
243         for (unsigned i = 0; i < numAttributes; ++i)
244             setRequestAttributeUpdate(i, false);
245
246         return;
247     } catch (RTI::ObjectNotKnown& e) {
248         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not request attribute update for object instance: " << e._name << " " << e._reason);
249         return;
250     } catch (RTI::AttributeNotDefined& e) {
251         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not request attribute update for object instance: " << e._name << " " << e._reason);
252         return;
253     } catch (RTI::FederateNotExecutionMember& e) {
254         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not request attribute update for object instance: " << e._name << " " << e._reason);
255         return;
256     } catch (RTI::ConcurrentAccessAttempted& e) {
257         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not request attribute update for object instance: " << e._name << " " << e._reason);
258         return;
259     } catch (RTI::SaveInProgress& e) {
260         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not request attribute update for object instance: " << e._name << " " << e._reason);
261         return;
262     } catch (RTI::RestoreInProgress& e) {
263         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not request attribute update for object instance: " << e._name << " " << e._reason);
264         return;
265     } catch (RTI::RTIinternalError& e) {
266         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not request attribute update for object instance: " << e._name << " " << e._reason);
267         return;
268     } catch (...) {
269         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not request attribute update for object instance.");
270         return;
271     }
272 }
273
274 void
275 RTI13ObjectInstance::provideAttributeValueUpdate(const RTI::AttributeHandleSet& attributes)
276 {
277     // Called from the ambassador. Just marks some instance attributes dirty so that they are sent with the next update
278     RTI::ULong numAttribs = attributes.size();
279     for (RTI::ULong i = 0; i < numAttribs; ++i) {
280         unsigned index = getAttributeIndex(attributes.getHandle(i));
281         setAttributeForceUpdate(index);
282     }
283 }
284
285 void
286 RTI13ObjectInstance::updateAttributeValues(const RTIData& tag)
287 {
288     SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
289     if (!ambassador.valid()) {
290         SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
291         return;
292     }
293
294     try {
295         // That means clear()
296         _attributeValuePairSet->empty();
297
298         unsigned numAttributes = getNumAttributes();
299         for (unsigned i = 0; i < numAttributes; ++i) {
300             if (!getAttributeEffectiveUpdateEnabled(i))
301                 continue;
302             const HLADataElement* dataElement = getDataElement(i);
303             if (!dataElement)
304                 continue;
305             // FIXME cache somewhere
306             RTIData data;
307             HLAEncodeStream stream(data);
308             dataElement->encode(stream);
309             _attributeValuePairSet->add(getAttributeHandle(i), data.data(), data.size());
310         }
311
312         if (!_attributeValuePairSet->size())
313             return;
314
315         ambassador->updateAttributeValues(_handle, *_attributeValuePairSet, tag);
316
317         for (unsigned i = 0; i < numAttributes; ++i) {
318             setAttributeUpdated(i);
319         }
320
321     } catch (RTI::ObjectNotKnown& e) {
322         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
323     } catch (RTI::AttributeNotDefined& e) {
324         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
325     } catch (RTI::AttributeNotOwned& e) {
326         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
327     } catch (RTI::FederateNotExecutionMember& e) {
328         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
329     } catch (RTI::ConcurrentAccessAttempted& e) {
330         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
331     } catch (RTI::SaveInProgress& e) {
332         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
333     } catch (RTI::RestoreInProgress& e) {
334         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
335     } catch (RTI::RTIinternalError& e) {
336         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
337     }
338
339     // That means clear()
340     _attributeValuePairSet->empty();
341 }
342
343 void
344 RTI13ObjectInstance::updateAttributeValues(const SGTimeStamp& timeStamp, const RTIData& tag)
345 {
346     SGSharedPtr<RTI13Ambassador> ambassador = _ambassador.lock();
347     if (!ambassador.valid()) {
348         SG_LOG(SG_NETWORK, SG_WARN, "Error: Ambassador is zero.");
349         return;
350     }
351
352     try {
353         // That means clear()
354         _attributeValuePairSet->empty();
355
356         unsigned numAttributes = getNumAttributes();
357         for (unsigned i = 0; i < numAttributes; ++i) {
358             if (!getAttributeEffectiveUpdateEnabled(i))
359                 continue;
360             const HLADataElement* dataElement = getDataElement(i);
361             if (!dataElement)
362                 continue;
363             // FIXME cache somewhere
364             RTIData data;
365             HLAEncodeStream stream(data);
366             dataElement->encode(stream);
367             _attributeValuePairSet->add(getAttributeHandle(i), data.data(), data.size());
368         }
369
370         if (!_attributeValuePairSet->size())
371             return;
372
373         ambassador->updateAttributeValues(_handle, *_attributeValuePairSet, timeStamp, tag);
374
375         for (unsigned i = 0; i < numAttributes; ++i) {
376             setAttributeUpdated(i);
377         }
378
379     } catch (RTI::ObjectNotKnown& e) {
380         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
381     } catch (RTI::AttributeNotDefined& e) {
382         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
383     } catch (RTI::AttributeNotOwned& e) {
384         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
385     } catch (RTI::InvalidFederationTime& e) {
386         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
387     } catch (RTI::FederateNotExecutionMember& e) {
388         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
389     } catch (RTI::ConcurrentAccessAttempted& e) {
390         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
391     } catch (RTI::SaveInProgress& e) {
392         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
393     } catch (RTI::RestoreInProgress& e) {
394         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
395     } catch (RTI::RTIinternalError& e) {
396         SG_LOG(SG_NETWORK, SG_WARN, "RTI: Could not delete object instance: " << e._name << " " << e._reason);
397     }
398
399     // That means clear()
400     _attributeValuePairSet->empty();
401 }
402
403 void
404 RTI13ObjectInstance::attributesInScope(const RTI::AttributeHandleSet& attributeHandleSet)
405 {
406     RTI::ULong numAttribs = attributeHandleSet.size();
407     for (RTI::ULong i = 0; i < numAttribs; ++i) {
408         RTI::AttributeHandle attributeHandle = attributeHandleSet.getHandle(i);
409         setAttributeInScope(getAttributeIndex(attributeHandle), true);
410     }
411 }
412
413 void
414 RTI13ObjectInstance::attributesOutOfScope(const RTI::AttributeHandleSet& attributeHandleSet)
415 {
416     RTI::ULong numAttribs = attributeHandleSet.size();
417     for (RTI::ULong i = 0; i < numAttribs; ++i) {
418         RTI::AttributeHandle attributeHandle = attributeHandleSet.getHandle(i);
419         setAttributeInScope(getAttributeIndex(attributeHandle), false);
420     }
421 }
422
423 void
424 RTI13ObjectInstance::turnUpdatesOnForObjectInstance(const RTI::AttributeHandleSet& attributeHandleSet)
425 {
426     RTI::ULong numAttribs = attributeHandleSet.size();
427     for (RTI::ULong i = 0; i < numAttribs; ++i) {
428         RTI::AttributeHandle attributeHandle = attributeHandleSet.getHandle(i);
429         setAttributeUpdateEnabled(getAttributeIndex(attributeHandle), true);
430     }
431 }
432
433 void
434 RTI13ObjectInstance::turnUpdatesOffForObjectInstance(const RTI::AttributeHandleSet& attributeHandleSet)
435 {
436     RTI::ULong numAttribs = attributeHandleSet.size();
437     for (RTI::ULong i = 0; i < numAttribs; ++i) {
438         RTI::AttributeHandle attributeHandle = attributeHandleSet.getHandle(i);
439         setAttributeUpdateEnabled(getAttributeIndex(attributeHandle), false);
440     }
441 }
442
443 void
444 RTI13ObjectInstance::requestAttributeOwnershipAssumption(const RTI::AttributeHandleSet& attributes, const RTIData& tag)
445 {
446 }
447
448 void
449 RTI13ObjectInstance::attributeOwnershipDivestitureNotification(const RTI::AttributeHandleSet& attributes)
450 {
451 }
452
453 void
454 RTI13ObjectInstance::attributeOwnershipAcquisitionNotification(const RTI::AttributeHandleSet& attributes)
455 {
456 }
457
458 void
459 RTI13ObjectInstance::attributeOwnershipUnavailable(const RTI::AttributeHandleSet& attributes)
460 {
461 }
462
463 void
464 RTI13ObjectInstance::requestAttributeOwnershipRelease(const RTI::AttributeHandleSet& attributes, const RTIData& tag)
465 {
466 }
467
468 void
469 RTI13ObjectInstance::confirmAttributeOwnershipAcquisitionCancellation(const RTI::AttributeHandleSet& attributes)
470 {
471 }
472
473 void
474 RTI13ObjectInstance::informAttributeOwnership(RTI::AttributeHandle attributeHandle, RTI::FederateHandle federateHandle)
475 {
476 }
477
478 void
479 RTI13ObjectInstance::attributeIsNotOwned(RTI::AttributeHandle attributeHandle)
480 {
481 }
482
483 void
484 RTI13ObjectInstance::attributeOwnedByRTI(RTI::AttributeHandle attributeHandle)
485 {
486 }
487
488 }