X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fhla%2FHLAPropertyDataElement.cxx;h=e8a931ee27c0ed8432553fef3c9432dfbbac60d6;hb=086a30e61aa153008bd403c79cd1bff3ad594179;hp=db4f00ba84a571a3f6330dd6650435caa80b9f8b;hpb=252a539e69bda7cf8cf0c5198f25f38b0a710ee2;p=simgear.git diff --git a/simgear/hla/HLAPropertyDataElement.cxx b/simgear/hla/HLAPropertyDataElement.cxx index db4f00ba..e8a931ee 100644 --- a/simgear/hla/HLAPropertyDataElement.cxx +++ b/simgear/hla/HLAPropertyDataElement.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de +// Copyright (C) 2009 - 2011 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 @@ -17,77 +17,208 @@ #include "HLAPropertyDataElement.hxx" +#include "HLAArrayDataElement.hxx" #include "HLADataTypeVisitor.hxx" +#include "HLAFixedRecordDataElement.hxx" +#include "HLAVariantDataElement.hxx" namespace simgear { -class HLAPropertyDataElement::DecodeVisitor : public HLADataTypeDecodeVisitor { +class HLAPropertyDataElement::ScalarDecodeVisitor : public HLADataTypeDecodeVisitor { public: - DecodeVisitor(HLADecodeStream& stream, HLAPropertyReference& propertyReference) : + ScalarDecodeVisitor(HLADecodeStream& stream, SGPropertyNode& propertyNode) : HLADataTypeDecodeVisitor(stream), - _propertyReference(propertyReference) + _propertyNode(propertyNode) + { } + virtual ~ScalarDecodeVisitor() { } virtual void apply(const HLAInt8DataType& dataType) { int8_t value = 0; dataType.decode(_stream, value); - _propertyReference.setIntValue(value); + _propertyNode.setIntValue(value); } virtual void apply(const HLAUInt8DataType& dataType) { uint8_t value = 0; dataType.decode(_stream, value); - _propertyReference.setIntValue(value); + _propertyNode.setIntValue(value); } virtual void apply(const HLAInt16DataType& dataType) { int16_t value = 0; dataType.decode(_stream, value); - _propertyReference.setIntValue(value); + _propertyNode.setIntValue(value); } virtual void apply(const HLAUInt16DataType& dataType) { uint16_t value = 0; dataType.decode(_stream, value); - _propertyReference.setIntValue(value); + _propertyNode.setIntValue(value); } virtual void apply(const HLAInt32DataType& dataType) { int32_t value = 0; dataType.decode(_stream, value); - _propertyReference.setIntValue(value); + _propertyNode.setIntValue(value); } virtual void apply(const HLAUInt32DataType& dataType) { uint32_t value = 0; dataType.decode(_stream, value); - _propertyReference.setIntValue(value); + _propertyNode.setIntValue(value); } virtual void apply(const HLAInt64DataType& dataType) { int64_t value = 0; dataType.decode(_stream, value); - _propertyReference.setLongValue(value); + _propertyNode.setLongValue(value); } virtual void apply(const HLAUInt64DataType& dataType) { uint64_t value = 0; dataType.decode(_stream, value); - _propertyReference.setLongValue(value); + _propertyNode.setLongValue(value); } virtual void apply(const HLAFloat32DataType& dataType) { float value = 0; dataType.decode(_stream, value); - _propertyReference.setFloatValue(value); + _propertyNode.setFloatValue(value); } virtual void apply(const HLAFloat64DataType& dataType) { double value = 0; dataType.decode(_stream, value); - _propertyReference.setDoubleValue(value); + _propertyNode.setDoubleValue(value); + } + +protected: + SGPropertyNode& _propertyNode; +}; + +class HLAPropertyDataElement::ScalarEncodeVisitor : public HLADataTypeEncodeVisitor { +public: + ScalarEncodeVisitor(HLAEncodeStream& stream, const SGPropertyNode& propertyNode) : + HLADataTypeEncodeVisitor(stream), + _propertyNode(propertyNode) + { } + virtual ~ScalarEncodeVisitor() + { } + + virtual void apply(const HLAInt8DataType& dataType) + { + dataType.encode(_stream, _propertyNode.getIntValue()); + } + virtual void apply(const HLAUInt8DataType& dataType) + { + dataType.encode(_stream, _propertyNode.getIntValue()); + } + virtual void apply(const HLAInt16DataType& dataType) + { + dataType.encode(_stream, _propertyNode.getIntValue()); + } + virtual void apply(const HLAUInt16DataType& dataType) + { + dataType.encode(_stream, _propertyNode.getIntValue()); + } + virtual void apply(const HLAInt32DataType& dataType) + { + dataType.encode(_stream, _propertyNode.getIntValue()); + } + virtual void apply(const HLAUInt32DataType& dataType) + { + dataType.encode(_stream, _propertyNode.getIntValue()); } + virtual void apply(const HLAInt64DataType& dataType) + { + dataType.encode(_stream, _propertyNode.getLongValue()); + } + virtual void apply(const HLAUInt64DataType& dataType) + { + dataType.encode(_stream, _propertyNode.getLongValue()); + } + virtual void apply(const HLAFloat32DataType& dataType) + { + dataType.encode(_stream, _propertyNode.getFloatValue()); + } + virtual void apply(const HLAFloat64DataType& dataType) + { + dataType.encode(_stream, _propertyNode.getDoubleValue()); + } + +protected: + const SGPropertyNode& _propertyNode; +}; + +class HLAPropertyDataElement::ScalarDataElement : public HLADataElement { +public: + ScalarDataElement(const HLABasicDataType* dataType, SGPropertyNode* propertyNode); + virtual ~ScalarDataElement(); + + virtual bool encode(HLAEncodeStream& stream) const; + virtual bool decode(HLADecodeStream& stream); + + virtual const HLADataType* getDataType() const; + virtual bool setDataType(const HLADataType* dataType); + +private: + SGSharedPtr _dataType; + SGSharedPtr _propertyNode; +}; + +HLAPropertyDataElement::ScalarDataElement::ScalarDataElement(const HLABasicDataType* dataType, SGPropertyNode* propertyNode) : + _dataType(dataType), + _propertyNode(propertyNode) +{ +} + +HLAPropertyDataElement::ScalarDataElement::~ScalarDataElement() +{ +} + +bool +HLAPropertyDataElement::ScalarDataElement::encode(HLAEncodeStream& stream) const +{ + ScalarEncodeVisitor visitor(stream, *_propertyNode); + _dataType->accept(visitor); + return true; +} + +bool +HLAPropertyDataElement::ScalarDataElement::decode(HLADecodeStream& stream) +{ + ScalarDecodeVisitor visitor(stream, *_propertyNode); + _dataType->accept(visitor); + return true; +} + +const HLADataType* +HLAPropertyDataElement::ScalarDataElement::getDataType() const +{ + return _dataType.get(); +} + +bool +HLAPropertyDataElement::ScalarDataElement::setDataType(const HLADataType* dataType) +{ + if (!dataType) + return false; + const HLABasicDataType* basicDataType = dataType->toBasicDataType(); + if (!basicDataType) + return false; + _dataType = basicDataType; + return true; +} + + +class HLAPropertyDataElement::StringDecodeVisitor : public HLADataTypeDecodeVisitor { +public: + StringDecodeVisitor(HLADecodeStream& stream, SGPropertyNode& propertyNode) : + HLADataTypeDecodeVisitor(stream), + _propertyNode(propertyNode) + { } virtual void apply(const HLAFixedArrayDataType& dataType) { @@ -99,113 +230,303 @@ public: dataType.getElementDataType()->accept(visitor); value.push_back(visitor.getValue()); } - _propertyReference.setStringValue(value); + _propertyNode.setStringValue(value); } virtual void apply(const HLAVariableArrayDataType& dataType) { - HLATemplateDecodeVisitor numElementsVisitor(_stream); + HLATemplateDecodeVisitor numElementsVisitor(_stream); dataType.getSizeDataType()->accept(numElementsVisitor); - unsigned numElements = numElementsVisitor.getValue(); + std::string::size_type numElements = numElementsVisitor.getValue(); std::string value; value.reserve(numElements); - for (unsigned i = 0; i < numElements; ++i) { + for (std::string::size_type i = 0; i < numElements; ++i) { HLATemplateDecodeVisitor visitor(_stream); dataType.getElementDataType()->accept(visitor); value.push_back(visitor.getValue()); } - _propertyReference.setStringValue(value); + _propertyNode.setStringValue(value); } protected: - HLAPropertyReference& _propertyReference; + SGPropertyNode& _propertyNode; }; -class HLAPropertyDataElement::EncodeVisitor : public HLADataTypeEncodeVisitor { +class HLAPropertyDataElement::StringEncodeVisitor : public HLADataTypeEncodeVisitor { public: - EncodeVisitor(HLAEncodeStream& stream, const HLAPropertyReference& propertyReference) : + StringEncodeVisitor(HLAEncodeStream& stream, const SGPropertyNode& propertyNode) : HLADataTypeEncodeVisitor(stream), - _propertyReference(propertyReference) + _propertyNode(propertyNode) { } + virtual void apply(const HLAFixedArrayDataType& dataType) + { + unsigned numElements = dataType.getNumElements(); + std::string value = _propertyNode.getStringValue(); + for (unsigned i = 0; i < numElements; ++i) { + if (i < value.size()) { + HLATemplateEncodeVisitor visitor(_stream, value[i]); + dataType.getElementDataType()->accept(visitor); + } else { + HLADataTypeEncodeVisitor visitor(_stream); + dataType.getElementDataType()->accept(visitor); + } + } + } + + virtual void apply(const HLAVariableArrayDataType& dataType) + { + std::string value = _propertyNode.getStringValue(); + HLATemplateEncodeVisitor numElementsVisitor(_stream, value.size()); + dataType.getSizeDataType()->accept(numElementsVisitor); + for (unsigned i = 0; i < value.size(); ++i) { + HLATemplateEncodeVisitor visitor(_stream, value[i]); + dataType.getElementDataType()->accept(visitor); + } + } + +protected: + const SGPropertyNode& _propertyNode; +}; + +class HLAPropertyDataElement::StringDataElement : public HLADataElement { +public: + StringDataElement(const HLAArrayDataType* dataType, SGPropertyNode* propertyNode); + virtual ~StringDataElement(); + + virtual bool encode(HLAEncodeStream& stream) const; + virtual bool decode(HLADecodeStream& stream); + + virtual const HLADataType* getDataType() const; + virtual bool setDataType(const HLADataType* dataType); + +private: + SGSharedPtr _dataType; + SGSharedPtr _propertyNode; +}; + +HLAPropertyDataElement::StringDataElement::StringDataElement(const HLAArrayDataType* dataType, SGPropertyNode* propertyNode) : + _dataType(dataType), + _propertyNode(propertyNode) +{ +} + +HLAPropertyDataElement::StringDataElement::~StringDataElement() +{ +} + +bool +HLAPropertyDataElement::StringDataElement::encode(HLAEncodeStream& stream) const +{ + StringEncodeVisitor visitor(stream, *_propertyNode); + _dataType->accept(visitor); + return true; +} + +bool +HLAPropertyDataElement::StringDataElement::decode(HLADecodeStream& stream) +{ + StringDecodeVisitor visitor(stream, *_propertyNode); + _dataType->accept(visitor); + return true; +} + +const HLADataType* +HLAPropertyDataElement::StringDataElement::getDataType() const +{ + return _dataType.get(); +} + +bool +HLAPropertyDataElement::StringDataElement::setDataType(const HLADataType* dataType) +{ + if (!dataType) + return false; + const HLAArrayDataType* arrayDataType = dataType->toArrayDataType(); + if (!arrayDataType) + return false; + const HLADataType* elementDataType = arrayDataType->getElementDataType(); + if (!elementDataType) + return false; + if (!elementDataType->toBasicDataType()) + return false; + _dataType = arrayDataType; + return true; +} + +class HLAPropertyDataElement::DataElementFactoryVisitor : public HLADataTypeVisitor { +public: + DataElementFactoryVisitor(SGPropertyNode* propertyNode) : + _propertyNode(propertyNode) + { } + virtual ~DataElementFactoryVisitor() + { } + + virtual void apply(const HLADataType& dataType) + { + 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) { - dataType.encode(_stream, _propertyReference.getIntValue()); + _dataElement = new ScalarDataElement(&dataType, _propertyNode.get()); } virtual void apply(const HLAUInt8DataType& dataType) { - dataType.encode(_stream, _propertyReference.getIntValue()); + _dataElement = new ScalarDataElement(&dataType, _propertyNode.get()); } virtual void apply(const HLAInt16DataType& dataType) { - dataType.encode(_stream, _propertyReference.getIntValue()); + _dataElement = new ScalarDataElement(&dataType, _propertyNode.get()); } virtual void apply(const HLAUInt16DataType& dataType) { - dataType.encode(_stream, _propertyReference.getIntValue()); + _dataElement = new ScalarDataElement(&dataType, _propertyNode.get()); } virtual void apply(const HLAInt32DataType& dataType) { - dataType.encode(_stream, _propertyReference.getIntValue()); + _dataElement = new ScalarDataElement(&dataType, _propertyNode.get()); } virtual void apply(const HLAUInt32DataType& dataType) { - dataType.encode(_stream, _propertyReference.getIntValue()); + _dataElement = new ScalarDataElement(&dataType, _propertyNode.get()); } virtual void apply(const HLAInt64DataType& dataType) { - dataType.encode(_stream, _propertyReference.getLongValue()); + _dataElement = new ScalarDataElement(&dataType, _propertyNode.get()); } virtual void apply(const HLAUInt64DataType& dataType) { - dataType.encode(_stream, _propertyReference.getLongValue()); + _dataElement = new ScalarDataElement(&dataType, _propertyNode.get()); } virtual void apply(const HLAFloat32DataType& dataType) { - dataType.encode(_stream, _propertyReference.getFloatValue()); + _dataElement = new ScalarDataElement(&dataType, _propertyNode.get()); } virtual void apply(const HLAFloat64DataType& dataType) { - dataType.encode(_stream, _propertyReference.getDoubleValue()); + _dataElement = new ScalarDataElement(&dataType, _propertyNode.get()); } + class ArrayDataElementFactory : public HLAArrayDataElement::DataElementFactory { + public: + ArrayDataElementFactory(SGPropertyNode* propertyNode) : + _propertyNode(propertyNode) + { } + virtual HLADataElement* createElement(const HLAArrayDataElement& element, unsigned index) + { + const HLADataType* dataType = element.getElementDataType(); + if (!dataType) + return 0; + + SGPropertyNode* parent = _propertyNode->getParent(); + DataElementFactoryVisitor visitor(parent->getChild(_propertyNode->getNameString(), index, true)); + dataType->accept(visitor); + return visitor.getDataElement(); + } + private: + SGSharedPtr _propertyNode; + }; + virtual void apply(const HLAFixedArrayDataType& dataType) { - unsigned numElements = dataType.getNumElements(); - std::string value = _propertyReference.getStringValue(); - for (unsigned i = 0; i < numElements; ++i) { - if (i < value.size()) { - HLATemplateEncodeVisitor visitor(_stream, value[i]); - dataType.getElementDataType()->accept(visitor); - } else { - HLADataTypeEncodeVisitor visitor(_stream); - dataType.getElementDataType()->accept(visitor); - } + if (dataType.getIsString()) { + _dataElement = new StringDataElement(&dataType, _propertyNode.get()); + } else { + SGSharedPtr arrayDataElement; + arrayDataElement = new HLAArrayDataElement(&dataType); + arrayDataElement->setDataElementFactory(new ArrayDataElementFactory(_propertyNode.get())); + arrayDataElement->setNumElements(dataType.getNumElements()); + _dataElement = arrayDataElement; } } virtual void apply(const HLAVariableArrayDataType& dataType) { - std::string value = _propertyReference.getStringValue(); - HLATemplateEncodeVisitor numElementsVisitor(_stream, value.size()); - dataType.getSizeDataType()->accept(numElementsVisitor); - for (unsigned i = 0; i < value.size(); ++i) { - HLATemplateEncodeVisitor visitor(_stream, value[i]); - dataType.getElementDataType()->accept(visitor); + if (dataType.getIsString()) { + _dataElement = new StringDataElement(&dataType, _propertyNode.get()); + } else { + SGSharedPtr arrayDataElement; + arrayDataElement = new HLAArrayDataElement(&dataType); + arrayDataElement->setDataElementFactory(new ArrayDataElementFactory(_propertyNode.get())); + _dataElement = arrayDataElement; } } -protected: - const HLAPropertyReference& _propertyReference; + virtual void apply(const HLAEnumeratedDataType& dataType) + { + _dataElement = new ScalarDataElement(dataType.getRepresentation(), _propertyNode.get()); + } + + virtual void apply(const HLAFixedRecordDataType& dataType) + { + SGSharedPtr recordDataElement; + recordDataElement = new HLAFixedRecordDataElement(&dataType); + + unsigned numFields = dataType.getNumFields(); + for (unsigned i = 0; i < numFields; ++i) { + DataElementFactoryVisitor visitor(_propertyNode->getChild(dataType.getFieldName(i), 0, true)); + dataType.getFieldDataType(i)->accept(visitor); + recordDataElement->setField(i, visitor._dataElement.get()); + } + + _dataElement = recordDataElement; + } + + class VariantDataElementFactory : public HLAVariantDataElement::DataElementFactory { + public: + VariantDataElementFactory(SGPropertyNode* propertyNode) : + _propertyNode(propertyNode) + { } + 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; + DataElementFactoryVisitor visitor(_propertyNode->getChild(dataType->getAlternativeName(index), 0, true)); + alternativeDataType->accept(visitor); + return visitor.getDataElement(); + } + private: + SGSharedPtr _propertyNode; + }; + + virtual void apply(const HLAVariantDataType& dataType) + { + SGSharedPtr variantDataElement; + variantDataElement = new HLAVariantDataElement(&dataType); + variantDataElement->setDataElementFactory(new VariantDataElementFactory(_propertyNode.get())); + _dataElement = variantDataElement; + } + + HLADataElement* getDataElement() + { return _dataElement.release(); } + +private: + SGSharedPtr _propertyNode; + SGSharedPtr _dataElement; }; -HLAPropertyDataElement::HLAPropertyDataElement(HLAPropertyReference* propertyReference) : - _propertyReference(propertyReference) +HLAPropertyDataElement::HLAPropertyDataElement() { } -HLAPropertyDataElement::HLAPropertyDataElement(const simgear::HLADataType* dataType, HLAPropertyReference* propertyReference) : - _dataType(dataType), - _propertyReference(propertyReference) +HLAPropertyDataElement::HLAPropertyDataElement(SGPropertyNode* propertyNode) +{ + setPropertyNode(propertyNode); +} + +HLAPropertyDataElement::HLAPropertyDataElement(const HLADataType* dataType, SGPropertyNode* propertyNode) : + _dataType(dataType) +{ + setPropertyNode(propertyNode); +} + +HLAPropertyDataElement::HLAPropertyDataElement(const HLADataType* dataType) : + _dataType(dataType) { } @@ -216,31 +537,37 @@ HLAPropertyDataElement::~HLAPropertyDataElement() bool HLAPropertyDataElement::encode(HLAEncodeStream& stream) const { - if (!_dataType.valid()) - return false; - if (_propertyReference.valid()) { - EncodeVisitor visitor(stream, *_propertyReference); - _dataType->accept(visitor); + if (_dataElement.valid()) { + return _dataElement->encode(stream); } else { + if (!_dataType.valid()) + return false; HLADataTypeEncodeVisitor visitor(stream); _dataType->accept(visitor); + return true; } - return true; } bool HLAPropertyDataElement::decode(HLADecodeStream& stream) { - if (!_dataType.valid()) + if (_dataElement.valid()) { + return _dataElement->decode(stream); + } else if (!_dataType.valid()) { + // We cant do anything if the data type is not valid return false; - if (_propertyReference.valid()) { - DecodeVisitor visitor(stream, *_propertyReference); - _dataType->accept(visitor); } else { - HLADataTypeDecodeVisitor visitor(stream); + HLADataElementFactoryVisitor visitor; _dataType->accept(visitor); + _dataElement = visitor.getDataElement(); + if (_dataElement.valid()) { + return _dataElement->decode(stream); + } else { + HLADataTypeDecodeVisitor visitor(stream); + _dataType->accept(visitor); + return true; + } } - return true; } const HLADataType* @@ -252,18 +579,52 @@ HLAPropertyDataElement::getDataType() const bool HLAPropertyDataElement::setDataType(const HLADataType* dataType) { - if (dataType->toBasicDataType()) { - _dataType = dataType; - return true; - } else { - const HLAArrayDataType* arrayDataType = dataType->toArrayDataType(); - if (arrayDataType && arrayDataType->getElementDataType() && - arrayDataType->getElementDataType()->toBasicDataType()) { - _dataType = dataType; - return true; + _dataType = dataType; + if (_dataType.valid() && _propertyNode.valid()) + _dataElement = createDataElement(_dataType, _propertyNode); + return true; +} + +void +HLAPropertyDataElement::setPropertyNode(SGPropertyNode* propertyNode) +{ + _propertyNode = propertyNode; + if (_dataType.valid() && _propertyNode.valid()) + _dataElement = createDataElement(_dataType, _propertyNode); +} + +SGPropertyNode* +HLAPropertyDataElement::getPropertyNode() +{ + return _propertyNode.get(); +} + +const SGPropertyNode* +HLAPropertyDataElement::getPropertyNode() const +{ + return _propertyNode.get(); +} + +HLADataElement* +HLAPropertyDataElement::createDataElement(const SGSharedPtr& dataType, + const SGSharedPtr& propertyNode) +{ + DataElementFactoryVisitor visitor(propertyNode); + dataType->accept(visitor); + SGSharedPtr dataElement = visitor.getDataElement(); + + // Copy over the content of the previous data element if there is any. + if (_dataElement.valid()) { + // FIXME is encode/decode the right tool here?? + RTIData data; + HLAEncodeStream encodeStream(data); + if (_dataElement->encode(encodeStream)) { + HLADecodeStream decodeStream(data); + dataElement->decode(decodeStream); } } - return false; + + return dataElement.release(); } } // namespace simgear