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 SGSharedPtr<HLAFederate> federate = _federate.lock();
303 if (!federate.valid())
305 return federate->createObjectInstance(this, name);
309 HLAObjectClass::_setRTIObjectClass(RTIObjectClass* objectClass)
311 if (_rtiObjectClass) {
312 SG_LOG(SG_NETWORK, SG_ALERT, "HLAObjectClass: Setting RTIObjectClass twice for object class \"" << getName() << "\"!");
315 _rtiObjectClass = objectClass;
316 if (_rtiObjectClass->_objectClass != this) {
317 SG_LOG(SG_NETWORK, SG_ALERT, "HLAObjectClass: backward reference does not match!");
320 for (unsigned i = 0; i < _attributeVector.size(); ++i)
321 _resolveAttributeIndex(_attributeVector[i]._name, i);
325 HLAObjectClass::_resolveAttributeIndex(const std::string& name, unsigned index)
327 if (!_rtiObjectClass)
329 if (!_rtiObjectClass->resolveAttributeIndex(name, index))
330 SG_LOG(SG_NETWORK, SG_ALERT, "HLAObjectClass: Could not resolve attribute \""
331 << name << "\" for object class \"" << getName() << "\"!");
335 HLAObjectClass::_clearRTIObjectClass()
337 if (!_rtiObjectClass.valid())
339 _rtiObjectClass->_objectClass = 0;
344 HLAObjectClass::_discoverInstance(RTIObjectInstance* rtiObjectInstance, const RTIData& tag)
346 SGSharedPtr<HLAFederate> federate = _federate.lock();
347 if (!federate.valid()) {
348 SG_LOG(SG_NETWORK, SG_ALERT, "RTI: could not find parent federate while discovering object instance");
352 SGSharedPtr<HLAObjectInstance> objectInstance = createObjectInstance(rtiObjectInstance->getName());
353 if (!objectInstance.valid()) {
354 SG_LOG(SG_NETWORK, SG_INFO, "RTI: could not create new object instance for discovered \""
355 << rtiObjectInstance->getName() << "\" object");
358 SG_LOG(SG_NETWORK, SG_INFO, "RTI: create new object instance for discovered \""
359 << rtiObjectInstance->getName() << "\" object");
360 objectInstance->_setRTIObjectInstance(rtiObjectInstance);
361 if (!federate->_insertObjectInstance(objectInstance)) {
362 SG_LOG(SG_NETWORK, SG_ALERT, "RTI: could not insert new object instance for discovered \""
363 << rtiObjectInstance->getName() << "\" object");
366 if (_instanceCallback.valid())
367 _instanceCallback->discoverInstance(*this, *objectInstance, tag);
371 HLAObjectClass::_removeInstance(HLAObjectInstance& objectInstance, const RTIData& tag)
373 SGSharedPtr<HLAFederate> federate = _federate.lock();
374 if (!federate.valid()) {
375 SG_LOG(SG_NETWORK, SG_ALERT, "RTI: could not find parent federate while removing object instance");
378 SG_LOG(SG_NETWORK, SG_INFO, "RTI: remove object instance \"" << objectInstance.getName() << "\"");
379 if (_instanceCallback.valid())
380 _instanceCallback->removeInstance(*this, objectInstance, tag);
381 federate->_eraseObjectInstance(objectInstance.getName());
385 HLAObjectClass::_registerInstance(HLAObjectInstance* objectInstance)
387 SGSharedPtr<HLAFederate> federate = _federate.lock();
388 if (!federate.valid()) {
389 SG_LOG(SG_NETWORK, SG_ALERT, "RTI: could not find parent federate while registering object instance");
394 // We can only register object instances with a valid name at the rti.
395 // So, we cannot do that at HLAObjectInstance creation time.
396 if (!federate->_insertObjectInstance(objectInstance)) {
397 SG_LOG(SG_NETWORK, SG_ALERT, "RTI: could not insert new object instance \""
398 << objectInstance->getName() << "\" object");
401 if (_instanceCallback.valid())
402 _instanceCallback->registerInstance(*this, *objectInstance);
406 HLAObjectClass::_deleteInstance(HLAObjectInstance& objectInstance)
408 SGSharedPtr<HLAFederate> federate = _federate.lock();
409 if (!federate.valid()) {
410 SG_LOG(SG_NETWORK, SG_ALERT, "RTI: could not find parent federate while deleting object instance");
413 if (_instanceCallback.valid())
414 _instanceCallback->deleteInstance(*this, objectInstance);
415 federate->_eraseObjectInstance(objectInstance.getName());
419 HLAObjectClass::_startRegistration()
421 if (_registrationCallback.valid())
422 _registrationCallback->startRegistration(*this);
428 HLAObjectClass::_stopRegistration()
430 if (_registrationCallback.valid())
431 _registrationCallback->stopRegistration(*this);
436 } // namespace simgear