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
84 const SGWeakPtr<HLAFederate>&
85 HLAObjectClass::getFederate() const
91 HLAObjectClass::getNumAttributes() const
93 return _attributeVector.size();
97 HLAObjectClass::addAttribute(const std::string& name)
99 unsigned index = _attributeVector.size();
100 _nameIndexMap[name] = index;
101 _attributeVector.push_back(Attribute(name));
102 _resolveAttributeIndex(name, index);
107 HLAObjectClass::getAttributeIndex(const std::string& name) const
109 NameIndexMap::const_iterator i = _nameIndexMap.find(name);
110 if (i == _nameIndexMap.end())
116 HLAObjectClass::getAttributeName(unsigned index) const
118 if (_attributeVector.size() <= index)
119 return std::string();
120 return _attributeVector[index]._name;
124 HLAObjectClass::getAttributeDataType(unsigned index) const
126 if (_attributeVector.size() <= index)
128 return _attributeVector[index]._dataType.get();
132 HLAObjectClass::setAttributeDataType(unsigned index, const HLADataType* dataType)
134 if (_attributeVector.size() <= index)
136 _attributeVector[index]._dataType = dataType;
140 HLAObjectClass::getAttributeUpdateType(unsigned index) const
142 if (_attributeVector.size() <= index)
143 return HLAUndefinedUpdate;
144 return _attributeVector[index]._updateType;
148 HLAObjectClass::setAttributeUpdateType(unsigned index, HLAUpdateType updateType)
150 if (_attributeVector.size() <= index)
152 _attributeVector[index]._updateType = updateType;
156 HLAObjectClass::getAttributeSubscriptionType(unsigned index) const
158 if (_attributeVector.size() <= index)
159 return HLAUnsubscribed;
160 return _attributeVector[index]._subscriptionType;
164 HLAObjectClass::setAttributeSubscriptionType(unsigned index, HLASubscriptionType subscriptionType)
166 if (_attributeVector.size() <= index)
168 _attributeVector[index]._subscriptionType = subscriptionType;
172 HLAObjectClass::getAttributePublicationType(unsigned index) const
174 if (_attributeVector.size() <= index)
175 return HLAUnpublished;
176 return _attributeVector[index]._publicationType;
180 HLAObjectClass::setAttributePublicationType(unsigned index, HLAPublicationType publicationType)
182 if (_attributeVector.size() <= index)
184 _attributeVector[index]._publicationType = publicationType;
187 HLADataElement::IndexPathPair
188 HLAObjectClass::getIndexPathPair(const HLADataElement::StringPathPair& stringPathPair) const
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() << "\"!");
197 return HLADataElement::IndexPathPair(index, stringPathPair.second);
200 HLADataElement::IndexPathPair
201 HLAObjectClass::getIndexPathPair(const std::string& path) const
203 return getIndexPathPair(HLADataElement::toStringPathPair(path));
207 HLAObjectClass::subscribe()
209 if (!_rtiObjectClass.valid()) {
210 SG_LOG(SG_NETWORK, SG_WARN, "HLAObjectClass::subscribe(): "
211 "No RTIObject class for object class \"" << getName() << "\"!");
215 HLAIndexList indexList;
216 for (unsigned i = 1; i < getNumAttributes(); ++i) {
217 if (_attributeVector[i]._subscriptionType != HLASubscribedActive)
219 indexList.push_back(i);
221 if (!indexList.empty()) {
222 if (!_rtiObjectClass->subscribe(indexList, true))
227 for (unsigned i = 1; i < getNumAttributes(); ++i) {
228 if (_attributeVector[i]._subscriptionType != HLASubscribedPassive)
230 indexList.push_back(i);
232 if (!indexList.empty()) {
233 if (!_rtiObjectClass->subscribe(indexList, false))
240 HLAObjectClass::unsubscribe()
242 if (!_rtiObjectClass.valid()) {
243 SG_LOG(SG_NETWORK, SG_WARN, "HLAObjectClass::unsubscribe(): "
244 "No RTIObject class for object class \"" << getName() << "\"!");
247 return _rtiObjectClass->unsubscribe();
251 HLAObjectClass::publish()
253 if (!_rtiObjectClass.valid()) {
254 SG_LOG(SG_NETWORK, SG_WARN, "HLAObjectClass::publish(): "
255 "No RTIObject class for object class \"" << getName() << "\"!");
259 HLAIndexList indexList;
260 for (unsigned i = 1; i < getNumAttributes(); ++i) {
261 if (_attributeVector[i]._publicationType == HLAUnpublished)
263 indexList.push_back(i);
265 if (indexList.empty())
267 if (!_rtiObjectClass->publish(indexList))
273 HLAObjectClass::unpublish()
275 if (!_rtiObjectClass.valid()) {
276 SG_LOG(SG_NETWORK, SG_WARN, "HLAObjectClass::unpublish(): "
277 "No RTIObject class for object class \"" << getName() << "\"!");
280 return _rtiObjectClass->unpublish();
284 HLAObjectClass::startRegistration() const
289 HLAObjectClass::stopRegistration() const
294 HLAObjectClass::createObjectInstance(const std::string& name)
296 HLAObjectInstance* objectInstance = createObjectInstance();
298 return objectInstance;
299 SGSharedPtr<HLAFederate> federate = _federate.lock();
300 if (!federate.valid())
302 return federate->createObjectInstance(this, name);
306 HLAObjectClass::createObjectInstance()
312 HLAObjectClass::_setRTIObjectClass(RTIObjectClass* objectClass)
314 if (_rtiObjectClass) {
315 SG_LOG(SG_NETWORK, SG_ALERT, "HLAObjectClass: Setting RTIObjectClass twice for object class \"" << getName() << "\"!");
318 _rtiObjectClass = objectClass;
319 if (_rtiObjectClass->_objectClass != this) {
320 SG_LOG(SG_NETWORK, SG_ALERT, "HLAObjectClass: backward reference does not match!");
323 for (unsigned i = 0; i < _attributeVector.size(); ++i)
324 _resolveAttributeIndex(_attributeVector[i]._name, i);
328 HLAObjectClass::_resolveAttributeIndex(const std::string& name, unsigned index)
330 if (!_rtiObjectClass)
332 if (!_rtiObjectClass->resolveAttributeIndex(name, index))
333 SG_LOG(SG_NETWORK, SG_ALERT, "HLAObjectClass: Could not resolve attribute \""
334 << name << "\" for object class \"" << getName() << "\"!");
338 HLAObjectClass::_clearRTIObjectClass()
340 if (!_rtiObjectClass.valid())
342 _rtiObjectClass->_objectClass = 0;
347 HLAObjectClass::_discoverInstance(RTIObjectInstance* rtiObjectInstance, const RTIData& tag)
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");
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");
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");
369 if (_instanceCallback.valid())
370 _instanceCallback->discoverInstance(*this, *objectInstance, tag);
374 HLAObjectClass::_removeInstance(HLAObjectInstance& objectInstance, const RTIData& tag)
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");
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());
388 HLAObjectClass::_registerInstance(HLAObjectInstance* objectInstance)
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");
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");
404 if (_instanceCallback.valid())
405 _instanceCallback->registerInstance(*this, *objectInstance);
409 HLAObjectClass::_deleteInstance(HLAObjectInstance& objectInstance)
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");
416 if (_instanceCallback.valid())
417 _instanceCallback->deleteInstance(*this, objectInstance);
418 federate->_eraseObjectInstance(objectInstance.getName());
422 HLAObjectClass::_startRegistration()
424 if (_registrationCallback.valid())
425 _registrationCallback->startRegistration(*this);
431 HLAObjectClass::_stopRegistration()
433 if (_registrationCallback.valid())
434 _registrationCallback->stopRegistration(*this);
439 } // namespace simgear