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