1 // Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
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.
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.
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.
18 #include "HLAObjectClass.hxx"
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"
30 HLAObjectClass::InstanceCallback::~InstanceCallback()
35 HLAObjectClass::InstanceCallback::discoverInstance(const HLAObjectClass&, HLAObjectInstance& objectInstance, const RTIData& tag)
40 HLAObjectClass::InstanceCallback::removeInstance(const HLAObjectClass&, HLAObjectInstance& objectInstance, const RTIData& tag)
45 HLAObjectClass::InstanceCallback::registerInstance(const HLAObjectClass&, HLAObjectInstance& objectInstance)
50 HLAObjectClass::InstanceCallback::deleteInstance(const HLAObjectClass&, HLAObjectInstance& objectInstance)
54 HLAObjectClass::RegistrationCallback::~RegistrationCallback()
58 HLAObjectClass::HLAObjectClass(const std::string& name, HLAFederate* federate) :
63 SG_LOG(SG_NETWORK, SG_ALERT, "HLAObjectClass::HLAObjectClass(): "
64 "No parent federate given for object class \"" << getName() << "\"!");
67 federate->_insertObjectClass(this);
70 HLAObjectClass::~HLAObjectClass()
72 // HLAObjectClass objects only get deleted when the parent federate
73 // dies. So we do not need to deregister there.
75 _clearRTIObjectClass();
79 HLAObjectClass::getName() const
85 HLAObjectClass::getNumAttributes() const
87 return _attributeVector.size();
91 HLAObjectClass::addAttribute(const std::string& name)
93 unsigned index = _attributeVector.size();
94 _nameIndexMap[name] = index;
95 _attributeVector.push_back(Attribute(name));
96 _resolveAttributeIndex(name, index);
101 HLAObjectClass::getAttributeIndex(const std::string& name) const
103 NameIndexMap::const_iterator i = _nameIndexMap.find(name);
104 if (i == _nameIndexMap.end())
110 HLAObjectClass::getAttributeName(unsigned index) const
112 if (_attributeVector.size() <= index)
113 return std::string();
114 return _attributeVector[index]._name;
118 HLAObjectClass::getAttributeDataType(unsigned index) const
120 if (_attributeVector.size() <= index)
122 return _attributeVector[index]._dataType.get();
126 HLAObjectClass::setAttributeDataType(unsigned index, const HLADataType* dataType)
128 if (_attributeVector.size() <= index)
130 _attributeVector[index]._dataType = dataType;
134 HLAObjectClass::getAttributeUpdateType(unsigned index) const
136 if (_attributeVector.size() <= index)
137 return HLAUndefinedUpdate;
138 return _attributeVector[index]._updateType;
142 HLAObjectClass::setAttributeUpdateType(unsigned index, HLAUpdateType updateType)
144 if (_attributeVector.size() <= index)
146 _attributeVector[index]._updateType = updateType;
150 HLAObjectClass::getAttributeSubscriptionType(unsigned index) const
152 if (_attributeVector.size() <= index)
153 return HLAUnsubscribed;
154 return _attributeVector[index]._subscriptionType;
158 HLAObjectClass::setAttributeSubscriptionType(unsigned index, HLASubscriptionType subscriptionType)
160 if (_attributeVector.size() <= index)
162 _attributeVector[index]._subscriptionType = subscriptionType;
166 HLAObjectClass::getAttributePublicationType(unsigned index) const
168 if (_attributeVector.size() <= index)
169 return HLAUnpublished;
170 return _attributeVector[index]._publicationType;
174 HLAObjectClass::setAttributePublicationType(unsigned index, HLAPublicationType publicationType)
176 if (_attributeVector.size() <= index)
178 _attributeVector[index]._publicationType = publicationType;
181 HLADataElement::IndexPathPair
182 HLAObjectClass::getIndexPathPair(const HLADataElement::StringPathPair& stringPathPair) const
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() << "\"!");
191 return HLADataElement::IndexPathPair(index, stringPathPair.second);
194 HLADataElement::IndexPathPair
195 HLAObjectClass::getIndexPathPair(const std::string& path) const
197 return getIndexPathPair(HLADataElement::toStringPathPair(path));
201 HLAObjectClass::subscribe()
203 if (!_rtiObjectClass.valid()) {
204 SG_LOG(SG_NETWORK, SG_WARN, "HLAObjectClass::subscribe(): "
205 "No RTIObject class for object class \"" << getName() << "\"!");
209 HLAIndexList indexList;
210 for (unsigned i = 1; i < getNumAttributes(); ++i) {
211 if (_attributeVector[i]._subscriptionType != HLASubscribedActive)
213 indexList.push_back(i);
215 if (!indexList.empty()) {
216 if (!_rtiObjectClass->subscribe(indexList, true))
221 for (unsigned i = 1; i < getNumAttributes(); ++i) {
222 if (_attributeVector[i]._subscriptionType != HLASubscribedPassive)
224 indexList.push_back(i);
226 if (!indexList.empty()) {
227 if (!_rtiObjectClass->subscribe(indexList, false))
234 HLAObjectClass::unsubscribe()
236 if (!_rtiObjectClass.valid()) {
237 SG_LOG(SG_NETWORK, SG_WARN, "HLAObjectClass::unsubscribe(): "
238 "No RTIObject class for object class \"" << getName() << "\"!");
241 return _rtiObjectClass->unsubscribe();
245 HLAObjectClass::publish()
247 if (!_rtiObjectClass.valid()) {
248 SG_LOG(SG_NETWORK, SG_WARN, "HLAObjectClass::publish(): "
249 "No RTIObject class for object class \"" << getName() << "\"!");
253 HLAIndexList indexList;
254 for (unsigned i = 1; i < getNumAttributes(); ++i) {
255 if (_attributeVector[i]._publicationType == HLAUnpublished)
257 indexList.push_back(i);
259 if (indexList.empty())
261 if (!_rtiObjectClass->publish(indexList))
267 HLAObjectClass::unpublish()
269 if (!_rtiObjectClass.valid()) {
270 SG_LOG(SG_NETWORK, SG_WARN, "HLAObjectClass::unpublish(): "
271 "No RTIObject class for object class \"" << getName() << "\"!");
274 return _rtiObjectClass->unpublish();
278 HLAObjectClass::startRegistration() const
283 HLAObjectClass::stopRegistration() const
288 HLAObjectClass::createObjectInstance(const std::string& name)
290 HLAObjectInstance* objectInstance = createObjectInstance();
292 return objectInstance;
293 SGSharedPtr<HLAFederate> federate = _federate.lock();
294 if (!federate.valid())
296 return federate->createObjectInstance(this, name);
300 HLAObjectClass::createObjectInstance()
306 HLAObjectClass::_setRTIObjectClass(RTIObjectClass* objectClass)
308 if (_rtiObjectClass) {
309 SG_LOG(SG_NETWORK, SG_ALERT, "HLAObjectClass: Setting RTIObjectClass twice for object class \"" << getName() << "\"!");
312 _rtiObjectClass = objectClass;
313 if (_rtiObjectClass->_objectClass != this) {
314 SG_LOG(SG_NETWORK, SG_ALERT, "HLAObjectClass: backward reference does not match!");
317 for (unsigned i = 0; i < _attributeVector.size(); ++i)
318 _resolveAttributeIndex(_attributeVector[i]._name, i);
322 HLAObjectClass::_resolveAttributeIndex(const std::string& name, unsigned index)
324 if (!_rtiObjectClass)
326 if (!_rtiObjectClass->resolveAttributeIndex(name, index))
327 SG_LOG(SG_NETWORK, SG_ALERT, "HLAObjectClass: Could not resolve attribute \""
328 << name << "\" for object class \"" << getName() << "\"!");
332 HLAObjectClass::_clearRTIObjectClass()
334 if (!_rtiObjectClass.valid())
336 _rtiObjectClass->_objectClass = 0;
341 HLAObjectClass::_discoverInstance(RTIObjectInstance* rtiObjectInstance, const RTIData& tag)
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");
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");
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");
363 if (_instanceCallback.valid())
364 _instanceCallback->discoverInstance(*this, *objectInstance, tag);
368 HLAObjectClass::_removeInstance(HLAObjectInstance& objectInstance, const RTIData& tag)
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");
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());
382 HLAObjectClass::_registerInstance(HLAObjectInstance* objectInstance)
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");
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");
398 if (_instanceCallback.valid())
399 _instanceCallback->registerInstance(*this, *objectInstance);
403 HLAObjectClass::_deleteInstance(HLAObjectInstance& objectInstance)
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");
410 if (_instanceCallback.valid())
411 _instanceCallback->deleteInstance(*this, objectInstance);
412 federate->_eraseObjectInstance(objectInstance.getName());
416 HLAObjectClass::_startRegistration()
418 if (_registrationCallback.valid())
419 _registrationCallback->startRegistration(*this);
425 HLAObjectClass::_stopRegistration()
427 if (_registrationCallback.valid())
428 _registrationCallback->stopRegistration(*this);
433 } // namespace simgear