-// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de
+// Copyright (C) 2009 - 2012 Mathias Froehlich - Mathias.Froehlich@web.de
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
+#ifdef HAVE_CONFIG_H
+# include <simgear_config.h>
+#endif
+
+#include <simgear/compiler.h>
+
#include "HLAObjectInstance.hxx"
#include <algorithm>
+#include "simgear/debug/logstream.hxx"
#include "HLAArrayDataElement.hxx"
#include "HLABasicDataElement.hxx"
#include "HLADataElement.hxx"
#include "HLAEnumeratedDataElement.hxx"
+#include "HLAFederate.hxx"
#include "HLAFixedRecordDataElement.hxx"
#include "HLAObjectClass.hxx"
-#include "HLAVariantDataElement.hxx"
+#include "HLAVariantRecordDataElement.hxx"
#include "RTIObjectClass.hxx"
#include "RTIObjectInstance.hxx"
namespace simgear {
+HLAObjectInstance::UpdateCallback::~UpdateCallback()
+{
+}
+
+HLAObjectInstance::ReflectCallback::~ReflectCallback()
+{
+}
+
HLAObjectInstance::HLAObjectInstance(HLAObjectClass* objectClass) :
_objectClass(objectClass)
{
+ if (objectClass)
+ _federate = objectClass->_federate;
}
-HLAObjectInstance::HLAObjectInstance(HLAObjectClass* objectClass, RTIObjectInstance* rtiObjectInstance) :
- _objectClass(objectClass),
- _rtiObjectInstance(rtiObjectInstance)
+HLAObjectInstance::~HLAObjectInstance()
{
- _rtiObjectInstance->_hlaObjectInstance = this;
- _name = _rtiObjectInstance->getName();
+ _clearRTIObjectInstance();
}
-HLAObjectInstance::~HLAObjectInstance()
+const std::string&
+HLAObjectInstance::getName() const
+{
+ return _name;
+}
+
+const SGWeakPtr<HLAFederate>&
+HLAObjectInstance::getFederate() const
{
+ return _federate;
}
-SGSharedPtr<HLAObjectClass>
+const SGSharedPtr<HLAObjectClass>&
HLAObjectInstance::getObjectClass() const
{
- return _objectClass.lock();
+ return _objectClass;
}
unsigned
HLAObjectInstance::getNumAttributes() const
{
- if (!_rtiObjectInstance.valid()) {
- SG_LOG(SG_IO, SG_ALERT, "Trying to get number of attributes for inactive object!");
+ if (!_objectClass.valid())
return 0;
- }
- return _rtiObjectInstance->getNumAttributes();
+ return _objectClass->getNumAttributes();
}
unsigned
HLAObjectInstance::getAttributeIndex(const std::string& name) const
{
- if (!_rtiObjectInstance.valid()) {
- SG_LOG(SG_IO, SG_ALERT, "Trying to get attribute index for inactive object!");
- return 0;
- }
- return _rtiObjectInstance->getAttributeIndex(name);
+ if (!_objectClass.valid())
+ return ~0u;
+ return _objectClass->getAttributeIndex(name);
}
std::string
HLAObjectInstance::getAttributeName(unsigned index) const
{
- if (!_rtiObjectInstance.valid()) {
- SG_LOG(SG_IO, SG_ALERT, "Trying to get attribute name for inactive object!");
+ if (!_objectClass.valid())
return std::string();
- }
- return _rtiObjectInstance->getAttributeName(index);
+ return _objectClass->getAttributeName(index);
}
-const HLADataType*
-HLAObjectInstance::getAttributeDataType(unsigned index) const
+bool
+HLAObjectInstance::getAttributeOwned(unsigned index) const
{
- if (!_rtiObjectInstance.valid()) {
- SG_LOG(SG_IO, SG_ALERT, "Trying to get attribute index for inactive object!");
- return 0;
- }
- return _rtiObjectInstance->getAttributeDataType(index);
+ if (!_rtiObjectInstance.valid())
+ return false;
+ return _rtiObjectInstance->getAttributeOwned(index);
}
-void
-HLAObjectInstance::setAttributeDataElement(unsigned index, SGSharedPtr<HLADataElement> dataElement)
+const HLADataType*
+HLAObjectInstance::getAttributeDataType(unsigned index) const
{
- if (!_rtiObjectInstance.valid()) {
- SG_LOG(SG_IO, SG_ALERT, "Trying to set data element for inactive object!");
- return;
- }
- _rtiObjectInstance->setDataElement(index, dataElement);
+ if (!_objectClass.valid())
+ return 0;
+ return _objectClass->getAttributeDataType(index);
}
HLADataElement*
HLAObjectInstance::getAttributeDataElement(unsigned index)
{
- if (!_rtiObjectInstance.valid()) {
- SG_LOG(SG_IO, SG_ALERT, "Trying to set data element for inactive object!");
+ if (_attributeVector.size() <= index)
return 0;
- }
- return _rtiObjectInstance->getDataElement(index);
+ return _attributeVector[index]._dataElement.get();
}
const HLADataElement*
HLAObjectInstance::getAttributeDataElement(unsigned index) const
{
- if (!_rtiObjectInstance.valid()) {
- SG_LOG(SG_IO, SG_ALERT, "Trying to set data element for inactive object!");
+ if (_attributeVector.size() <= index)
return 0;
- }
- return _rtiObjectInstance->getDataElement(index);
-}
-
-class HLAObjectInstance::DataElementFactoryVisitor : public HLADataTypeVisitor {
-public:
- DataElementFactoryVisitor(const HLAPathElementMap& pathElementMap) :
- _pathElementMap(pathElementMap)
- { }
- DataElementFactoryVisitor(const HLADataElement::Path& path, const HLAPathElementMap& pathElementMap) :
- _pathElementMap(pathElementMap),
- _path(path)
- { }
- virtual ~DataElementFactoryVisitor() {}
-
- virtual void apply(const HLADataType& dataType)
- {
- _dataElement = createDataElement(_path, dataType);
- if (_dataElement.valid())
- return;
-
- SG_LOG(SG_NETWORK, SG_ALERT, "HLA: Can not find a suitable data element for data type \""
- << dataType.getName() << "\"");
- }
-
- virtual void apply(const HLAInt8DataType& dataType)
- {
- _dataElement = createDataElement(_path, dataType);
- if (_dataElement.valid())
- return;
-
- _dataElement = new HLASCharDataElement(&dataType);
- }
- virtual void apply(const HLAUInt8DataType& dataType)
- {
- _dataElement = createDataElement(_path, dataType);
- if (_dataElement.valid())
- return;
-
- _dataElement = new HLAUCharDataElement(&dataType);
- }
- virtual void apply(const HLAInt16DataType& dataType)
- {
- _dataElement = createDataElement(_path, dataType);
- if (_dataElement.valid())
- return;
-
- _dataElement = new HLAShortDataElement(&dataType);
- }
- virtual void apply(const HLAUInt16DataType& dataType)
- {
- _dataElement = createDataElement(_path, dataType);
- if (_dataElement.valid())
- return;
-
- _dataElement = new HLAUShortDataElement(&dataType);
- }
- virtual void apply(const HLAInt32DataType& dataType)
- {
- _dataElement = createDataElement(_path, dataType);
- if (_dataElement.valid())
- return;
-
- _dataElement = new HLAIntDataElement(&dataType);
- }
- virtual void apply(const HLAUInt32DataType& dataType)
- {
- _dataElement = createDataElement(_path, dataType);
- if (_dataElement.valid())
- return;
-
- _dataElement = new HLAUIntDataElement(&dataType);
- }
- virtual void apply(const HLAInt64DataType& dataType)
- {
- _dataElement = createDataElement(_path, dataType);
- if (_dataElement.valid())
- return;
-
- _dataElement = new HLALongDataElement(&dataType);
- }
- virtual void apply(const HLAUInt64DataType& dataType)
- {
- _dataElement = createDataElement(_path, dataType);
- if (_dataElement.valid())
- return;
-
- _dataElement = new HLAULongDataElement(&dataType);
- }
- virtual void apply(const HLAFloat32DataType& dataType)
- {
- _dataElement = createDataElement(_path, dataType);
- if (_dataElement.valid())
- return;
-
- _dataElement = new HLAFloatDataElement(&dataType);
- }
- virtual void apply(const HLAFloat64DataType& dataType)
- {
- _dataElement = createDataElement(_path, dataType);
- if (_dataElement.valid())
- return;
+ return _attributeVector[index]._dataElement.get();
+}
- _dataElement = new HLADoubleDataElement(&dataType);
+bool
+HLAObjectInstance::getAttributeData(unsigned index, RTIData& data) const
+{
+ if (!_rtiObjectInstance.valid()) {
+ SG_LOG(SG_IO, SG_ALERT, "Trying to get raw attribute data without rti object instance for \"" << getName() << "\"!");
+ return false;
}
+ return _rtiObjectInstance->getAttributeData(index, data);
+}
- class ArrayDataElementFactory : public HLAArrayDataElement::DataElementFactory {
- public:
- ArrayDataElementFactory(const HLADataElement::Path& path, const HLAPathElementMap& pathElementMap) :
- _path(path)
- {
- for (HLAPathElementMap::const_iterator i = pathElementMap.lower_bound(path);
- i != pathElementMap.end(); ++i) {
- if (i->first.begin() != std::search(i->first.begin(), i->first.end(),
- path.begin(), path.end()))
- break;
- _pathElementMap.insert(*i);
- }
- }
- virtual HLADataElement* createElement(const HLAArrayDataElement& element, unsigned index)
- {
- const HLADataType* dataType = element.getElementDataType();
- if (!dataType)
- return 0;
- HLADataElement::Path path = _path;
- path.push_back(HLADataElement::PathElement(index));
- DataElementFactoryVisitor visitor(path, _pathElementMap);
- dataType->accept(visitor);
- return visitor._dataElement.release();
- }
- private:
- HLADataElement::Path _path;
- HLAPathElementMap _pathElementMap;
- };
-
- virtual void apply(const HLAFixedArrayDataType& dataType)
- {
- _dataElement = createDataElement(_path, dataType);
- if (_dataElement.valid())
- return;
-
- SGSharedPtr<HLAArrayDataElement> arrayDataElement;
- arrayDataElement = new HLAArrayDataElement(&dataType);
- arrayDataElement->setDataElementFactory(new ArrayDataElementFactory(_path, _pathElementMap));
- arrayDataElement->setNumElements(dataType.getNumElements());
+void
+HLAObjectInstance::setAttributeDataElement(unsigned index, const SGSharedPtr<HLADataElement>& dataElement)
+{
+ unsigned numAttributes = getNumAttributes();
+ if (numAttributes <= index)
+ return;
+ _attributeVector.resize(numAttributes);
+ if (_attributeVector[index]._dataElement.valid())
+ _attributeVector[index]._dataElement->clearStamp();
+ _attributeVector[index]._dataElement = dataElement;
+ if (_attributeVector[index]._dataElement.valid())
+ _attributeVector[index]._dataElement->createStamp();
+}
- _dataElement = arrayDataElement;
+bool
+HLAObjectInstance::getDataElementIndex(HLADataElementIndex& index, const std::string& path) const
+{
+ HLAObjectClass* objectClass = getObjectClass().get();
+ if (!objectClass) {
+ SG_LOG(SG_IO, SG_ALERT, "Could not get the data element index of an object instance with unknown class!");
+ return false;
}
+ return objectClass->getDataElementIndex(index, path);
+}
- virtual void apply(const HLAVariableArrayDataType& dataType)
- {
- _dataElement = createDataElement(_path, dataType);
- if (_dataElement.valid())
- return;
+HLADataElementIndex
+HLAObjectInstance::getDataElementIndex(const std::string& path) const
+{
+ HLADataElementIndex dataElementIndex;
+ getDataElementIndex(dataElementIndex, path);
+ return dataElementIndex;
+}
- SGSharedPtr<HLAArrayDataElement> arrayDataElement;
- arrayDataElement = new HLAArrayDataElement(&dataType);
- arrayDataElement->setDataElementFactory(new ArrayDataElementFactory(_path, _pathElementMap));
+HLADataElement*
+HLAObjectInstance::getAttributeDataElement(const HLADataElementIndex& index)
+{
+ if (index.empty())
+ return 0;
+ HLADataElement* dataElement = getAttributeDataElement(index[0]);
+ if (!dataElement)
+ return 0;
+ return dataElement->getDataElement(index.begin() + 1, index.end());
+}
- _dataElement = arrayDataElement;
- }
+const HLADataElement*
+HLAObjectInstance::getAttributeDataElement(const HLADataElementIndex& index) const
+{
+ if (index.empty())
+ return 0;
+ const HLADataElement* dataElement = getAttributeDataElement(index[0]);
+ if (!dataElement)
+ return 0;
+ return dataElement->getDataElement(index.begin() + 1, index.end());
+}
- virtual void apply(const HLAEnumeratedDataType& dataType)
- {
- _dataElement = createDataElement(_path, dataType);
- if (_dataElement.valid())
+void
+HLAObjectInstance::setAttributeDataElement(const HLADataElementIndex& index, const SGSharedPtr<HLADataElement>& dataElement)
+{
+ if (index.empty())
+ return;
+ if (index.size() == 1) {
+ if (!getAttributeDataType(index[0]))
return;
-
- _dataElement = new HLAEnumeratedDataElement(&dataType);
- }
-
- virtual void apply(const HLAFixedRecordDataType& dataType)
- {
- _dataElement = createDataElement(_path, dataType);
- if (_dataElement.valid())
+ if (dataElement.valid() && !dataElement->setDataType(getAttributeDataType(index[0])))
return;
-
- SGSharedPtr<HLAFixedRecordDataElement> recordDataElement;
- recordDataElement = new HLAFixedRecordDataElement(&dataType);
-
- unsigned numFields = dataType.getNumFields();
- for (unsigned i = 0; i < numFields; ++i) {
-
- _path.push_back(HLADataElement::PathElement(dataType.getFieldName(i)));
-
- dataType.getFieldDataType(i)->accept(*this);
- recordDataElement->setField(i, _dataElement.release());
-
- _path.pop_back();
- }
- _dataElement = recordDataElement;
- }
-
- class VariantDataElementFactory : public HLAVariantDataElement::DataElementFactory {
- public:
- VariantDataElementFactory(const HLADataElement::Path& path, const HLAPathElementMap& pathElementMap) :
- _path(path)
- {
- for (HLAPathElementMap::const_iterator i = pathElementMap.lower_bound(path);
- i != pathElementMap.end(); ++i) {
- if (i->first.begin() != std::search(i->first.begin(), i->first.end(),
- path.begin(), path.end()))
- break;
- _pathElementMap.insert(*i);
- }
- }
- virtual HLADataElement* createElement(const HLAVariantDataElement& element, unsigned index)
- {
- const HLAVariantDataType* dataType = element.getDataType();
- if (!dataType)
- return 0;
- const HLADataType* alternativeDataType = element.getAlternativeDataType();
- if (!alternativeDataType)
- return 0;
- HLADataElement::Path path = _path;
- path.push_back(HLADataElement::PathElement(dataType->getAlternativeName(index)));
- DataElementFactoryVisitor visitor(path, _pathElementMap);
- alternativeDataType->accept(visitor);
- return visitor._dataElement.release();
+ setAttributeDataElement(index[0], dataElement);
+ } else {
+ SGSharedPtr<HLADataElement> attributeDataElement = getAttributeDataElement(index[0]);
+ if (!attributeDataElement.valid()) {
+ createAndSetAttributeDataElement(index[0]);
+ attributeDataElement = getAttributeDataElement(index[0]);
}
- private:
- HLADataElement::Path _path;
- HLAPathElementMap _pathElementMap;
- };
-
- virtual void apply(const HLAVariantDataType& dataType)
- {
- _dataElement = createDataElement(_path, dataType);
- if (_dataElement.valid())
+ if (!attributeDataElement.valid())
return;
-
- SGSharedPtr<HLAVariantDataElement> variantDataElement;
- variantDataElement = new HLAVariantDataElement(&dataType);
- variantDataElement->setDataElementFactory(new VariantDataElementFactory(_path, _pathElementMap));
-
- _dataElement = variantDataElement;
+ attributeDataElement->setDataElement(index.begin() + 1, index.end(), dataElement.get());
}
+}
- const SGSharedPtr<HLADataElement>& getDataElement() const
- { return _dataElement; }
-
-private:
- SGSharedPtr<HLADataElement> createDataElement(const HLADataElement::Path& path, const HLADataType& dataType)
- {
- HLAPathElementMap::const_iterator i = _pathElementMap.find(path);
- if (i == _pathElementMap.end()) {
- SG_LOG(SG_IO, SG_WARN, "No dataElement provided for \""
- << HLADataElement::toString(path) << "\".");
-
- return 0;
- }
- SGSharedPtr<HLADataElement> dataElement = i->second.getDataElement(path);
- if (!dataElement->setDataType(&dataType)) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot set data type for data element at \""
- << HLADataElement::toString(path) << "\"!");
- return 0;
- }
- SG_LOG(SG_IO, SG_DEBUG, "Using provided dataElement for \""
- << HLADataElement::toString(path) << "\".");
- return dataElement;
- }
+HLADataElement*
+HLAObjectInstance::getAttributeDataElement(const std::string& path)
+{
+ HLADataElementIndex index;
+ if (!getDataElementIndex(index, path))
+ return 0;
+ return getAttributeDataElement(index);
+}
- SGSharedPtr<HLADataElement> _dataElement;
- const HLAPathElementMap& _pathElementMap;
- HLADataElement::Path _path;
-};
+const HLADataElement*
+HLAObjectInstance::getAttributeDataElement(const std::string& path) const
+{
+ HLADataElementIndex index;
+ if (!getDataElementIndex(index, path))
+ return 0;
+ return getAttributeDataElement(index);
+}
void
-HLAObjectInstance::setAttribute(unsigned index, const HLAPathElementMap& pathElementMap)
+HLAObjectInstance::setAttributeDataElement(const std::string& path, const SGSharedPtr<HLADataElement>& dataElement)
{
- const HLADataType* dataType = getAttributeDataType(index);
- if (!dataType) {
- SG_LOG(SG_IO, SG_ALERT, "Cannot get attribute data type for setting attribute at index "
- << index << "!");
+ HLADataElementIndex index;
+ if (!getDataElementIndex(index, path))
return;
- }
-
- SG_LOG(SG_IO, SG_DEBUG, "Setting DataElement for attribute \""
- << getAttributeName(index) << "\".");
-
- DataElementFactoryVisitor visitor(pathElementMap);
- dataType->accept(visitor);
- setAttributeDataElement(index, visitor.getDataElement());
+ setAttributeDataElement(index, dataElement);
}
void
-HLAObjectInstance::setAttributes(const HLAAttributePathElementMap& attributePathElementMap)
+HLAObjectInstance::discoverInstance(const RTIData& tag)
{
- for (HLAAttributePathElementMap::const_iterator i = attributePathElementMap.begin();
- i != attributePathElementMap.end(); ++i) {
- setAttribute(i->first, i->second);
+ HLAObjectClass* objectClass = getObjectClass().get();
+ if (!objectClass) {
+ SG_LOG(SG_IO, SG_ALERT, "Could not discover instance of unknown object class!");
+ return;
}
+ objectClass->discoverInstance(*this, tag);
}
void
-HLAObjectInstance::requestAttributeUpdate(unsigned index)
+HLAObjectInstance::removeInstance(const RTIData& tag)
{
- if (!_rtiObjectInstance.valid()) {
- SG_LOG(SG_IO, SG_ALERT, "Trying to request attribute update for inactive object!");
+ HLAObjectClass* objectClass = getObjectClass().get();
+ if (!objectClass) {
+ SG_LOG(SG_IO, SG_ALERT, "Could not remove instance of unknown object class!");
return;
}
- _rtiObjectInstance->setRequestAttributeUpdate(index, true);
+ objectClass->removeInstance(*this, tag);
}
void
-HLAObjectInstance::requestAttributeUpdate()
+HLAObjectInstance::registerInstance()
{
- if (!_rtiObjectInstance.valid()) {
- SG_LOG(SG_IO, SG_ALERT, "Trying to request attribute update for inactive object!");
- return;
- }
- _rtiObjectInstance->setRequestAttributeUpdate(true);
+ registerInstance(_objectClass.get());
}
void
-HLAObjectInstance::registerInstance()
+HLAObjectInstance::registerInstance(HLAObjectClass* objectClass)
{
if (_rtiObjectInstance.valid()) {
SG_LOG(SG_IO, SG_ALERT, "Trying to register object " << getName() << " already known to the RTI!");
return;
}
- SGSharedPtr<HLAObjectClass> objectClass = _objectClass.lock();
- if (!objectClass.valid()) {
+ if (!objectClass) {
SG_LOG(SG_IO, SG_ALERT, "Could not register object with unknown object class!");
return;
}
+ if (_objectClass.valid() && objectClass != _objectClass.get()) {
+ SG_LOG(SG_IO, SG_ALERT, "Could not change object class while registering!");
+ return;
+ }
+ _objectClass = objectClass;
+ _federate = _objectClass->_federate;
// This error must have been flagged before
- if (!objectClass->_rtiObjectClass.valid())
+ if (!_objectClass->_rtiObjectClass.valid())
return;
- _rtiObjectInstance = objectClass->_rtiObjectClass->registerObjectInstance(this);
+ _setRTIObjectInstance(_objectClass->_rtiObjectClass->registerObjectInstance(this));
if (!_rtiObjectInstance.valid()) {
SG_LOG(SG_IO, SG_ALERT, "Could not register object at the RTI!");
return;
}
- _name = _rtiObjectInstance->getName();
- objectClass->registerInstance(*this);
+ _objectClass->_registerInstance(this);
}
void
SG_LOG(SG_IO, SG_ALERT, "Trying to delete inactive object!");
return;
}
- SGSharedPtr<HLAObjectClass> objectClass = _objectClass.lock();
- if (!objectClass.valid())
+ if (!_objectClass.valid())
return;
- objectClass->deleteInstance(*this);
+ _objectClass->_deleteInstance(*this);
_rtiObjectInstance->deleteObjectInstance(tag);
}
void
-HLAObjectInstance::localDeleteInstance()
+HLAObjectInstance::createAttributeDataElements()
{
- if (!_rtiObjectInstance.valid()) {
- SG_LOG(SG_IO, SG_ALERT, "Trying to delete inactive object!");
+ HLAObjectClass* objectClass = getObjectClass().get();
+ if (!objectClass) {
+ SG_LOG(SG_IO, SG_ALERT, "Could not create data elements for instance of unknown object class!");
return;
}
- _rtiObjectInstance->localDeleteObjectInstance();
+ objectClass->createAttributeDataElements(*this);
+}
+
+void
+HLAObjectInstance::createAndSetAttributeDataElement(unsigned index)
+{
+ if (getAttributeDataElement(index)) {
+ SG_LOG(SG_IO, SG_DEBUG, "Attribute data element for attribute \""
+ << getAttributeName(index) << "\" is already set.");
+ return;
+ }
+ SGSharedPtr<HLADataElement> dataElement = createAttributeDataElement(index);
+ setAttributeDataElement(index, dataElement);
+}
+
+HLADataElement*
+HLAObjectInstance::createAttributeDataElement(unsigned index)
+{
+ HLAObjectClass* objectClass = getObjectClass().get();
+ if (!objectClass) {
+ SG_LOG(SG_IO, SG_ALERT, "Could not create data element for instance of unknown object class!");
+ return 0;
+ }
+ return objectClass->createAttributeDataElement(*this, index);
}
void
HLAObjectInstance::updateAttributeValues(const RTIData& tag)
+{
+ if (_updateCallback.valid()) {
+ _updateCallback->updateAttributeValues(*this, tag);
+ } else {
+ encodeAttributeValues();
+ sendAttributeValues(tag);
+ }
+}
+
+void
+HLAObjectInstance::updateAttributeValues(const SGTimeStamp& timeStamp, const RTIData& tag)
+{
+ if (_updateCallback.valid()) {
+ _updateCallback->updateAttributeValues(*this, timeStamp, tag);
+ } else {
+ encodeAttributeValues();
+ sendAttributeValues(timeStamp, tag);
+ }
+}
+
+void
+HLAObjectInstance::encodeAttributeValues()
+{
+ unsigned numAttributes = _attributeVector.size();
+ for (unsigned i = 0; i < numAttributes;++i) {
+ if (_attributeVector[i]._unconditionalUpdate) {
+ encodeAttributeValue(i);
+ } else if (_attributeVector[i]._enabledUpdate) {
+ const HLADataElement* dataElement = getAttributeDataElement(i);
+ if (dataElement && dataElement->getDirty())
+ encodeAttributeValue(i);
+ }
+ }
+}
+
+void
+HLAObjectInstance::encodeAttributeValue(unsigned index)
{
if (!_rtiObjectInstance.valid()) {
SG_LOG(SG_IO, SG_INFO, "Not updating inactive object!");
return;
}
- if (_attributeCallback.valid())
- _attributeCallback->updateAttributeValues(*this, tag);
- _rtiObjectInstance->updateAttributeValues(tag);
+ HLADataElement* dataElement = getAttributeDataElement(index);
+ if (!dataElement)
+ return;
+ _rtiObjectInstance->encodeAttributeData(index, *dataElement);
+ dataElement->setDirty(false);
}
void
-HLAObjectInstance::updateAttributeValues(const SGTimeStamp& timeStamp, const RTIData& tag)
+HLAObjectInstance::sendAttributeValues(const RTIData& tag)
{
if (!_rtiObjectInstance.valid()) {
SG_LOG(SG_IO, SG_INFO, "Not updating inactive object!");
return;
}
- if (_attributeCallback.valid())
- _attributeCallback->updateAttributeValues(*this, tag);
- _rtiObjectInstance->updateAttributeValues(timeStamp, tag);
+ _rtiObjectInstance->updateAttributeValues(tag);
}
void
-HLAObjectInstance::reflectQueuedAttributeValues(const SGTimeStamp& timeStamp)
+HLAObjectInstance::sendAttributeValues(const SGTimeStamp& timeStamp, const RTIData& tag)
{
if (!_rtiObjectInstance.valid()) {
SG_LOG(SG_IO, SG_INFO, "Not updating inactive object!");
return;
}
- _rtiObjectInstance->reflectQueuedAttributeValues(timeStamp);
+ _rtiObjectInstance->updateAttributeValues(timeStamp, tag);
}
void
-HLAObjectInstance::removeInstance(const RTIData& tag)
+HLAObjectInstance::reflectAttributeValues(const HLAIndexList& indexList, const RTIData& tag)
+{
+ for (HLAIndexList::const_iterator i = indexList.begin(); i != indexList.end(); ++i)
+ reflectAttributeValue(*i, tag);
+}
+
+void
+HLAObjectInstance::reflectAttributeValues(const HLAIndexList& indexList,
+ const SGTimeStamp& timeStamp, const RTIData& tag)
+{
+ for (HLAIndexList::const_iterator i = indexList.begin(); i != indexList.end(); ++i)
+ reflectAttributeValue(*i, timeStamp, tag);
+}
+
+void
+HLAObjectInstance::reflectAttributeValue(unsigned index, const RTIData& tag)
{
- SGSharedPtr<HLAObjectClass> objectClass = _objectClass.lock();
- if (!objectClass.valid())
+ HLADataElement* dataElement = getAttributeDataElement(index);
+ if (!dataElement)
return;
- objectClass->removeInstanceCallback(*this, tag);
+ dataElement->setTimeStampValid(false);
+ _rtiObjectInstance->decodeAttributeData(index, *dataElement);
}
void
-HLAObjectInstance::reflectAttributeValues(const RTIIndexDataPairList& dataPairList, const RTIData& tag)
+HLAObjectInstance::reflectAttributeValue(unsigned index, const SGTimeStamp& timeStamp, const RTIData& tag)
{
- if (!_attributeCallback.valid())
+ HLADataElement* dataElement = getAttributeDataElement(index);
+ if (!dataElement)
return;
- _attributeCallback->reflectAttributeValues(*this, dataPairList, tag);
+ dataElement->setTimeStamp(timeStamp);
+ dataElement->setTimeStampValid(true);
+ _rtiObjectInstance->decodeAttributeData(index, *dataElement);
}
void
-HLAObjectInstance::reflectAttributeValues(const RTIIndexDataPairList& dataPairList,
- const SGTimeStamp& timeStamp, const RTIData& tag)
+HLAObjectInstance::_setRTIObjectInstance(RTIObjectInstance* rtiObjectInstance)
{
- if (!_attributeCallback.valid())
+ if (!_objectClass.valid())
return;
- _attributeCallback->reflectAttributeValues(*this, dataPairList, timeStamp, tag);
+
+ _rtiObjectInstance = rtiObjectInstance;
+ _rtiObjectInstance->setObjectInstance(this);
+ _name = _rtiObjectInstance->getName();
+
+ unsigned numAttributes = getNumAttributes();
+ _attributeVector.resize(numAttributes);
+ for (unsigned i = 0; i < numAttributes; ++i) {
+ HLAUpdateType updateType = _objectClass->getAttributeUpdateType(i);
+ if (getAttributeOwned(i) && updateType != HLAUndefinedUpdate) {
+ _attributeVector[i]._enabledUpdate = true;
+ _attributeVector[i]._unconditionalUpdate = (updateType == HLAPeriodicUpdate);
+ // In case of an owned attribute, now encode its value
+ encodeAttributeValue(i);
+ } else {
+ _attributeVector[i]._enabledUpdate = false;
+ _attributeVector[i]._unconditionalUpdate = false;
+ }
+ }
+
+ // This makes sense with any new object. Even if we registered one, there might be unpublished attributes.
+ HLAIndexList indexList;
+ for (unsigned i = 0; i < numAttributes; ++i) {
+ HLAUpdateType updateType = _objectClass->getAttributeUpdateType(i);
+ if (getAttributeOwned(i))
+ continue;
+ if (updateType == HLAUndefinedUpdate)
+ continue;
+ if (updateType == HLAPeriodicUpdate)
+ continue;
+ indexList.push_back(i);
+ }
+ _rtiObjectInstance->requestObjectAttributeValueUpdate(indexList);
+}
+
+void
+HLAObjectInstance::_clearRTIObjectInstance()
+{
+ if (!_rtiObjectInstance.valid())
+ return;
+
+ for (unsigned i = 0; i < _attributeVector.size(); ++i) {
+ _attributeVector[i]._enabledUpdate = false;
+ _attributeVector[i]._unconditionalUpdate = false;
+ }
+
+ _rtiObjectInstance->setObjectInstance(0);
+ _rtiObjectInstance = 0;
+}
+
+void
+HLAObjectInstance::_removeInstance(const RTIData& tag)
+{
+ if (!_objectClass.valid())
+ return;
+ _objectClass->_removeInstance(*this, tag);
+}
+
+void
+HLAObjectInstance::_reflectAttributeValues(const HLAIndexList& indexList, const RTIData& tag)
+{
+ if (_reflectCallback.valid()) {
+ _reflectCallback->reflectAttributeValues(*this, indexList, tag);
+ } else {
+ reflectAttributeValues(indexList, tag);
+ }
+}
+
+void
+HLAObjectInstance::_reflectAttributeValues(const HLAIndexList& indexList, const SGTimeStamp& timeStamp, const RTIData& tag)
+{
+ if (_reflectCallback.valid()) {
+ _reflectCallback->reflectAttributeValues(*this, indexList, timeStamp, tag);
+ } else {
+ reflectAttributeValues(indexList, timeStamp, tag);
+ }
}
} // namespace simgear