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.
19 # include <simgear_config.h>
22 #include <simgear/compiler.h>
24 #include "HLAObjectClass.hxx"
26 #include "simgear/debug/logstream.hxx"
27 #include "RTIFederate.hxx"
28 #include "RTIObjectClass.hxx"
29 #include "RTIObjectInstance.hxx"
30 #include "HLADataType.hxx"
31 #include "HLAFederate.hxx"
32 #include "HLAObjectInstance.hxx"
36 HLAObjectClass::InstanceCallback::~InstanceCallback()
41 HLAObjectClass::InstanceCallback::discoverInstance(const HLAObjectClass&, HLAObjectInstance& objectInstance, const RTIData& tag)
46 HLAObjectClass::InstanceCallback::removeInstance(const HLAObjectClass&, HLAObjectInstance& objectInstance, const RTIData& tag)
51 HLAObjectClass::InstanceCallback::registerInstance(const HLAObjectClass&, HLAObjectInstance& objectInstance)
56 HLAObjectClass::InstanceCallback::deleteInstance(const HLAObjectClass&, HLAObjectInstance& objectInstance)
60 HLAObjectClass::RegistrationCallback::~RegistrationCallback()
64 HLAObjectClass::HLAObjectClass(const std::string& name, HLAFederate* federate) :
69 SG_LOG(SG_NETWORK, SG_ALERT, "HLAObjectClass::HLAObjectClass(): "
70 "No parent federate given for object class \"" << getName() << "\"!");
73 federate->_insertObjectClass(this);
76 HLAObjectClass::~HLAObjectClass()
78 // HLAObjectClass objects only get deleted when the parent federate
79 // dies. So we do not need to deregister there.
81 _clearRTIObjectClass();
85 HLAObjectClass::getName() const
90 const SGWeakPtr<HLAFederate>&
91 HLAObjectClass::getFederate() const
97 HLAObjectClass::getNumAttributes() const
99 return _attributeVector.size();
103 HLAObjectClass::addAttribute(const std::string& name)
105 unsigned index = _attributeVector.size();
106 _nameIndexMap[name] = index;
107 _attributeVector.push_back(Attribute(name));
108 _resolveAttributeIndex(name, index);
113 HLAObjectClass::getAttributeIndex(const std::string& name) const
115 NameIndexMap::const_iterator i = _nameIndexMap.find(name);
116 if (i == _nameIndexMap.end())
122 HLAObjectClass::getAttributeName(unsigned index) const
124 if (_attributeVector.size() <= index)
125 return std::string();
126 return _attributeVector[index]._name;
130 HLAObjectClass::getAttributeDataType(unsigned index) const
132 if (_attributeVector.size() <= index)
134 return _attributeVector[index]._dataType.get();
138 HLAObjectClass::setAttributeDataType(unsigned index, const HLADataType* dataType)
140 if (_attributeVector.size() <= index)
142 _attributeVector[index]._dataType = dataType;
146 HLAObjectClass::getAttributeUpdateType(unsigned index) const
148 if (_attributeVector.size() <= index)
149 return HLAUndefinedUpdate;
150 return _attributeVector[index]._updateType;
154 HLAObjectClass::setAttributeUpdateType(unsigned index, HLAUpdateType updateType)
156 if (_attributeVector.size() <= index)
158 _attributeVector[index]._updateType = updateType;
162 HLAObjectClass::getAttributeSubscriptionType(unsigned index) const
164 if (_attributeVector.size() <= index)
165 return HLAUnsubscribed;
166 return _attributeVector[index]._subscriptionType;
170 HLAObjectClass::setAttributeSubscriptionType(unsigned index, HLASubscriptionType subscriptionType)
172 if (_attributeVector.size() <= index)
174 _attributeVector[index]._subscriptionType = subscriptionType;
178 HLAObjectClass::getAttributePublicationType(unsigned index) const
180 if (_attributeVector.size() <= index)
181 return HLAUnpublished;
182 return _attributeVector[index]._publicationType;
186 HLAObjectClass::setAttributePublicationType(unsigned index, HLAPublicationType publicationType)
188 if (_attributeVector.size() <= index)
190 _attributeVector[index]._publicationType = publicationType;
193 HLADataElement::IndexPathPair
194 HLAObjectClass::getIndexPathPair(const HLADataElement::StringPathPair& stringPathPair) const
196 unsigned index = getAttributeIndex(stringPathPair.first);
197 if (getNumAttributes() <= index) {
198 SG_LOG(SG_NETWORK, SG_ALERT, "HLAObjectClass::getIndexPathPair(\""
199 << HLADataElement::toString(stringPathPair)
200 << "\"): Could not resolve attribute \"" << stringPathPair.first
201 << "\" for object class \"" << getName() << "\"!");
203 return HLADataElement::IndexPathPair(index, stringPathPair.second);
206 HLADataElement::IndexPathPair
207 HLAObjectClass::getIndexPathPair(const std::string& path) const
209 return getIndexPathPair(HLADataElement::toStringPathPair(path));
213 HLAObjectClass::subscribe()
215 if (!_rtiObjectClass.valid()) {
216 SG_LOG(SG_NETWORK, SG_WARN, "HLAObjectClass::subscribe(): "
217 "No RTIObject class for object class \"" << getName() << "\"!");
221 HLAIndexList indexList;
222 for (unsigned i = 1; i < getNumAttributes(); ++i) {
223 if (_attributeVector[i]._subscriptionType != HLASubscribedActive)
225 indexList.push_back(i);
227 if (!indexList.empty()) {
228 if (!_rtiObjectClass->subscribe(indexList, true))
233 for (unsigned i = 1; i < getNumAttributes(); ++i) {
234 if (_attributeVector[i]._subscriptionType != HLASubscribedPassive)
236 indexList.push_back(i);
238 if (!indexList.empty()) {
239 if (!_rtiObjectClass->subscribe(indexList, false))
246 HLAObjectClass::unsubscribe()
248 if (!_rtiObjectClass.valid()) {
249 SG_LOG(SG_NETWORK, SG_WARN, "HLAObjectClass::unsubscribe(): "
250 "No RTIObject class for object class \"" << getName() << "\"!");
253 return _rtiObjectClass->unsubscribe();
257 HLAObjectClass::publish()
259 if (!_rtiObjectClass.valid()) {
260 SG_LOG(SG_NETWORK, SG_WARN, "HLAObjectClass::publish(): "
261 "No RTIObject class for object class \"" << getName() << "\"!");
265 HLAIndexList indexList;
266 for (unsigned i = 1; i < getNumAttributes(); ++i) {
267 if (_attributeVector[i]._publicationType == HLAUnpublished)
269 indexList.push_back(i);
271 if (indexList.empty())
273 if (!_rtiObjectClass->publish(indexList))
279 HLAObjectClass::unpublish()
281 if (!_rtiObjectClass.valid()) {
282 SG_LOG(SG_NETWORK, SG_WARN, "HLAObjectClass::unpublish(): "
283 "No RTIObject class for object class \"" << getName() << "\"!");
286 return _rtiObjectClass->unpublish();
290 HLAObjectClass::startRegistration() const
295 HLAObjectClass::stopRegistration() const
300 HLAObjectClass::createObjectInstance(const std::string& name)
302 HLAObjectInstance* objectInstance = createObjectInstance();
304 return objectInstance;
305 SGSharedPtr<HLAFederate> federate = _federate.lock();
306 if (!federate.valid())
308 return federate->createObjectInstance(this, name);
312 HLAObjectClass::createObjectInstance()
318 HLAObjectClass::_setRTIObjectClass(RTIObjectClass* objectClass)
320 if (_rtiObjectClass) {
321 SG_LOG(SG_NETWORK, SG_ALERT, "HLAObjectClass: Setting RTIObjectClass twice for object class \"" << getName() << "\"!");
324 _rtiObjectClass = objectClass;
325 if (_rtiObjectClass->_objectClass != this) {
326 SG_LOG(SG_NETWORK, SG_ALERT, "HLAObjectClass: backward reference does not match!");
329 for (unsigned i = 0; i < _attributeVector.size(); ++i)
330 _resolveAttributeIndex(_attributeVector[i]._name, i);
334 HLAObjectClass::_resolveAttributeIndex(const std::string& name, unsigned index)
336 if (!_rtiObjectClass)
338 if (!_rtiObjectClass->resolveAttributeIndex(name, index))
339 SG_LOG(SG_NETWORK, SG_ALERT, "HLAObjectClass: Could not resolve attribute \""
340 << name << "\" for object class \"" << getName() << "\"!");
344 HLAObjectClass::_clearRTIObjectClass()
346 if (!_rtiObjectClass.valid())
348 _rtiObjectClass->_objectClass = 0;
353 HLAObjectClass::_discoverInstance(RTIObjectInstance* rtiObjectInstance, const RTIData& tag)
355 SGSharedPtr<HLAFederate> federate = _federate.lock();
356 if (!federate.valid()) {
357 SG_LOG(SG_NETWORK, SG_ALERT, "RTI: could not find parent federate while discovering object instance");
361 SGSharedPtr<HLAObjectInstance> objectInstance = createObjectInstance(rtiObjectInstance->getName());
362 if (!objectInstance.valid()) {
363 SG_LOG(SG_NETWORK, SG_INFO, "RTI: could not create new object instance for discovered \""
364 << rtiObjectInstance->getName() << "\" object");
367 SG_LOG(SG_NETWORK, SG_INFO, "RTI: create new object instance for discovered \""
368 << rtiObjectInstance->getName() << "\" object");
369 objectInstance->_setRTIObjectInstance(rtiObjectInstance);
370 if (!federate->_insertObjectInstance(objectInstance)) {
371 SG_LOG(SG_NETWORK, SG_ALERT, "RTI: could not insert new object instance for discovered \""
372 << rtiObjectInstance->getName() << "\" object");
375 if (_instanceCallback.valid())
376 _instanceCallback->discoverInstance(*this, *objectInstance, tag);
380 HLAObjectClass::_removeInstance(HLAObjectInstance& objectInstance, const RTIData& tag)
382 SGSharedPtr<HLAFederate> federate = _federate.lock();
383 if (!federate.valid()) {
384 SG_LOG(SG_NETWORK, SG_ALERT, "RTI: could not find parent federate while removing object instance");
387 SG_LOG(SG_NETWORK, SG_INFO, "RTI: remove object instance \"" << objectInstance.getName() << "\"");
388 if (_instanceCallback.valid())
389 _instanceCallback->removeInstance(*this, objectInstance, tag);
390 federate->_eraseObjectInstance(objectInstance.getName());
394 HLAObjectClass::_registerInstance(HLAObjectInstance* objectInstance)
396 SGSharedPtr<HLAFederate> federate = _federate.lock();
397 if (!federate.valid()) {
398 SG_LOG(SG_NETWORK, SG_ALERT, "RTI: could not find parent federate while registering object instance");
403 // We can only register object instances with a valid name at the rti.
404 // So, we cannot do that at HLAObjectInstance creation time.
405 if (!federate->_insertObjectInstance(objectInstance)) {
406 SG_LOG(SG_NETWORK, SG_ALERT, "RTI: could not insert new object instance \""
407 << objectInstance->getName() << "\" object");
410 if (_instanceCallback.valid())
411 _instanceCallback->registerInstance(*this, *objectInstance);
415 HLAObjectClass::_deleteInstance(HLAObjectInstance& objectInstance)
417 SGSharedPtr<HLAFederate> federate = _federate.lock();
418 if (!federate.valid()) {
419 SG_LOG(SG_NETWORK, SG_ALERT, "RTI: could not find parent federate while deleting object instance");
422 if (_instanceCallback.valid())
423 _instanceCallback->deleteInstance(*this, objectInstance);
424 federate->_eraseObjectInstance(objectInstance.getName());
428 HLAObjectClass::_startRegistration()
430 if (_registrationCallback.valid())
431 _registrationCallback->startRegistration(*this);
437 HLAObjectClass::_stopRegistration()
439 if (_registrationCallback.valid())
440 _registrationCallback->stopRegistration(*this);
445 } // namespace simgear