--- /dev/null
+// 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
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifndef HLADataElementVisitor_hxx
+#define HLADataElementVisitor_hxx
+
+namespace simgear {
+
+class HLABasicDataElement;
+class HLAAbstractEnumeratedDataElement;
+class HLAAbstractFixedRecordDataElement;
+class HLAAbstractArrayDataElement;
+class HLAAbstractVariantDataElement;
+
+class HLADataElementVisitor {
+public:
+ virtual ~HLADataElementVisitor() {}
+
+ virtual void apply(HLADataElement&);
+
+ virtual void apply(HLABasicDataElement&);
+ virtual void apply(HLAAbstractEnumeratedDataElement&);
+ virtual void apply(HLAAbstractArrayDataElement&);
+ virtual void apply(HLAAbstractFixedRecordDataElement&);
+ virtual void apply(HLAAbstractVariantDataElement&);
+};
+
+class HLAConstDataElementVisitor {
+public:
+ virtual ~HLAConstDataElementVisitor() {}
+
+ virtual void apply(const HLADataElement&);
+
+ virtual void apply(const HLABasicDataElement&);
+ virtual void apply(const HLAAbstractEnumeratedDataElement&);
+ virtual void apply(const HLAAbstractArrayDataElement&);
+ virtual void apply(const HLAAbstractFixedRecordDataElement&);
+ virtual void apply(const HLAAbstractVariantDataElement&);
+};
+
+}
+
+#endif
#include "HLAPropertyDataElement.hxx"
#include "HLAArrayDataElement.hxx"
+#include "HLABasicDataElement.hxx"
+#include "HLADataElementVisitor.hxx"
#include "HLADataTypeVisitor.hxx"
#include "HLAFixedRecordDataElement.hxx"
#include "HLAVariantDataElement.hxx"
const SGPropertyNode& _propertyNode;
};
-class HLAPropertyDataElement::ScalarDataElement : public HLADataElement {
+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);
- virtual const HLADataType* getDataType() const;
- virtual bool setDataType(const HLADataType* dataType);
-
private:
- SGSharedPtr<const HLABasicDataType> _dataType;
SGSharedPtr<SGPropertyNode> _propertyNode;
};
HLAPropertyDataElement::ScalarDataElement::ScalarDataElement(const HLABasicDataType* dataType, SGPropertyNode* propertyNode) :
- _dataType(dataType),
+ HLABasicDataElement(dataType),
_propertyNode(propertyNode)
{
}
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)
- {
- unsigned numElements = dataType.getNumElements();
- std::string value;
- value.reserve(numElements);
- for (unsigned i = 0; i < numElements; ++i) {
- HLATemplateDecodeVisitor<char> visitor(_stream);
- dataType.getElementDataType()->accept(visitor);
- value.push_back(visitor.getValue());
- }
- _propertyNode.setStringValue(value);
- }
- virtual void apply(const HLAVariableArrayDataType& dataType)
- {
- HLATemplateDecodeVisitor<std::string::size_type> numElementsVisitor(_stream);
- dataType.getSizeDataType()->accept(numElementsVisitor);
- std::string::size_type numElements = numElementsVisitor.getValue();
- std::string value;
- value.reserve(numElements);
- for (std::string::size_type i = 0; i < numElements; ++i) {
- HLATemplateDecodeVisitor<char> visitor(_stream);
- dataType.getElementDataType()->accept(visitor);
- value.push_back(visitor.getValue());
- }
- _propertyNode.setStringValue(value);
- }
-
-protected:
- SGPropertyNode& _propertyNode;
-};
-
-class HLAPropertyDataElement::StringEncodeVisitor : public HLADataTypeEncodeVisitor {
-public:
- StringEncodeVisitor(HLAEncodeStream& stream, const SGPropertyNode& propertyNode) :
- HLADataTypeEncodeVisitor(stream),
- _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<char> 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<std::string::size_type> numElementsVisitor(_stream, value.size());
- dataType.getSizeDataType()->accept(numElementsVisitor);
- for (unsigned i = 0; i < value.size(); ++i) {
- HLATemplateEncodeVisitor<char> visitor(_stream, value[i]);
- dataType.getElementDataType()->accept(visitor);
- }
- }
-
-protected:
- const SGPropertyNode& _propertyNode;
-};
-
-class HLAPropertyDataElement::StringDataElement : public HLADataElement {
+class HLAPropertyDataElement::StringDataElement : public HLAStringDataElement {
public:
StringDataElement(const HLAArrayDataType* dataType, SGPropertyNode* propertyNode);
virtual ~StringDataElement();
- virtual bool encode(HLAEncodeStream& stream) const;
- virtual bool decode(HLADecodeStream& stream);
+ virtual bool decodeElement(HLADecodeStream& stream, unsigned i);
- virtual const HLADataType* getDataType() const;
- virtual bool setDataType(const HLADataType* dataType);
+ class Listener : public SGPropertyChangeListener {
+ public:
+ Listener(StringDataElement* stringDataElement);
+ virtual ~Listener();
+ virtual void valueChanged (SGPropertyNode * node);
+ private:
+ StringDataElement* _stringDataElement;
+ };
private:
- SGSharedPtr<const HLAArrayDataType> _dataType;
SGSharedPtr<SGPropertyNode> _propertyNode;
+ Listener* _listener;
};
-HLAPropertyDataElement::StringDataElement::StringDataElement(const HLAArrayDataType* dataType, SGPropertyNode* propertyNode) :
- _dataType(dataType),
- _propertyNode(propertyNode)
+HLAPropertyDataElement::StringDataElement::Listener::Listener(StringDataElement* stringDataElement) :
+ _stringDataElement(stringDataElement)
{
}
-HLAPropertyDataElement::StringDataElement::~StringDataElement()
+HLAPropertyDataElement::StringDataElement::Listener::~Listener()
{
}
-bool
-HLAPropertyDataElement::StringDataElement::encode(HLAEncodeStream& stream) const
+void
+HLAPropertyDataElement::StringDataElement::Listener::valueChanged (SGPropertyNode * node)
{
- StringEncodeVisitor visitor(stream, *_propertyNode);
- _dataType->accept(visitor);
- return true;
+ _stringDataElement->setValue(node->getStringValue());
}
-bool
-HLAPropertyDataElement::StringDataElement::decode(HLADecodeStream& stream)
+HLAPropertyDataElement::StringDataElement::StringDataElement(const HLAArrayDataType* dataType, SGPropertyNode* propertyNode) :
+ HLAStringDataElement(dataType),
+ _propertyNode(propertyNode),
+ _listener(new Listener(this))
{
- StringDecodeVisitor visitor(stream, *_propertyNode);
- _dataType->accept(visitor);
- return true;
+ _propertyNode->addChangeListener(_listener, true);
}
-const HLADataType*
-HLAPropertyDataElement::StringDataElement::getDataType() const
+HLAPropertyDataElement::StringDataElement::~StringDataElement()
{
- return _dataType.get();
+ _propertyNode->removeChangeListener(_listener);
+ delete _listener;
+ _listener = 0;
}
bool
-HLAPropertyDataElement::StringDataElement::setDataType(const HLADataType* dataType)
+HLAPropertyDataElement::StringDataElement::decodeElement(HLADecodeStream& stream, unsigned i)
{
- if (!dataType)
- return false;
- const HLAArrayDataType* arrayDataType = dataType->toArrayDataType();
- if (!arrayDataType)
- return false;
- const HLADataType* elementDataType = arrayDataType->getElementDataType();
- if (!elementDataType)
+ if (!HLAStringDataElement::decodeElement(stream, i))
return false;
- if (!elementDataType->toBasicDataType())
- return false;
- _dataType = arrayDataType;
+ if (i + 1 == getValue().size())
+ _propertyNode->setStringValue(getValue());
return true;
}
{
}
+void
+HLAPropertyDataElement::accept(HLADataElementVisitor& visitor)
+{
+ if (_dataElement.valid()) {
+ visitor.apply(*_dataElement);
+ } else {
+ // We cant do anything if the data type is not valid
+ if (_dataType.valid()) {
+ HLADataElementFactoryVisitor factoryVisitor;
+ _dataType->accept(factoryVisitor);
+ _dataElement = factoryVisitor.getDataElement();
+ if (_dataElement.valid()) {
+ visitor.apply(*_dataElement);
+ } else {
+ HLADataElement::accept(visitor);
+ }
+ } else {
+ HLADataElement::accept(visitor);
+ }
+ }
+}
+
+void
+HLAPropertyDataElement::accept(HLAConstDataElementVisitor& visitor) const
+{
+ if (_dataElement.valid()) {
+ visitor.apply(*_dataElement);
+ } else {
+ HLADataElement::accept(visitor);
+ }
+}
+
bool
HLAPropertyDataElement::encode(HLAEncodeStream& stream) const
{