+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)
+ {
+ _dataElement = new ScalarDataElement(&dataType, _propertyNode.get());
+ }
+ virtual void apply(const HLAUInt8DataType& dataType)
+ {
+ _dataElement = new ScalarDataElement(&dataType, _propertyNode.get());
+ }
+ virtual void apply(const HLAInt16DataType& dataType)
+ {
+ _dataElement = new ScalarDataElement(&dataType, _propertyNode.get());
+ }
+ virtual void apply(const HLAUInt16DataType& dataType)
+ {
+ _dataElement = new ScalarDataElement(&dataType, _propertyNode.get());
+ }
+ virtual void apply(const HLAInt32DataType& dataType)
+ {
+ _dataElement = new ScalarDataElement(&dataType, _propertyNode.get());
+ }
+ virtual void apply(const HLAUInt32DataType& dataType)
+ {
+ _dataElement = new ScalarDataElement(&dataType, _propertyNode.get());
+ }
+ virtual void apply(const HLAInt64DataType& dataType)
+ {
+ _dataElement = new ScalarDataElement(&dataType, _propertyNode.get());
+ }
+ virtual void apply(const HLAUInt64DataType& dataType)
+ {
+ _dataElement = new ScalarDataElement(&dataType, _propertyNode.get());
+ }
+ virtual void apply(const HLAFloat32DataType& dataType)
+ {
+ _dataElement = new ScalarDataElement(&dataType, _propertyNode.get());
+ }
+ virtual void apply(const HLAFloat64DataType& dataType)
+ {
+ _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<SGPropertyNode> _propertyNode;
+ };
+
+ virtual void apply(const HLAFixedArrayDataType& dataType)
+ {
+ if (dataType.getIsString()) {
+ _dataElement = new StringDataElement(&dataType, _propertyNode.get());
+ } else {
+ SGSharedPtr<HLAArrayDataElement> arrayDataElement;
+ arrayDataElement = new HLAArrayDataElement(&dataType);
+ arrayDataElement->setDataElementFactory(new ArrayDataElementFactory(_propertyNode.get()));
+ arrayDataElement->setNumElements(dataType.getNumElements());
+ _dataElement = arrayDataElement;
+ }
+ }
+
+ virtual void apply(const HLAVariableArrayDataType& dataType)
+ {
+ if (dataType.getIsString()) {
+ _dataElement = new StringDataElement(&dataType, _propertyNode.get());
+ } else {
+ SGSharedPtr<HLAArrayDataElement> arrayDataElement;
+ arrayDataElement = new HLAArrayDataElement(&dataType);
+ arrayDataElement->setDataElementFactory(new ArrayDataElementFactory(_propertyNode.get()));
+ _dataElement = arrayDataElement;
+ }
+ }
+
+ virtual void apply(const HLAEnumeratedDataType& dataType)
+ {
+ _dataElement = new ScalarDataElement(dataType.getRepresentation(), _propertyNode.get());
+ }
+
+ virtual void apply(const HLAFixedRecordDataType& dataType)
+ {
+ SGSharedPtr<HLAFixedRecordDataElement> 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<SGPropertyNode> _propertyNode;
+ };
+
+ virtual void apply(const HLAVariantDataType& dataType)
+ {
+ SGSharedPtr<HLAVariantDataElement> variantDataElement;
+ variantDataElement = new HLAVariantDataElement(&dataType);
+ variantDataElement->setDataElementFactory(new VariantDataElementFactory(_propertyNode.get()));
+ _dataElement = variantDataElement;
+ }
+
+ HLADataElement* getDataElement()
+ { return _dataElement.release(); }
+
+private:
+ SGSharedPtr<SGPropertyNode> _propertyNode;
+ SGSharedPtr<HLADataElement> _dataElement;
+};
+