]> git.mxchange.org Git - simgear.git/blob - simgear/hla/HLAObjectClass.cxx
hla: Provide access to the parent federate.
[simgear.git] / simgear / hla / HLAObjectClass.cxx
1 // Copyright (C) 2009 - 2012  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 "HLAObjectClass.hxx"
19
20 #include "simgear/debug/logstream.hxx"
21 #include "RTIFederate.hxx"
22 #include "RTIObjectClass.hxx"
23 #include "RTIObjectInstance.hxx"
24 #include "HLADataType.hxx"
25 #include "HLAFederate.hxx"
26 #include "HLAObjectInstance.hxx"
27
28 namespace simgear {
29
30 HLAObjectClass::InstanceCallback::~InstanceCallback()
31 {
32 }
33
34 void
35 HLAObjectClass::InstanceCallback::discoverInstance(const HLAObjectClass&, HLAObjectInstance& objectInstance, const RTIData& tag)
36 {
37 }
38
39 void
40 HLAObjectClass::InstanceCallback::removeInstance(const HLAObjectClass&, HLAObjectInstance& objectInstance, const RTIData& tag)
41 {
42 }
43
44 void
45 HLAObjectClass::InstanceCallback::registerInstance(const HLAObjectClass&, HLAObjectInstance& objectInstance)
46 {
47 }
48
49 void
50 HLAObjectClass::InstanceCallback::deleteInstance(const HLAObjectClass&, HLAObjectInstance& objectInstance)
51 {
52 }
53
54 HLAObjectClass::RegistrationCallback::~RegistrationCallback()
55 {
56 }
57
58 HLAObjectClass::HLAObjectClass(const std::string& name, HLAFederate* federate) :
59     _federate(federate),
60     _name(name)
61 {
62     if (!federate) {
63         SG_LOG(SG_NETWORK, SG_ALERT, "HLAObjectClass::HLAObjectClass(): "
64                "No parent federate given for object class \"" << getName() << "\"!");
65         return;
66     }
67     federate->_insertObjectClass(this);
68 }
69
70 HLAObjectClass::~HLAObjectClass()
71 {
72     // HLAObjectClass objects only get deleted when the parent federate
73     // dies. So we do not need to deregister there.
74
75     _clearRTIObjectClass();
76 }
77
78 const std::string&
79 HLAObjectClass::getName() const
80 {
81     return _name;
82 }
83
84 const SGWeakPtr<HLAFederate>&
85 HLAObjectClass::getFederate() const
86 {
87     return _federate;
88 }
89
90 unsigned
91 HLAObjectClass::getNumAttributes() const
92 {
93     return _attributeVector.size();
94 }
95
96 unsigned
97 HLAObjectClass::addAttribute(const std::string& name)
98 {
99     unsigned index = _attributeVector.size();
100     _nameIndexMap[name] = index;
101     _attributeVector.push_back(Attribute(name));
102     _resolveAttributeIndex(name, index);
103     return index;
104 }
105
106 unsigned
107 HLAObjectClass::getAttributeIndex(const std::string& name) const
108 {
109     NameIndexMap::const_iterator i = _nameIndexMap.find(name);
110     if (i == _nameIndexMap.end())
111         return ~0u;
112     return i->second;
113 }
114
115 std::string
116 HLAObjectClass::getAttributeName(unsigned index) const
117 {
118     if (_attributeVector.size() <= index)
119         return std::string();
120     return _attributeVector[index]._name;
121 }
122
123 const HLADataType*
124 HLAObjectClass::getAttributeDataType(unsigned index) const
125 {
126     if (_attributeVector.size() <= index)
127         return 0;
128     return _attributeVector[index]._dataType.get();
129 }
130
131 void
132 HLAObjectClass::setAttributeDataType(unsigned index, const HLADataType* dataType)
133 {
134     if (_attributeVector.size() <= index)
135         return;
136     _attributeVector[index]._dataType = dataType;
137 }
138
139 HLAUpdateType
140 HLAObjectClass::getAttributeUpdateType(unsigned index) const
141 {
142     if (_attributeVector.size() <= index)
143         return HLAUndefinedUpdate;
144     return _attributeVector[index]._updateType;
145 }
146
147 void
148 HLAObjectClass::setAttributeUpdateType(unsigned index, HLAUpdateType updateType)
149 {
150     if (_attributeVector.size() <= index)
151         return;
152     _attributeVector[index]._updateType = updateType;
153 }
154
155 HLASubscriptionType
156 HLAObjectClass::getAttributeSubscriptionType(unsigned index) const
157 {
158     if (_attributeVector.size() <= index)
159         return HLAUnsubscribed;
160     return _attributeVector[index]._subscriptionType;
161 }
162
163 void
164 HLAObjectClass::setAttributeSubscriptionType(unsigned index, HLASubscriptionType subscriptionType)
165 {
166     if (_attributeVector.size() <= index)
167         return;
168     _attributeVector[index]._subscriptionType = subscriptionType;
169 }
170
171 HLAPublicationType
172 HLAObjectClass::getAttributePublicationType(unsigned index) const
173 {
174     if (_attributeVector.size() <= index)
175         return HLAUnpublished;
176     return _attributeVector[index]._publicationType;
177 }
178
179 void
180 HLAObjectClass::setAttributePublicationType(unsigned index, HLAPublicationType publicationType)
181 {
182     if (_attributeVector.size() <= index)
183         return;
184     _attributeVector[index]._publicationType = publicationType;
185 }
186
187 HLADataElement::IndexPathPair
188 HLAObjectClass::getIndexPathPair(const HLADataElement::StringPathPair& stringPathPair) const
189 {
190     unsigned index = getAttributeIndex(stringPathPair.first);
191     if (getNumAttributes() <= index) {
192         SG_LOG(SG_NETWORK, SG_ALERT, "HLAObjectClass::getIndexPathPair(\""
193                << HLADataElement::toString(stringPathPair)
194                << "\"): Could not resolve attribute \"" << stringPathPair.first
195                << "\" for object class \"" << getName() << "\"!");
196     }
197     return HLADataElement::IndexPathPair(index, stringPathPair.second);
198 }
199
200 HLADataElement::IndexPathPair
201 HLAObjectClass::getIndexPathPair(const std::string& path) const
202 {
203     return getIndexPathPair(HLADataElement::toStringPathPair(path));
204 }
205
206 bool
207 HLAObjectClass::subscribe()
208 {
209     if (!_rtiObjectClass.valid()) {
210         SG_LOG(SG_NETWORK, SG_WARN, "HLAObjectClass::subscribe(): "
211                "No RTIObject class for object class \"" << getName() << "\"!");
212         return false;
213     }
214
215     HLAIndexList indexList;
216     for (unsigned i = 1; i < getNumAttributes(); ++i) {
217         if (_attributeVector[i]._subscriptionType != HLASubscribedActive)
218             continue;
219         indexList.push_back(i);
220     }
221     if (!indexList.empty()) {
222         if (!_rtiObjectClass->subscribe(indexList, true))
223             return false;
224     }
225
226     indexList.clear();
227     for (unsigned i = 1; i < getNumAttributes(); ++i) {
228         if (_attributeVector[i]._subscriptionType != HLASubscribedPassive)
229             continue;
230         indexList.push_back(i);
231     }
232     if (!indexList.empty()) {
233         if (!_rtiObjectClass->subscribe(indexList, false))
234             return false;
235     }
236     return true;
237 }
238
239 bool
240 HLAObjectClass::unsubscribe()
241 {
242     if (!_rtiObjectClass.valid()) {
243         SG_LOG(SG_NETWORK, SG_WARN, "HLAObjectClass::unsubscribe(): "
244                "No RTIObject class for object class \"" << getName() << "\"!");
245         return false;
246     }
247     return _rtiObjectClass->unsubscribe();
248 }
249
250 bool
251 HLAObjectClass::publish()
252 {
253     if (!_rtiObjectClass.valid()) {
254         SG_LOG(SG_NETWORK, SG_WARN, "HLAObjectClass::publish(): "
255                "No RTIObject class for object class \"" << getName() << "\"!");
256         return false;
257     }
258
259     HLAIndexList indexList;
260     for (unsigned i = 1; i < getNumAttributes(); ++i) {
261         if (_attributeVector[i]._publicationType == HLAUnpublished)
262             continue;
263         indexList.push_back(i);
264     }
265     if (indexList.empty())
266         return true;
267     if (!_rtiObjectClass->publish(indexList))
268         return false;
269     return true;
270 }
271
272 bool
273 HLAObjectClass::unpublish()
274 {
275     if (!_rtiObjectClass.valid()) {
276         SG_LOG(SG_NETWORK, SG_WARN, "HLAObjectClass::unpublish(): "
277                "No RTIObject class for object class \"" << getName() << "\"!");
278         return false;
279     }
280     return _rtiObjectClass->unpublish();
281 }
282
283 void
284 HLAObjectClass::startRegistration() const
285 {
286 }
287
288 void
289 HLAObjectClass::stopRegistration() const
290 {
291 }
292
293 HLAObjectInstance*
294 HLAObjectClass::createObjectInstance(const std::string& name)
295 {
296     HLAObjectInstance* objectInstance = createObjectInstance();
297     if (objectInstance)
298         return objectInstance;
299     SGSharedPtr<HLAFederate> federate = _federate.lock();
300     if (!federate.valid())
301         return 0;
302     return federate->createObjectInstance(this, name);
303 }
304
305 HLAObjectInstance*
306 HLAObjectClass::createObjectInstance()
307 {
308     return 0;
309 }
310
311 void
312 HLAObjectClass::_setRTIObjectClass(RTIObjectClass* objectClass)
313 {
314     if (_rtiObjectClass) {
315         SG_LOG(SG_NETWORK, SG_ALERT, "HLAObjectClass: Setting RTIObjectClass twice for object class \"" << getName() << "\"!");
316         return;
317     }
318     _rtiObjectClass = objectClass;
319     if (_rtiObjectClass->_objectClass != this) {
320         SG_LOG(SG_NETWORK, SG_ALERT, "HLAObjectClass: backward reference does not match!");
321         return;
322     }
323     for (unsigned i = 0; i < _attributeVector.size(); ++i)
324         _resolveAttributeIndex(_attributeVector[i]._name, i);
325 }
326
327 void
328 HLAObjectClass::_resolveAttributeIndex(const std::string& name, unsigned index)
329 {
330     if (!_rtiObjectClass)
331         return;
332     if (!_rtiObjectClass->resolveAttributeIndex(name, index))
333         SG_LOG(SG_NETWORK, SG_ALERT, "HLAObjectClass: Could not resolve attribute \""
334                << name << "\" for object class \"" << getName() << "\"!");
335 }
336
337 void
338 HLAObjectClass::_clearRTIObjectClass()
339 {
340     if (!_rtiObjectClass.valid())
341         return;
342     _rtiObjectClass->_objectClass = 0;
343     _rtiObjectClass = 0;
344 }
345
346 void
347 HLAObjectClass::_discoverInstance(RTIObjectInstance* rtiObjectInstance, const RTIData& tag)
348 {
349     SGSharedPtr<HLAFederate> federate = _federate.lock();
350     if (!federate.valid()) {
351         SG_LOG(SG_NETWORK, SG_ALERT, "RTI: could not find parent federate while discovering object instance");
352         return;
353     }
354
355     SGSharedPtr<HLAObjectInstance> objectInstance = createObjectInstance(rtiObjectInstance->getName());
356     if (!objectInstance.valid()) {
357         SG_LOG(SG_NETWORK, SG_INFO, "RTI: could not create new object instance for discovered \""
358                << rtiObjectInstance->getName() << "\" object");
359         return;
360     }
361     SG_LOG(SG_NETWORK, SG_INFO, "RTI: create new object instance for discovered \""
362            << rtiObjectInstance->getName() << "\" object");
363     objectInstance->_setRTIObjectInstance(rtiObjectInstance);
364     if (!federate->_insertObjectInstance(objectInstance)) {
365         SG_LOG(SG_NETWORK, SG_ALERT, "RTI: could not insert new object instance for discovered \""
366                << rtiObjectInstance->getName() << "\" object");
367         return;
368     }
369     if (_instanceCallback.valid())
370         _instanceCallback->discoverInstance(*this, *objectInstance, tag);
371 }
372
373 void
374 HLAObjectClass::_removeInstance(HLAObjectInstance& objectInstance, const RTIData& tag)
375 {
376     SGSharedPtr<HLAFederate> federate = _federate.lock();
377     if (!federate.valid()) {
378         SG_LOG(SG_NETWORK, SG_ALERT, "RTI: could not find parent federate while removing object instance");
379         return;
380     }
381     SG_LOG(SG_NETWORK, SG_INFO, "RTI: remove object instance \"" << objectInstance.getName() << "\"");
382     if (_instanceCallback.valid())
383         _instanceCallback->removeInstance(*this, objectInstance, tag);
384     federate->_eraseObjectInstance(objectInstance.getName());
385 }
386
387 void
388 HLAObjectClass::_registerInstance(HLAObjectInstance* objectInstance)
389 {
390     SGSharedPtr<HLAFederate> federate = _federate.lock();
391     if (!federate.valid()) {
392         SG_LOG(SG_NETWORK, SG_ALERT, "RTI: could not find parent federate while registering object instance");
393         return;
394     }
395     if (!objectInstance)
396         return;
397     // We can only register object instances with a valid name at the rti.
398     // So, we cannot do that at HLAObjectInstance creation time.
399     if (!federate->_insertObjectInstance(objectInstance)) {
400         SG_LOG(SG_NETWORK, SG_ALERT, "RTI: could not insert new object instance \""
401                << objectInstance->getName() << "\" object");
402         return;
403     }
404     if (_instanceCallback.valid())
405         _instanceCallback->registerInstance(*this, *objectInstance);
406 }
407
408 void
409 HLAObjectClass::_deleteInstance(HLAObjectInstance& objectInstance)
410 {
411     SGSharedPtr<HLAFederate> federate = _federate.lock();
412     if (!federate.valid()) {
413         SG_LOG(SG_NETWORK, SG_ALERT, "RTI: could not find parent federate while deleting object instance");
414         return;
415     }
416     if (_instanceCallback.valid())
417         _instanceCallback->deleteInstance(*this, objectInstance);
418     federate->_eraseObjectInstance(objectInstance.getName());
419 }
420
421 void
422 HLAObjectClass::_startRegistration()
423 {
424     if (_registrationCallback.valid())
425         _registrationCallback->startRegistration(*this);
426     else
427         startRegistration();
428 }
429
430 void
431 HLAObjectClass::_stopRegistration()
432 {
433     if (_registrationCallback.valid())
434         _registrationCallback->stopRegistration(*this);
435     else
436         stopRegistration();
437 }
438
439 } // namespace simgear