+protected:
+ const SGPropertyNode& _propertyNode;
+};
+
+class HLAPropertyDataElement::ScalarDataElement : public HLABasicDataElement {
+public:
+ ScalarDataElement(const HLABasicDataType* dataType, SGPropertyNode* propertyNode);
+ virtual ~ScalarDataElement();
+
+ virtual bool encode(HLAEncodeStream& stream) const;
+ virtual bool decode(HLADecodeStream& stream);
+
+private:
+ SGSharedPtr<SGPropertyNode> _propertyNode;
+};
+
+HLAPropertyDataElement::ScalarDataElement::ScalarDataElement(const HLABasicDataType* dataType, SGPropertyNode* propertyNode) :
+ HLABasicDataElement(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;
+}
+
+class HLAPropertyDataElement::StringDataElement : public HLAStringDataElement {
+public:
+ StringDataElement(const HLAArrayDataType* dataType, SGPropertyNode* propertyNode);
+ virtual ~StringDataElement();
+
+ virtual bool decodeElement(HLADecodeStream& stream, unsigned i);
+
+ class Listener : public SGPropertyChangeListener {
+ public:
+ Listener(StringDataElement* stringDataElement);
+ virtual ~Listener();
+ virtual void valueChanged (SGPropertyNode * node);
+ private:
+ StringDataElement* _stringDataElement;
+ };
+
+private:
+ SGSharedPtr<SGPropertyNode> _propertyNode;
+ Listener* _listener;
+};
+
+HLAPropertyDataElement::StringDataElement::Listener::Listener(StringDataElement* stringDataElement) :
+ _stringDataElement(stringDataElement)
+{
+}
+
+HLAPropertyDataElement::StringDataElement::Listener::~Listener()
+{
+}
+
+void
+HLAPropertyDataElement::StringDataElement::Listener::valueChanged (SGPropertyNode * node)
+{
+ _stringDataElement->setValue(node->getStringValue());
+}
+
+HLAPropertyDataElement::StringDataElement::StringDataElement(const HLAArrayDataType* dataType, SGPropertyNode* propertyNode) :
+ HLAStringDataElement(dataType),
+ _propertyNode(propertyNode),
+ _listener(new Listener(this))
+{
+ _propertyNode->addChangeListener(_listener, true);
+}
+
+HLAPropertyDataElement::StringDataElement::~StringDataElement()
+{
+ _propertyNode->removeChangeListener(_listener);
+ delete _listener;
+ _listener = 0;
+}
+
+bool
+HLAPropertyDataElement::StringDataElement::decodeElement(HLADecodeStream& stream, unsigned i)
+{
+ if (!HLAStringDataElement::decodeElement(stream, i))
+ return false;
+ if (i + 1 == getValue().size())
+ _propertyNode->setStringValue(getValue());
+ 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;
+ };
+