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