1 // Copyright (C) 2009 - 2010 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 "HLAObjectInstance.hxx"
21 #include "HLAArrayDataElement.hxx"
22 #include "HLABasicDataElement.hxx"
23 #include "HLADataElement.hxx"
24 #include "HLAEnumeratedDataElement.hxx"
25 #include "HLAFixedRecordDataElement.hxx"
26 #include "HLAObjectClass.hxx"
27 #include "HLAVariantDataElement.hxx"
28 #include "RTIObjectClass.hxx"
29 #include "RTIObjectInstance.hxx"
33 HLAObjectInstance::HLAObjectInstance(HLAObjectClass* objectClass) :
34 _objectClass(objectClass)
38 HLAObjectInstance::HLAObjectInstance(HLAObjectClass* objectClass, RTIObjectInstance* rtiObjectInstance) :
39 _objectClass(objectClass),
40 _rtiObjectInstance(rtiObjectInstance)
42 _rtiObjectInstance->_hlaObjectInstance = this;
43 _name = _rtiObjectInstance->getName();
46 HLAObjectInstance::~HLAObjectInstance()
50 SGSharedPtr<HLAObjectClass>
51 HLAObjectInstance::getObjectClass() const
53 return _objectClass.lock();
57 HLAObjectInstance::getNumAttributes() const
59 if (!_rtiObjectInstance.valid()) {
60 SG_LOG(SG_IO, SG_ALERT, "Trying to get number of attributes for inactive object!");
63 return _rtiObjectInstance->getNumAttributes();
67 HLAObjectInstance::getAttributeIndex(const std::string& name) const
69 if (!_rtiObjectInstance.valid()) {
70 SG_LOG(SG_IO, SG_ALERT, "Trying to get attribute index for inactive object!");
73 return _rtiObjectInstance->getAttributeIndex(name);
77 HLAObjectInstance::getAttributeName(unsigned index) const
79 if (!_rtiObjectInstance.valid()) {
80 SG_LOG(SG_IO, SG_ALERT, "Trying to get attribute name for inactive object!");
83 return _rtiObjectInstance->getAttributeName(index);
87 HLAObjectInstance::getAttributeDataType(unsigned index) const
89 if (!_rtiObjectInstance.valid()) {
90 SG_LOG(SG_IO, SG_ALERT, "Trying to get attribute index for inactive object!");
93 return _rtiObjectInstance->getAttributeDataType(index);
97 HLAObjectInstance::setAttributeDataElement(unsigned index, SGSharedPtr<HLADataElement> dataElement)
99 if (!_rtiObjectInstance.valid()) {
100 SG_LOG(SG_IO, SG_ALERT, "Trying to set data element for inactive object!");
103 _rtiObjectInstance->setDataElement(index, dataElement);
107 HLAObjectInstance::getAttributeDataElement(unsigned index)
109 if (!_rtiObjectInstance.valid()) {
110 SG_LOG(SG_IO, SG_ALERT, "Trying to set data element for inactive object!");
113 return _rtiObjectInstance->getDataElement(index);
116 const HLADataElement*
117 HLAObjectInstance::getAttributeDataElement(unsigned index) const
119 if (!_rtiObjectInstance.valid()) {
120 SG_LOG(SG_IO, SG_ALERT, "Trying to set data element for inactive object!");
123 return _rtiObjectInstance->getDataElement(index);
126 class HLAObjectInstance::DataElementFactoryVisitor : public HLADataTypeVisitor {
128 DataElementFactoryVisitor(const HLAPathElementMap& pathElementMap) :
129 _pathElementMap(pathElementMap)
131 DataElementFactoryVisitor(const HLADataElement::Path& path, const HLAPathElementMap& pathElementMap) :
132 _pathElementMap(pathElementMap),
135 virtual ~DataElementFactoryVisitor() {}
137 virtual void apply(const HLADataType& dataType)
139 _dataElement = createDataElement(_path, dataType);
140 if (_dataElement.valid())
143 SG_LOG(SG_NETWORK, SG_ALERT, "HLA: Can not find a suitable data element for data type \""
144 << dataType.getName() << "\"");
147 virtual void apply(const HLAInt8DataType& dataType)
149 _dataElement = createDataElement(_path, dataType);
150 if (_dataElement.valid())
153 _dataElement = new HLASCharDataElement(&dataType);
155 virtual void apply(const HLAUInt8DataType& dataType)
157 _dataElement = createDataElement(_path, dataType);
158 if (_dataElement.valid())
161 _dataElement = new HLAUCharDataElement(&dataType);
163 virtual void apply(const HLAInt16DataType& dataType)
165 _dataElement = createDataElement(_path, dataType);
166 if (_dataElement.valid())
169 _dataElement = new HLAShortDataElement(&dataType);
171 virtual void apply(const HLAUInt16DataType& dataType)
173 _dataElement = createDataElement(_path, dataType);
174 if (_dataElement.valid())
177 _dataElement = new HLAUShortDataElement(&dataType);
179 virtual void apply(const HLAInt32DataType& dataType)
181 _dataElement = createDataElement(_path, dataType);
182 if (_dataElement.valid())
185 _dataElement = new HLAIntDataElement(&dataType);
187 virtual void apply(const HLAUInt32DataType& dataType)
189 _dataElement = createDataElement(_path, dataType);
190 if (_dataElement.valid())
193 _dataElement = new HLAUIntDataElement(&dataType);
195 virtual void apply(const HLAInt64DataType& dataType)
197 _dataElement = createDataElement(_path, dataType);
198 if (_dataElement.valid())
201 _dataElement = new HLALongDataElement(&dataType);
203 virtual void apply(const HLAUInt64DataType& dataType)
205 _dataElement = createDataElement(_path, dataType);
206 if (_dataElement.valid())
209 _dataElement = new HLAULongDataElement(&dataType);
211 virtual void apply(const HLAFloat32DataType& dataType)
213 _dataElement = createDataElement(_path, dataType);
214 if (_dataElement.valid())
217 _dataElement = new HLAFloatDataElement(&dataType);
219 virtual void apply(const HLAFloat64DataType& dataType)
221 _dataElement = createDataElement(_path, dataType);
222 if (_dataElement.valid())
225 _dataElement = new HLADoubleDataElement(&dataType);
228 class ArrayDataElementFactory : public HLAArrayDataElement::DataElementFactory {
230 ArrayDataElementFactory(const HLADataElement::Path& path, const HLAPathElementMap& pathElementMap) :
233 for (HLAPathElementMap::const_iterator i = pathElementMap.lower_bound(path);
234 i != pathElementMap.end(); ++i) {
235 if (i->first.begin() != std::search(i->first.begin(), i->first.end(),
236 path.begin(), path.end()))
238 _pathElementMap.insert(*i);
241 virtual HLADataElement* createElement(const HLAArrayDataElement& element, unsigned index)
243 const HLADataType* dataType = element.getElementDataType();
246 HLADataElement::Path path = _path;
247 path.push_back(HLADataElement::PathElement(index));
248 DataElementFactoryVisitor visitor(path, _pathElementMap);
249 dataType->accept(visitor);
250 return visitor._dataElement.release();
253 HLADataElement::Path _path;
254 HLAPathElementMap _pathElementMap;
257 virtual void apply(const HLAFixedArrayDataType& dataType)
259 _dataElement = createDataElement(_path, dataType);
260 if (_dataElement.valid())
263 SGSharedPtr<HLAArrayDataElement> arrayDataElement;
264 arrayDataElement = new HLAArrayDataElement(&dataType);
265 arrayDataElement->setDataElementFactory(new ArrayDataElementFactory(_path, _pathElementMap));
266 arrayDataElement->setNumElements(dataType.getNumElements());
268 _dataElement = arrayDataElement;
271 virtual void apply(const HLAVariableArrayDataType& dataType)
273 _dataElement = createDataElement(_path, dataType);
274 if (_dataElement.valid())
277 SGSharedPtr<HLAArrayDataElement> arrayDataElement;
278 arrayDataElement = new HLAArrayDataElement(&dataType);
279 arrayDataElement->setDataElementFactory(new ArrayDataElementFactory(_path, _pathElementMap));
281 _dataElement = arrayDataElement;
284 virtual void apply(const HLAEnumeratedDataType& dataType)
286 _dataElement = createDataElement(_path, dataType);
287 if (_dataElement.valid())
290 _dataElement = new HLAEnumeratedDataElement(&dataType);
293 virtual void apply(const HLAFixedRecordDataType& dataType)
295 _dataElement = createDataElement(_path, dataType);
296 if (_dataElement.valid())
299 SGSharedPtr<HLAFixedRecordDataElement> recordDataElement;
300 recordDataElement = new HLAFixedRecordDataElement(&dataType);
302 unsigned numFields = dataType.getNumFields();
303 for (unsigned i = 0; i < numFields; ++i) {
305 _path.push_back(HLADataElement::PathElement(dataType.getFieldName(i)));
307 dataType.getFieldDataType(i)->accept(*this);
308 recordDataElement->setField(i, _dataElement.release());
312 _dataElement = recordDataElement;
315 class VariantDataElementFactory : public HLAVariantDataElement::DataElementFactory {
317 VariantDataElementFactory(const HLADataElement::Path& path, const HLAPathElementMap& pathElementMap) :
320 for (HLAPathElementMap::const_iterator i = pathElementMap.lower_bound(path);
321 i != pathElementMap.end(); ++i) {
322 if (i->first.begin() != std::search(i->first.begin(), i->first.end(),
323 path.begin(), path.end()))
325 _pathElementMap.insert(*i);
328 virtual HLADataElement* createElement(const HLAVariantDataElement& element, unsigned index)
330 const HLAVariantDataType* dataType = element.getDataType();
333 const HLADataType* alternativeDataType = element.getAlternativeDataType();
334 if (!alternativeDataType)
336 HLADataElement::Path path = _path;
337 path.push_back(HLADataElement::PathElement(dataType->getAlternativeName(index)));
338 DataElementFactoryVisitor visitor(path, _pathElementMap);
339 alternativeDataType->accept(visitor);
340 return visitor._dataElement.release();
343 HLADataElement::Path _path;
344 HLAPathElementMap _pathElementMap;
347 virtual void apply(const HLAVariantDataType& dataType)
349 _dataElement = createDataElement(_path, dataType);
350 if (_dataElement.valid())
353 SGSharedPtr<HLAVariantDataElement> variantDataElement;
354 variantDataElement = new HLAVariantDataElement(&dataType);
355 variantDataElement->setDataElementFactory(new VariantDataElementFactory(_path, _pathElementMap));
357 _dataElement = variantDataElement;
360 const SGSharedPtr<HLADataElement>& getDataElement() const
361 { return _dataElement; }
364 SGSharedPtr<HLADataElement> createDataElement(const HLADataElement::Path& path, const HLADataType& dataType)
366 HLAPathElementMap::const_iterator i = _pathElementMap.find(path);
367 if (i == _pathElementMap.end()) {
368 SG_LOG(SG_IO, SG_WARN, "No dataElement provided for \""
369 << HLADataElement::toString(path) << "\".");
373 SGSharedPtr<HLADataElement> dataElement = i->second.getDataElement(path);
374 if (!dataElement->setDataType(&dataType)) {
375 SG_LOG(SG_IO, SG_ALERT, "Cannot set data type for data element at \""
376 << HLADataElement::toString(path) << "\"!");
379 SG_LOG(SG_IO, SG_DEBUG, "Using provided dataElement for \""
380 << HLADataElement::toString(path) << "\".");
384 SGSharedPtr<HLADataElement> _dataElement;
385 const HLAPathElementMap& _pathElementMap;
386 HLADataElement::Path _path;
390 HLAObjectInstance::setAttribute(unsigned index, const HLAPathElementMap& pathElementMap)
392 const HLADataType* dataType = getAttributeDataType(index);
394 SG_LOG(SG_IO, SG_ALERT, "Cannot get attribute data type for setting attribute at index "
399 SG_LOG(SG_IO, SG_DEBUG, "Setting DataElement for attribute \""
400 << getAttributeName(index) << "\".");
402 DataElementFactoryVisitor visitor(pathElementMap);
403 dataType->accept(visitor);
404 setAttributeDataElement(index, visitor.getDataElement());
408 HLAObjectInstance::setAttributes(const HLAAttributePathElementMap& attributePathElementMap)
410 for (HLAAttributePathElementMap::const_iterator i = attributePathElementMap.begin();
411 i != attributePathElementMap.end(); ++i) {
412 setAttribute(i->first, i->second);
417 HLAObjectInstance::requestAttributeUpdate(unsigned index)
419 if (!_rtiObjectInstance.valid()) {
420 SG_LOG(SG_IO, SG_ALERT, "Trying to request attribute update for inactive object!");
423 _rtiObjectInstance->setRequestAttributeUpdate(index, true);
427 HLAObjectInstance::requestAttributeUpdate()
429 if (!_rtiObjectInstance.valid()) {
430 SG_LOG(SG_IO, SG_ALERT, "Trying to request attribute update for inactive object!");
433 _rtiObjectInstance->setRequestAttributeUpdate(true);
437 HLAObjectInstance::registerInstance()
439 if (_rtiObjectInstance.valid()) {
440 SG_LOG(SG_IO, SG_ALERT, "Trying to register object " << getName() << " already known to the RTI!");
443 SGSharedPtr<HLAObjectClass> objectClass = _objectClass.lock();
444 if (!objectClass.valid()) {
445 SG_LOG(SG_IO, SG_ALERT, "Could not register object with unknown object class!");
448 // This error must have been flagged before
449 if (!objectClass->_rtiObjectClass.valid())
451 _rtiObjectInstance = objectClass->_rtiObjectClass->registerObjectInstance(this);
452 if (!_rtiObjectInstance.valid()) {
453 SG_LOG(SG_IO, SG_ALERT, "Could not register object at the RTI!");
456 _name = _rtiObjectInstance->getName();
457 objectClass->registerInstance(*this);
461 HLAObjectInstance::deleteInstance(const RTIData& tag)
463 if (!_rtiObjectInstance.valid()) {
464 SG_LOG(SG_IO, SG_ALERT, "Trying to delete inactive object!");
467 SGSharedPtr<HLAObjectClass> objectClass = _objectClass.lock();
468 if (!objectClass.valid())
470 objectClass->deleteInstance(*this);
471 _rtiObjectInstance->deleteObjectInstance(tag);
475 HLAObjectInstance::localDeleteInstance()
477 if (!_rtiObjectInstance.valid()) {
478 SG_LOG(SG_IO, SG_ALERT, "Trying to delete inactive object!");
481 _rtiObjectInstance->localDeleteObjectInstance();
485 HLAObjectInstance::updateAttributeValues(const RTIData& tag)
487 if (!_rtiObjectInstance.valid()) {
488 SG_LOG(SG_IO, SG_INFO, "Not updating inactive object!");
491 if (_attributeCallback.valid())
492 _attributeCallback->updateAttributeValues(*this, tag);
493 _rtiObjectInstance->updateAttributeValues(tag);
497 HLAObjectInstance::updateAttributeValues(const SGTimeStamp& timeStamp, const RTIData& tag)
499 if (!_rtiObjectInstance.valid()) {
500 SG_LOG(SG_IO, SG_INFO, "Not updating inactive object!");
503 if (_attributeCallback.valid())
504 _attributeCallback->updateAttributeValues(*this, tag);
505 _rtiObjectInstance->updateAttributeValues(timeStamp, tag);
509 HLAObjectInstance::reflectQueuedAttributeValues(const SGTimeStamp& timeStamp)
511 if (!_rtiObjectInstance.valid()) {
512 SG_LOG(SG_IO, SG_INFO, "Not updating inactive object!");
515 _rtiObjectInstance->reflectQueuedAttributeValues(timeStamp);
519 HLAObjectInstance::removeInstance(const RTIData& tag)
521 SGSharedPtr<HLAObjectClass> objectClass = _objectClass.lock();
522 if (!objectClass.valid())
524 objectClass->removeInstanceCallback(*this, tag);
528 HLAObjectInstance::reflectAttributeValues(const RTIIndexDataPairList& dataPairList, const RTIData& tag)
530 if (!_attributeCallback.valid())
532 _attributeCallback->reflectAttributeValues(*this, dataPairList, tag);
536 HLAObjectInstance::reflectAttributeValues(const RTIIndexDataPairList& dataPairList,
537 const SGTimeStamp& timeStamp, const RTIData& tag)
539 if (!_attributeCallback.valid())
541 _attributeCallback->reflectAttributeValues(*this, dataPairList, timeStamp, tag);
544 } // namespace simgear