hla: Introduce HLADataElementIndex.
This commit is contained in:
@@ -108,6 +108,54 @@ HLAArrayDataElement::~HLAArrayDataElement()
|
|||||||
clearStamp();
|
clearStamp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
HLAArrayDataElement::setDataElement(HLADataElementIndex::const_iterator begin, HLADataElementIndex::const_iterator end, HLADataElement* dataElement)
|
||||||
|
{
|
||||||
|
// Must have happened in the parent
|
||||||
|
if (begin == end)
|
||||||
|
return false;
|
||||||
|
unsigned index = *begin;
|
||||||
|
if (++begin != end) {
|
||||||
|
if (getNumElements() <= index && !setNumElements(index + 1))
|
||||||
|
return false;
|
||||||
|
if (!getElement(index) && getElementDataType()) {
|
||||||
|
HLADataElementFactoryVisitor visitor;
|
||||||
|
getElementDataType()->accept(visitor);
|
||||||
|
setElement(index, visitor.getDataElement());
|
||||||
|
}
|
||||||
|
if (!getElement(index))
|
||||||
|
return false;
|
||||||
|
return getElement(index)->setDataElement(begin, end, dataElement);
|
||||||
|
} else {
|
||||||
|
if (!dataElement->setDataType(getElementDataType()))
|
||||||
|
return false;
|
||||||
|
setElement(index, dataElement);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HLADataElement*
|
||||||
|
HLAArrayDataElement::getDataElement(HLADataElementIndex::const_iterator begin, HLADataElementIndex::const_iterator end)
|
||||||
|
{
|
||||||
|
if (begin == end)
|
||||||
|
return this;
|
||||||
|
HLADataElement* dataElement = getElement(*begin);
|
||||||
|
if (!dataElement)
|
||||||
|
return 0;
|
||||||
|
return dataElement->getDataElement(++begin, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
const HLADataElement*
|
||||||
|
HLAArrayDataElement::getDataElement(HLADataElementIndex::const_iterator begin, HLADataElementIndex::const_iterator end) const
|
||||||
|
{
|
||||||
|
if (begin == end)
|
||||||
|
return this;
|
||||||
|
const HLADataElement* dataElement = getElement(*begin);
|
||||||
|
if (!dataElement)
|
||||||
|
return 0;
|
||||||
|
return dataElement->getDataElement(++begin, end);
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
HLAArrayDataElement::setNumElements(unsigned size)
|
HLAArrayDataElement::setNumElements(unsigned size)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -59,6 +59,10 @@ public:
|
|||||||
HLAArrayDataElement(const HLAArrayDataType* dataType = 0);
|
HLAArrayDataElement(const HLAArrayDataType* dataType = 0);
|
||||||
virtual ~HLAArrayDataElement();
|
virtual ~HLAArrayDataElement();
|
||||||
|
|
||||||
|
virtual bool setDataElement(HLADataElementIndex::const_iterator begin, HLADataElementIndex::const_iterator end, HLADataElement* dataElement);
|
||||||
|
virtual HLADataElement* getDataElement(HLADataElementIndex::const_iterator begin, HLADataElementIndex::const_iterator end);
|
||||||
|
virtual const HLADataElement* getDataElement(HLADataElementIndex::const_iterator begin, HLADataElementIndex::const_iterator end) const;
|
||||||
|
|
||||||
virtual bool setNumElements(unsigned size);
|
virtual bool setNumElements(unsigned size);
|
||||||
virtual bool decodeElement(HLADecodeStream& stream, unsigned i);
|
virtual bool decodeElement(HLADecodeStream& stream, unsigned i);
|
||||||
virtual unsigned getNumElements() const;
|
virtual unsigned getNumElements() const;
|
||||||
|
|||||||
@@ -137,6 +137,28 @@ HLADataElement::~HLADataElement()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
HLADataElement::setDataElement(HLADataElementIndex::const_iterator begin, HLADataElementIndex::const_iterator end, HLADataElement* dataElement)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
HLADataElement*
|
||||||
|
HLADataElement::getDataElement(HLADataElementIndex::const_iterator begin, HLADataElementIndex::const_iterator end)
|
||||||
|
{
|
||||||
|
if (begin != end)
|
||||||
|
return 0;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
const HLADataElement*
|
||||||
|
HLADataElement::getDataElement(HLADataElementIndex::const_iterator begin, HLADataElementIndex::const_iterator end) const
|
||||||
|
{
|
||||||
|
if (begin != end)
|
||||||
|
return 0;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
HLADataElement::setTimeStamp(const SGTimeStamp& timeStamp)
|
HLADataElement::setTimeStamp(const SGTimeStamp& timeStamp)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
#include <simgear/timing/timestamp.hxx>
|
#include <simgear/timing/timestamp.hxx>
|
||||||
#include "RTIData.hxx"
|
#include "RTIData.hxx"
|
||||||
#include "HLADataType.hxx"
|
#include "HLADataType.hxx"
|
||||||
|
#include "HLATypes.hxx"
|
||||||
|
|
||||||
class SGTimeStamp;
|
class SGTimeStamp;
|
||||||
|
|
||||||
@@ -46,6 +47,17 @@ public:
|
|||||||
virtual const HLADataType* getDataType() const = 0;
|
virtual const HLADataType* getDataType() const = 0;
|
||||||
virtual bool setDataType(const HLADataType* dataType) = 0;
|
virtual bool setDataType(const HLADataType* dataType) = 0;
|
||||||
|
|
||||||
|
bool setDataElement(const HLADataElementIndex& index, HLADataElement* dataElement)
|
||||||
|
{ return setDataElement(index.begin(), index.end(), dataElement); }
|
||||||
|
HLADataElement* getDataElement(const HLADataElementIndex& index)
|
||||||
|
{ return getDataElement(index.begin(), index.end()); }
|
||||||
|
const HLADataElement* getDataElement(const HLADataElementIndex& index) const
|
||||||
|
{ return getDataElement(index.begin(), index.end()); }
|
||||||
|
|
||||||
|
virtual bool setDataElement(HLADataElementIndex::const_iterator begin, HLADataElementIndex::const_iterator end, HLADataElement* dataElement);
|
||||||
|
virtual HLADataElement* getDataElement(HLADataElementIndex::const_iterator begin, HLADataElementIndex::const_iterator end);
|
||||||
|
virtual const HLADataElement* getDataElement(HLADataElementIndex::const_iterator begin, HLADataElementIndex::const_iterator end) const;
|
||||||
|
|
||||||
/// Returns the time stamp if this data element.
|
/// Returns the time stamp if this data element.
|
||||||
/// Do not access this getter if the getTimeStampValid() method returns false.
|
/// Do not access this getter if the getTimeStampValid() method returns false.
|
||||||
const SGTimeStamp& getTimeStamp() const
|
const SGTimeStamp& getTimeStamp() const
|
||||||
|
|||||||
@@ -88,6 +88,161 @@ HLADataType::releaseDataTypeReferences()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class HLADataType::_DataElementIndexVisitor : public HLADataTypeVisitor {
|
||||||
|
public:
|
||||||
|
_DataElementIndexVisitor(HLADataElementIndex& index, const std::string& path, size_t offset) :
|
||||||
|
_index(index),
|
||||||
|
_path(path),
|
||||||
|
_offset(offset),
|
||||||
|
_success(false)
|
||||||
|
{ }
|
||||||
|
virtual ~_DataElementIndexVisitor()
|
||||||
|
{ }
|
||||||
|
|
||||||
|
virtual void apply(const HLADataType& dataType)
|
||||||
|
{
|
||||||
|
if (_path.size() == _offset)
|
||||||
|
_success = true;
|
||||||
|
}
|
||||||
|
virtual void apply(const HLAArrayDataType& dataType)
|
||||||
|
{
|
||||||
|
if (_path.size() <= _offset) {
|
||||||
|
SG_LOG(SG_NETWORK, SG_ALERT, "HLADataType: faild to parse data element index \"" << _path << "\":\n"
|
||||||
|
<< "Expected array subscript at the end of the path!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (_path[_offset] != '[') {
|
||||||
|
SG_LOG(SG_NETWORK, SG_ALERT, "HLADataType: faild to parse data element index \"" << _path << "\":\n"
|
||||||
|
<< "Expected array subscript at the end of the path!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
++_offset;
|
||||||
|
if (_path.size() <= _offset) {
|
||||||
|
SG_LOG(SG_NETWORK, SG_ALERT, "HLADataType: faild to parse data element index \"" << _path << "\":\n"
|
||||||
|
<< "Expected closing array subscript at the end of the path!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
unsigned index = 0;
|
||||||
|
bool closed = false;
|
||||||
|
while (_offset <= _path.size()) {
|
||||||
|
if (_path[_offset] == ']') {
|
||||||
|
++_offset;
|
||||||
|
closed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
unsigned v = _path[_offset] - '0';
|
||||||
|
// Error, no number
|
||||||
|
if (10 <= v) {
|
||||||
|
SG_LOG(SG_NETWORK, SG_ALERT, "HLADataType: faild to parse data element index \"" << _path << "\":\n"
|
||||||
|
<< "Array subscript is not a number!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
index *= 10;
|
||||||
|
index += v;
|
||||||
|
++_offset;
|
||||||
|
}
|
||||||
|
if (!closed) {
|
||||||
|
SG_LOG(SG_NETWORK, SG_ALERT, "HLADataType: faild to parse data element index \"" << _path << "\":\n"
|
||||||
|
<< "Expected closing array subscript at the end of the path!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!dataType.getElementDataType()) {
|
||||||
|
SG_LOG(SG_NETWORK, SG_ALERT, "HLADataType: faild to parse data element index \"" << _path << "\":\n"
|
||||||
|
<< "Undefined array element data type!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_index.push_back(index);
|
||||||
|
_success = dataType.getElementDataType()->getDataElementIndex(_index, _path, _offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void apply(const HLAFixedRecordDataType& dataType)
|
||||||
|
{
|
||||||
|
if (_path.size() <= _offset) {
|
||||||
|
SG_LOG(SG_NETWORK, SG_ALERT, "HLADataType: faild to parse data element index \"" << _path << "\":\n"
|
||||||
|
<< "Expected field name at the end of the path!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (_path[_offset] == '.')
|
||||||
|
++_offset;
|
||||||
|
if (_path.size() <= _offset) {
|
||||||
|
SG_LOG(SG_NETWORK, SG_ALERT, "HLADataType: faild to parse data element index \"" << _path << "\":\n"
|
||||||
|
<< "Expected field name at the end of the path!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
size_t len = _path.find_first_of("[.", _offset) - _offset;
|
||||||
|
unsigned index = 0;
|
||||||
|
while (index < dataType.getNumFields()) {
|
||||||
|
if (_path.compare(_offset, len, dataType.getFieldName(index)) == 0)
|
||||||
|
break;
|
||||||
|
++index;
|
||||||
|
}
|
||||||
|
if (dataType.getNumFields() <= index) {
|
||||||
|
SG_LOG(SG_NETWORK, SG_ALERT, "HLADataType: faild to parse data element index \"" << _path << "\":\n"
|
||||||
|
<< "Field \"" << _path.substr(_offset, len) << "\" not found in fixed record data type \""
|
||||||
|
<< dataType.getName() << "\"!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!dataType.getFieldDataType(index)) {
|
||||||
|
SG_LOG(SG_NETWORK, SG_ALERT, "HLADataType: faild to parse data element index \"" << _path << "\":\n"
|
||||||
|
<< "Undefined field data type in variant record data type \""
|
||||||
|
<< dataType.getName() << "\" at field \"" << dataType.getFieldName(index) << "\"!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_index.push_back(index);
|
||||||
|
_success = dataType.getFieldDataType(index)->getDataElementIndex(_index, _path, _offset + len);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void apply(const HLAVariantRecordDataType& dataType)
|
||||||
|
{
|
||||||
|
if (_path.size() <= _offset) {
|
||||||
|
SG_LOG(SG_NETWORK, SG_ALERT, "HLADataType: faild to parse data element index \"" << _path << "\":\n"
|
||||||
|
<< "Expected alternative name at the end of the path!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (_path[_offset] == '.')
|
||||||
|
++_offset;
|
||||||
|
if (_path.size() <= _offset) {
|
||||||
|
SG_LOG(SG_NETWORK, SG_ALERT, "HLADataType: faild to parse data element index \"" << _path << "\":\n"
|
||||||
|
<< "Expected alternative name at the end of the path!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
size_t len = _path.find_first_of("[.", _offset) - _offset;
|
||||||
|
unsigned index = 0;
|
||||||
|
while (index < dataType.getNumAlternatives()) {
|
||||||
|
if (_path.compare(_offset, len, dataType.getAlternativeName(index)) == 0)
|
||||||
|
break;
|
||||||
|
++index;
|
||||||
|
}
|
||||||
|
if (dataType.getNumAlternatives() <= index) {
|
||||||
|
SG_LOG(SG_NETWORK, SG_ALERT, "HLADataType: faild to parse data element index \"" << _path << "\":\n"
|
||||||
|
<< "Alternative \"" << _path.substr(_offset, len) << "\" not found in variant record data type \""
|
||||||
|
<< dataType.getName() << "\"!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!dataType.getAlternativeDataType(index)) {
|
||||||
|
SG_LOG(SG_NETWORK, SG_ALERT, "HLADataType: faild to parse data element index \"" << _path << "\":\n"
|
||||||
|
<< "Undefined alternative data type in variant record data type \""
|
||||||
|
<< dataType.getName() << "\" at alternative \"" << dataType.getAlternativeName(index) << "\"!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_index.push_back(index);
|
||||||
|
_success = dataType.getAlternativeDataType(index)->getDataElementIndex(_index, _path, _offset + len);
|
||||||
|
}
|
||||||
|
|
||||||
|
HLADataElementIndex& _index;
|
||||||
|
const std::string& _path;
|
||||||
|
size_t _offset;
|
||||||
|
bool _success;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool
|
||||||
|
HLADataType::getDataElementIndex(HLADataElementIndex& index, const std::string& path, size_t offset) const
|
||||||
|
{
|
||||||
|
_DataElementIndexVisitor visitor(index, path, offset);
|
||||||
|
accept(visitor);
|
||||||
|
return visitor._success;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
HLADataType::setAlignment(unsigned alignment)
|
HLADataType::setAlignment(unsigned alignment)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#include <simgear/structure/SGWeakPtr.hxx>
|
#include <simgear/structure/SGWeakPtr.hxx>
|
||||||
#include <simgear/structure/SGWeakReferenced.hxx>
|
#include <simgear/structure/SGWeakReferenced.hxx>
|
||||||
#include "RTIData.hxx"
|
#include "RTIData.hxx"
|
||||||
|
#include "HLATypes.hxx"
|
||||||
|
|
||||||
namespace simgear {
|
namespace simgear {
|
||||||
|
|
||||||
@@ -63,6 +64,8 @@ public:
|
|||||||
/// required for propper feeing of memory.
|
/// required for propper feeing of memory.
|
||||||
virtual void releaseDataTypeReferences();
|
virtual void releaseDataTypeReferences();
|
||||||
|
|
||||||
|
bool getDataElementIndex(HLADataElementIndex& index, const std::string& path, size_t offset) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
HLADataType(const std::string& name, unsigned alignment = 1);
|
HLADataType(const std::string& name, unsigned alignment = 1);
|
||||||
void setAlignment(unsigned alignment);
|
void setAlignment(unsigned alignment);
|
||||||
@@ -70,6 +73,8 @@ protected:
|
|||||||
virtual void _recomputeAlignmentImplementation();
|
virtual void _recomputeAlignmentImplementation();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
class _DataElementIndexVisitor;
|
||||||
|
|
||||||
std::string _name;
|
std::string _name;
|
||||||
std::string _semantics;
|
std::string _semantics;
|
||||||
unsigned _alignment;
|
unsigned _alignment;
|
||||||
|
|||||||
@@ -146,6 +146,54 @@ HLAFixedRecordDataElement::setDataType(const HLADataType* dataType)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
HLAFixedRecordDataElement::setDataElement(HLADataElementIndex::const_iterator begin, HLADataElementIndex::const_iterator end, HLADataElement* dataElement)
|
||||||
|
{
|
||||||
|
// Must have happened in the parent
|
||||||
|
if (begin == end)
|
||||||
|
return false;
|
||||||
|
unsigned index = *begin;
|
||||||
|
if (++begin != end) {
|
||||||
|
if (getNumFields() <= index)
|
||||||
|
return false;
|
||||||
|
if (!getField(index) && getFieldDataType(index)) {
|
||||||
|
HLADataElementFactoryVisitor visitor;
|
||||||
|
getFieldDataType(index)->accept(visitor);
|
||||||
|
setField(index, visitor.getDataElement());
|
||||||
|
}
|
||||||
|
if (!getField(index))
|
||||||
|
return false;
|
||||||
|
return getField(index)->setDataElement(begin, end, dataElement);
|
||||||
|
} else {
|
||||||
|
if (!dataElement->setDataType(getFieldDataType(index)))
|
||||||
|
return false;
|
||||||
|
setField(index, dataElement);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HLADataElement*
|
||||||
|
HLAFixedRecordDataElement::getDataElement(HLADataElementIndex::const_iterator begin, HLADataElementIndex::const_iterator end)
|
||||||
|
{
|
||||||
|
if (begin == end)
|
||||||
|
return this;
|
||||||
|
HLADataElement* dataElement = getField(*begin);
|
||||||
|
if (!dataElement)
|
||||||
|
return 0;
|
||||||
|
return dataElement->getDataElement(++begin, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
const HLADataElement*
|
||||||
|
HLAFixedRecordDataElement::getDataElement(HLADataElementIndex::const_iterator begin, HLADataElementIndex::const_iterator end) const
|
||||||
|
{
|
||||||
|
if (begin == end)
|
||||||
|
return this;
|
||||||
|
const HLADataElement* dataElement = getField(*begin);
|
||||||
|
if (!dataElement)
|
||||||
|
return 0;
|
||||||
|
return dataElement->getDataElement(++begin, end);
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
HLAFixedRecordDataElement::decodeField(HLADecodeStream& stream, unsigned i)
|
HLAFixedRecordDataElement::decodeField(HLADecodeStream& stream, unsigned i)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -60,6 +60,10 @@ public:
|
|||||||
|
|
||||||
virtual bool setDataType(const HLADataType* dataType);
|
virtual bool setDataType(const HLADataType* dataType);
|
||||||
|
|
||||||
|
virtual bool setDataElement(HLADataElementIndex::const_iterator begin, HLADataElementIndex::const_iterator end, HLADataElement* dataElement);
|
||||||
|
virtual HLADataElement* getDataElement(HLADataElementIndex::const_iterator begin, HLADataElementIndex::const_iterator end);
|
||||||
|
virtual const HLADataElement* getDataElement(HLADataElementIndex::const_iterator begin, HLADataElementIndex::const_iterator end) const;
|
||||||
|
|
||||||
virtual bool decodeField(HLADecodeStream& stream, unsigned i);
|
virtual bool decodeField(HLADecodeStream& stream, unsigned i);
|
||||||
virtual bool encodeField(HLAEncodeStream& stream, unsigned i) const;
|
virtual bool encodeField(HLAEncodeStream& stream, unsigned i) const;
|
||||||
|
|
||||||
|
|||||||
@@ -210,6 +210,36 @@ HLAObjectClass::getIndexPathPair(const std::string& path) const
|
|||||||
return getIndexPathPair(HLADataElement::toStringPathPair(path));
|
return getIndexPathPair(HLADataElement::toStringPathPair(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
HLAObjectClass::getAttributeIndex(HLADataElementIndex& dataElementIndex, const std::string& path) const
|
||||||
|
{
|
||||||
|
if (path.empty()) {
|
||||||
|
SG_LOG(SG_NETWORK, SG_ALERT, "HLAObjectClass: failed to parse empty element path!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
size_t len = path.find_first_of("[.");
|
||||||
|
unsigned index = 0;
|
||||||
|
while (index < getNumAttributes()) {
|
||||||
|
if (path.compare(0, len, getAttributeName(index)) == 0)
|
||||||
|
break;
|
||||||
|
++index;
|
||||||
|
}
|
||||||
|
if (getNumAttributes() <= index) {
|
||||||
|
SG_LOG(SG_NETWORK, SG_ALERT, "HLAObjectClass: faild to parse data element index \"" << path << "\":\n"
|
||||||
|
<< "Attribute \"" << path.substr(0, len) << "\" not found in object class \""
|
||||||
|
<< getName() << "\"!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!getAttributeDataType(index)) {
|
||||||
|
SG_LOG(SG_NETWORK, SG_ALERT, "HLAObjectClass: faild to parse data element index \"" << path << "\":\n"
|
||||||
|
<< "Undefined attribute data type in variant record data type \""
|
||||||
|
<< getAttributeName(index) << "\"!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
dataElementIndex.push_back(index);
|
||||||
|
return getAttributeDataType(index)->getDataElementIndex(dataElementIndex, path, len);
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
HLAObjectClass::subscribe()
|
HLAObjectClass::subscribe()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -77,6 +77,9 @@ public:
|
|||||||
/// Return the index, path pair for the given string path
|
/// Return the index, path pair for the given string path
|
||||||
HLADataElement::IndexPathPair getIndexPathPair(const std::string& path) const;
|
HLADataElement::IndexPathPair getIndexPathPair(const std::string& path) const;
|
||||||
|
|
||||||
|
/// Get the attribute data element index for the given path, return true if successful
|
||||||
|
bool getAttributeIndex(HLADataElementIndex& dataElementIndex, const std::string& path) const;
|
||||||
|
|
||||||
virtual bool subscribe();
|
virtual bool subscribe();
|
||||||
virtual bool unsubscribe();
|
virtual bool unsubscribe();
|
||||||
|
|
||||||
|
|||||||
@@ -442,6 +442,87 @@ HLAObjectInstance::setAttributes(const HLAAttributePathElementMap& attributePath
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
HLAObjectInstance::getAttributeIndex(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->getAttributeIndex(index, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HLAObjectInstance::setAttributeDataElement(const HLADataElementIndex& index, const SGSharedPtr<HLADataElement>& dataElement)
|
||||||
|
{
|
||||||
|
if (index.empty())
|
||||||
|
return;
|
||||||
|
if (index.size() == 1) {
|
||||||
|
if (!getAttributeDataType(index[0]))
|
||||||
|
return;
|
||||||
|
if (dataElement.valid() && !dataElement->setDataType(getAttributeDataType(index[0])))
|
||||||
|
return;
|
||||||
|
setAttributeDataElement(index[0], dataElement);
|
||||||
|
} else {
|
||||||
|
SGSharedPtr<HLADataElement> attributeDataElement = getAttributeDataElement(index[0]);
|
||||||
|
if (!attributeDataElement.valid())
|
||||||
|
attributeDataElement = createAttributeDataElement(index[0]);
|
||||||
|
if (!attributeDataElement.valid())
|
||||||
|
return;
|
||||||
|
attributeDataElement->setDataElement(index.begin() + 1, index.end(), dataElement.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HLADataElement*
|
||||||
|
HLAObjectInstance::getAttributeDataElement(const std::string& path)
|
||||||
|
{
|
||||||
|
HLADataElementIndex index;
|
||||||
|
if (!getAttributeIndex(index, path))
|
||||||
|
return 0;
|
||||||
|
return getAttributeDataElement(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
const HLADataElement*
|
||||||
|
HLAObjectInstance::getAttributeDataElement(const std::string& path) const
|
||||||
|
{
|
||||||
|
HLADataElementIndex index;
|
||||||
|
if (!getAttributeIndex(index, path))
|
||||||
|
return 0;
|
||||||
|
return getAttributeDataElement(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HLAObjectInstance::setAttributeDataElement(const std::string& path, const SGSharedPtr<HLADataElement>& dataElement)
|
||||||
|
{
|
||||||
|
HLADataElementIndex index;
|
||||||
|
if (!getAttributeIndex(index, path))
|
||||||
|
return;
|
||||||
|
setAttributeDataElement(index, dataElement);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
HLAObjectInstance::discoverInstance(const RTIData& tag)
|
HLAObjectInstance::discoverInstance(const RTIData& tag)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -77,6 +77,25 @@ public:
|
|||||||
void setAttribute(unsigned index, const HLAPathElementMap& pathElementMap);
|
void setAttribute(unsigned index, const HLAPathElementMap& pathElementMap);
|
||||||
void setAttributes(const HLAAttributePathElementMap& attributePathElementMap);
|
void setAttributes(const HLAAttributePathElementMap& attributePathElementMap);
|
||||||
|
|
||||||
|
/// Retrieve the data element index for the given path.
|
||||||
|
bool getAttributeIndex(HLADataElementIndex& index, const std::string& path) const;
|
||||||
|
|
||||||
|
/// Return the data element of the attribute with the given index
|
||||||
|
HLADataElement* getAttributeDataElement(const HLADataElementIndex& index);
|
||||||
|
const HLADataElement* getAttributeDataElement(const HLADataElementIndex& index) const;
|
||||||
|
/// Set the data element of the attribute with the given index
|
||||||
|
void setAttributeDataElement(const HLADataElementIndex& index, const SGSharedPtr<HLADataElement>& dataElement);
|
||||||
|
|
||||||
|
/// Return the data element of the attribute with the given path.
|
||||||
|
/// The method is only for convenience as parsing the path is expensive.
|
||||||
|
/// Precompute the index and use the index instead if you use this method more often.
|
||||||
|
HLADataElement* getAttributeDataElement(const std::string& path);
|
||||||
|
const HLADataElement* getAttributeDataElement(const std::string& path) const;
|
||||||
|
/// Set the data element of the attribute with the given path
|
||||||
|
/// The method is only for convenience as parsing the path is expensive.
|
||||||
|
/// Precompute the index and use the index instead if you use this method more often.
|
||||||
|
void setAttributeDataElement(const std::string& path, const SGSharedPtr<HLADataElement>& dataElement);
|
||||||
|
|
||||||
/// Gets called on discovering this object instance.
|
/// Gets called on discovering this object instance.
|
||||||
virtual void discoverInstance(const RTIData& tag);
|
virtual void discoverInstance(const RTIData& tag);
|
||||||
/// Gets called on remove this object instance.
|
/// Gets called on remove this object instance.
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#define HLATypes_hxx
|
#define HLATypes_hxx
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace simgear {
|
namespace simgear {
|
||||||
|
|
||||||
@@ -42,6 +43,8 @@ enum HLAUpdateType {
|
|||||||
|
|
||||||
typedef std::list<unsigned> HLAIndexList;
|
typedef std::list<unsigned> HLAIndexList;
|
||||||
|
|
||||||
|
typedef std::vector<unsigned> HLADataElementIndex;
|
||||||
|
|
||||||
} // namespace simgear
|
} // namespace simgear
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
#include <simgear/debug/logstream.hxx>
|
#include <simgear/debug/logstream.hxx>
|
||||||
|
|
||||||
#include "HLADataElementVisitor.hxx"
|
#include "HLADataElementVisitor.hxx"
|
||||||
|
#include "HLADataTypeVisitor.hxx"
|
||||||
|
|
||||||
namespace simgear {
|
namespace simgear {
|
||||||
|
|
||||||
@@ -122,6 +123,58 @@ HLAVariantRecordDataElement::~HLAVariantRecordDataElement()
|
|||||||
clearStamp();
|
clearStamp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
HLAVariantRecordDataElement::setDataElement(HLADataElementIndex::const_iterator begin, HLADataElementIndex::const_iterator end, HLADataElement* dataElement)
|
||||||
|
{
|
||||||
|
// Must have happened in the parent
|
||||||
|
if (begin == end)
|
||||||
|
return false;
|
||||||
|
unsigned index = *begin;
|
||||||
|
if (++begin != end) {
|
||||||
|
if (!setAlternativeIndex(index))
|
||||||
|
return false;
|
||||||
|
if (!_dataElement.valid() && getAlternativeDataType()) {
|
||||||
|
HLADataElementFactoryVisitor visitor;
|
||||||
|
getAlternativeDataType()->accept(visitor);
|
||||||
|
_dataElement = visitor.getDataElement();
|
||||||
|
}
|
||||||
|
if (!_dataElement.valid())
|
||||||
|
return false;
|
||||||
|
return _dataElement->setDataElement(begin, end, dataElement);
|
||||||
|
} else {
|
||||||
|
if (!setAlternativeIndex(index))
|
||||||
|
return false;
|
||||||
|
if (!dataElement->setDataType(getAlternativeDataType()))
|
||||||
|
return false;
|
||||||
|
_dataElement = dataElement;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HLADataElement*
|
||||||
|
HLAVariantRecordDataElement::getDataElement(HLADataElementIndex::const_iterator begin, HLADataElementIndex::const_iterator end)
|
||||||
|
{
|
||||||
|
if (begin == end)
|
||||||
|
return this;
|
||||||
|
if (getAlternativeIndex() != *begin)
|
||||||
|
return 0;
|
||||||
|
if (!_dataElement.valid())
|
||||||
|
return 0;
|
||||||
|
return _dataElement->getDataElement(++begin, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
const HLADataElement*
|
||||||
|
HLAVariantRecordDataElement::getDataElement(HLADataElementIndex::const_iterator begin, HLADataElementIndex::const_iterator end) const
|
||||||
|
{
|
||||||
|
if (begin == end)
|
||||||
|
return this;
|
||||||
|
if (getAlternativeIndex() != *begin)
|
||||||
|
return 0;
|
||||||
|
if (!_dataElement.valid())
|
||||||
|
return 0;
|
||||||
|
return _dataElement->getDataElement(++begin, end);
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
HLAVariantRecordDataElement::setAlternativeIndex(unsigned index)
|
HLAVariantRecordDataElement::setAlternativeIndex(unsigned index)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -57,6 +57,10 @@ public:
|
|||||||
HLAVariantRecordDataElement(const HLAVariantRecordDataType* dataType);
|
HLAVariantRecordDataElement(const HLAVariantRecordDataType* dataType);
|
||||||
virtual ~HLAVariantRecordDataElement();
|
virtual ~HLAVariantRecordDataElement();
|
||||||
|
|
||||||
|
virtual bool setDataElement(HLADataElementIndex::const_iterator begin, HLADataElementIndex::const_iterator end, HLADataElement* dataElement);
|
||||||
|
virtual HLADataElement* getDataElement(HLADataElementIndex::const_iterator begin, HLADataElementIndex::const_iterator end);
|
||||||
|
virtual const HLADataElement* getDataElement(HLADataElementIndex::const_iterator begin, HLADataElementIndex::const_iterator end) const;
|
||||||
|
|
||||||
virtual bool setAlternativeIndex(unsigned index);
|
virtual bool setAlternativeIndex(unsigned index);
|
||||||
virtual bool decodeAlternative(HLADecodeStream& stream);
|
virtual bool decodeAlternative(HLADecodeStream& stream);
|
||||||
virtual unsigned getAlternativeIndex() const;
|
virtual unsigned getAlternativeIndex() const;
|
||||||
|
|||||||
Reference in New Issue
Block a user