Add a HLADataElementVisitor implementation.

This commit is contained in:
Mathias Froehlich 2011-10-30 10:23:59 +01:00
parent d36e13e8ed
commit be70656745
17 changed files with 245 additions and 143 deletions

View File

@ -7,6 +7,7 @@ set(HLA_HEADERS
HLABasicDataElement.hxx HLABasicDataElement.hxx
HLABasicDataType.hxx HLABasicDataType.hxx
HLADataElement.hxx HLADataElement.hxx
HLADataElementVisitor.hxx
HLADataType.hxx HLADataType.hxx
HLADataTypeVisitor.hxx HLADataTypeVisitor.hxx
HLAEnumeratedDataElement.hxx HLAEnumeratedDataElement.hxx

View File

@ -19,6 +19,8 @@
#include <simgear/debug/logstream.hxx> #include <simgear/debug/logstream.hxx>
#include "HLADataElementVisitor.hxx"
namespace simgear { namespace simgear {
HLAAbstractArrayDataElement::HLAAbstractArrayDataElement(const HLAArrayDataType* dataType) : HLAAbstractArrayDataElement::HLAAbstractArrayDataElement(const HLAArrayDataType* dataType) :
@ -30,6 +32,18 @@ HLAAbstractArrayDataElement::~HLAAbstractArrayDataElement()
{ {
} }
void
HLAAbstractArrayDataElement::accept(HLADataElementVisitor& visitor)
{
visitor.apply(*this);
}
void
HLAAbstractArrayDataElement::accept(HLAConstDataElementVisitor& visitor) const
{
visitor.apply(*this);
}
bool bool
HLAAbstractArrayDataElement::decode(HLADecodeStream& stream) HLAAbstractArrayDataElement::decode(HLADecodeStream& stream)
{ {

View File

@ -33,6 +33,9 @@ public:
HLAAbstractArrayDataElement(const HLAArrayDataType* dataType); HLAAbstractArrayDataElement(const HLAArrayDataType* dataType);
virtual ~HLAAbstractArrayDataElement(); virtual ~HLAAbstractArrayDataElement();
virtual void accept(HLADataElementVisitor& visitor);
virtual void accept(HLAConstDataElementVisitor& visitor) const;
virtual bool decode(HLADecodeStream& stream); virtual bool decode(HLADecodeStream& stream);
virtual bool encode(HLAEncodeStream& stream) const; virtual bool encode(HLAEncodeStream& stream) const;

View File

@ -17,6 +17,7 @@
#include "HLABasicDataElement.hxx" #include "HLABasicDataElement.hxx"
#include "HLADataElementVisitor.hxx"
#include "HLADataTypeVisitor.hxx" #include "HLADataTypeVisitor.hxx"
namespace simgear { namespace simgear {
@ -30,6 +31,18 @@ HLABasicDataElement::~HLABasicDataElement()
{ {
} }
void
HLABasicDataElement::accept(HLADataElementVisitor& visitor)
{
visitor.apply(*this);
}
void
HLABasicDataElement::accept(HLAConstDataElementVisitor& visitor) const
{
visitor.apply(*this);
}
const HLABasicDataType* const HLABasicDataType*
HLABasicDataElement::getDataType() const HLABasicDataElement::getDataType() const
{ {

View File

@ -28,6 +28,12 @@ public:
HLABasicDataElement(const HLABasicDataType* dataType); HLABasicDataElement(const HLABasicDataType* dataType);
virtual ~HLABasicDataElement(); virtual ~HLABasicDataElement();
virtual void accept(HLADataElementVisitor& visitor);
virtual void accept(HLAConstDataElementVisitor& visitor) const;
virtual bool encode(HLAEncodeStream& stream) const = 0;
virtual bool decode(HLADecodeStream& stream) = 0;
virtual const HLABasicDataType* getDataType() const; virtual const HLABasicDataType* getDataType() const;
virtual bool setDataType(const HLADataType* dataType); virtual bool setDataType(const HLADataType* dataType);
void setDataType(const HLABasicDataType* dataType); void setDataType(const HLABasicDataType* dataType);
@ -41,6 +47,7 @@ class HLAAbstract##type##DataElement : public HLABasicDataElement { \
public: \ public: \
HLAAbstract##type##DataElement(const HLABasicDataType* dataType = 0); \ HLAAbstract##type##DataElement(const HLABasicDataType* dataType = 0); \
virtual ~HLAAbstract##type##DataElement(); \ virtual ~HLAAbstract##type##DataElement(); \
\
virtual bool encode(HLAEncodeStream& stream) const; \ virtual bool encode(HLAEncodeStream& stream) const; \
virtual bool decode(HLADecodeStream& stream); \ virtual bool decode(HLADecodeStream& stream); \
\ \

View File

@ -19,6 +19,8 @@
#include <simgear/debug/logstream.hxx> #include <simgear/debug/logstream.hxx>
#include "HLADataElementVisitor.hxx"
namespace simgear { namespace simgear {
HLADataElement::PathElement::Data::~Data() HLADataElement::PathElement::Data::~Data()
@ -129,6 +131,18 @@ HLADataElement::~HLADataElement()
{ {
} }
void
HLADataElement::accept(HLADataElementVisitor& visitor)
{
visitor.apply(*this);
}
void
HLADataElement::accept(HLAConstDataElementVisitor& visitor) const
{
visitor.apply(*this);
}
std::string std::string
HLADataElement::toString(const Path& path) HLADataElement::toString(const Path& path)
{ {

View File

@ -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 // This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public // modify it under the terms of the GNU Library General Public
@ -30,10 +30,16 @@ class SGTimeStamp;
namespace simgear { namespace simgear {
class HLADataElementVisitor;
class HLAConstDataElementVisitor;
class HLADataElement : public SGReferenced { class HLADataElement : public SGReferenced {
public: public:
virtual ~HLADataElement(); virtual ~HLADataElement();
virtual void accept(HLADataElementVisitor& visitor) = 0;
virtual void accept(HLAConstDataElementVisitor& visitor) const = 0;
virtual bool encode(HLAEncodeStream& stream) const = 0; virtual bool encode(HLAEncodeStream& stream) const = 0;
virtual bool decode(HLADecodeStream& stream) = 0; virtual bool decode(HLADecodeStream& stream) = 0;

View File

@ -0,0 +1,57 @@
// 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

View File

@ -19,6 +19,8 @@
#include <simgear/debug/logstream.hxx> #include <simgear/debug/logstream.hxx>
#include "HLADataElementVisitor.hxx"
namespace simgear { namespace simgear {
HLAAbstractEnumeratedDataElement::HLAAbstractEnumeratedDataElement(const HLAEnumeratedDataType* dataType) : HLAAbstractEnumeratedDataElement::HLAAbstractEnumeratedDataElement(const HLAEnumeratedDataType* dataType) :
@ -30,6 +32,18 @@ HLAAbstractEnumeratedDataElement::~HLAAbstractEnumeratedDataElement()
{ {
} }
void
HLAAbstractEnumeratedDataElement::accept(HLADataElementVisitor& visitor)
{
visitor.apply(*this);
}
void
HLAAbstractEnumeratedDataElement::accept(HLAConstDataElementVisitor& visitor) const
{
visitor.apply(*this);
}
bool bool
HLAAbstractEnumeratedDataElement::decode(HLADecodeStream& stream) HLAAbstractEnumeratedDataElement::decode(HLADecodeStream& stream)
{ {

View File

@ -28,6 +28,9 @@ public:
HLAAbstractEnumeratedDataElement(const HLAEnumeratedDataType* dataType); HLAAbstractEnumeratedDataElement(const HLAEnumeratedDataType* dataType);
virtual ~HLAAbstractEnumeratedDataElement(); virtual ~HLAAbstractEnumeratedDataElement();
virtual void accept(HLADataElementVisitor& visitor);
virtual void accept(HLAConstDataElementVisitor& visitor) const;
virtual bool decode(HLADecodeStream& stream); virtual bool decode(HLADecodeStream& stream);
virtual bool encode(HLAEncodeStream& stream) const; virtual bool encode(HLAEncodeStream& stream) const;

View File

@ -20,6 +20,8 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <simgear/debug/logstream.hxx> #include <simgear/debug/logstream.hxx>
#include "HLADataElementVisitor.hxx"
#include "HLADataTypeVisitor.hxx" #include "HLADataTypeVisitor.hxx"
namespace simgear { namespace simgear {
@ -33,6 +35,18 @@ HLAAbstractFixedRecordDataElement::~HLAAbstractFixedRecordDataElement()
{ {
} }
void
HLAAbstractFixedRecordDataElement::accept(HLADataElementVisitor& visitor)
{
visitor.apply(*this);
}
void
HLAAbstractFixedRecordDataElement::accept(HLAConstDataElementVisitor& visitor) const
{
visitor.apply(*this);
}
bool bool
HLAAbstractFixedRecordDataElement::decode(HLADecodeStream& stream) HLAAbstractFixedRecordDataElement::decode(HLADecodeStream& stream)
{ {

View File

@ -30,6 +30,9 @@ public:
HLAAbstractFixedRecordDataElement(const HLAFixedRecordDataType* dataType); HLAAbstractFixedRecordDataElement(const HLAFixedRecordDataType* dataType);
virtual ~HLAAbstractFixedRecordDataElement(); virtual ~HLAAbstractFixedRecordDataElement();
virtual void accept(HLADataElementVisitor& visitor);
virtual void accept(HLAConstDataElementVisitor& visitor) const;
virtual bool decode(HLADecodeStream& stream); virtual bool decode(HLADecodeStream& stream);
virtual bool encode(HLAEncodeStream& stream) const; virtual bool encode(HLAEncodeStream& stream) const;

View File

@ -18,6 +18,8 @@
#include "HLAPropertyDataElement.hxx" #include "HLAPropertyDataElement.hxx"
#include "HLAArrayDataElement.hxx" #include "HLAArrayDataElement.hxx"
#include "HLABasicDataElement.hxx"
#include "HLADataElementVisitor.hxx"
#include "HLADataTypeVisitor.hxx" #include "HLADataTypeVisitor.hxx"
#include "HLAFixedRecordDataElement.hxx" #include "HLAFixedRecordDataElement.hxx"
#include "HLAVariantDataElement.hxx" #include "HLAVariantDataElement.hxx"
@ -152,7 +154,7 @@ protected:
const SGPropertyNode& _propertyNode; const SGPropertyNode& _propertyNode;
}; };
class HLAPropertyDataElement::ScalarDataElement : public HLADataElement { class HLAPropertyDataElement::ScalarDataElement : public HLABasicDataElement {
public: public:
ScalarDataElement(const HLABasicDataType* dataType, SGPropertyNode* propertyNode); ScalarDataElement(const HLABasicDataType* dataType, SGPropertyNode* propertyNode);
virtual ~ScalarDataElement(); virtual ~ScalarDataElement();
@ -160,16 +162,12 @@ public:
virtual bool encode(HLAEncodeStream& stream) const; virtual bool encode(HLAEncodeStream& stream) const;
virtual bool decode(HLADecodeStream& stream); virtual bool decode(HLADecodeStream& stream);
virtual const HLADataType* getDataType() const;
virtual bool setDataType(const HLADataType* dataType);
private: private:
SGSharedPtr<const HLABasicDataType> _dataType;
SGSharedPtr<SGPropertyNode> _propertyNode; SGSharedPtr<SGPropertyNode> _propertyNode;
}; };
HLAPropertyDataElement::ScalarDataElement::ScalarDataElement(const HLABasicDataType* dataType, SGPropertyNode* propertyNode) : HLAPropertyDataElement::ScalarDataElement::ScalarDataElement(const HLABasicDataType* dataType, SGPropertyNode* propertyNode) :
_dataType(dataType), HLABasicDataElement(dataType),
_propertyNode(propertyNode) _propertyNode(propertyNode)
{ {
} }
@ -194,162 +192,64 @@ HLAPropertyDataElement::ScalarDataElement::decode(HLADecodeStream& stream)
return true; return true;
} }
const HLADataType* class HLAPropertyDataElement::StringDataElement : public HLAStringDataElement {
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 {
public: public:
StringDataElement(const HLAArrayDataType* dataType, SGPropertyNode* propertyNode); StringDataElement(const HLAArrayDataType* dataType, SGPropertyNode* propertyNode);
virtual ~StringDataElement(); virtual ~StringDataElement();
virtual bool encode(HLAEncodeStream& stream) const; virtual bool decodeElement(HLADecodeStream& stream, unsigned i);
virtual bool decode(HLADecodeStream& stream);
virtual const HLADataType* getDataType() const; class Listener : public SGPropertyChangeListener {
virtual bool setDataType(const HLADataType* dataType); public:
Listener(StringDataElement* stringDataElement);
virtual ~Listener();
virtual void valueChanged (SGPropertyNode * node);
private:
StringDataElement* _stringDataElement;
};
private: private:
SGSharedPtr<const HLAArrayDataType> _dataType;
SGSharedPtr<SGPropertyNode> _propertyNode; SGSharedPtr<SGPropertyNode> _propertyNode;
Listener* _listener;
}; };
HLAPropertyDataElement::StringDataElement::StringDataElement(const HLAArrayDataType* dataType, SGPropertyNode* propertyNode) : HLAPropertyDataElement::StringDataElement::Listener::Listener(StringDataElement* stringDataElement) :
_dataType(dataType), _stringDataElement(stringDataElement)
_propertyNode(propertyNode)
{ {
} }
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() HLAPropertyDataElement::StringDataElement::~StringDataElement()
{ {
_propertyNode->removeChangeListener(_listener);
delete _listener;
_listener = 0;
} }
bool bool
HLAPropertyDataElement::StringDataElement::encode(HLAEncodeStream& stream) const HLAPropertyDataElement::StringDataElement::decodeElement(HLADecodeStream& stream, unsigned i)
{ {
StringEncodeVisitor visitor(stream, *_propertyNode); if (!HLAStringDataElement::decodeElement(stream, i))
_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; return false;
const HLAArrayDataType* arrayDataType = dataType->toArrayDataType(); if (i + 1 == getValue().size())
if (!arrayDataType) _propertyNode->setStringValue(getValue());
return false;
const HLADataType* elementDataType = arrayDataType->getElementDataType();
if (!elementDataType)
return false;
if (!elementDataType->toBasicDataType())
return false;
_dataType = arrayDataType;
return true; return true;
} }
@ -534,6 +434,38 @@ HLAPropertyDataElement::~HLAPropertyDataElement()
{ {
} }
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 bool
HLAPropertyDataElement::encode(HLAEncodeStream& stream) const HLAPropertyDataElement::encode(HLAEncodeStream& stream) const
{ {

View File

@ -31,6 +31,9 @@ public:
HLAPropertyDataElement(const HLADataType* dataType); HLAPropertyDataElement(const HLADataType* dataType);
virtual ~HLAPropertyDataElement(); virtual ~HLAPropertyDataElement();
virtual void accept(HLADataElementVisitor& visitor);
virtual void accept(HLAConstDataElementVisitor& visitor) const;
virtual bool encode(HLAEncodeStream& stream) const; virtual bool encode(HLAEncodeStream& stream) const;
virtual bool decode(HLADecodeStream& stream); virtual bool decode(HLADecodeStream& stream);

View File

@ -19,6 +19,8 @@
#include <simgear/debug/logstream.hxx> #include <simgear/debug/logstream.hxx>
#include "HLADataElementVisitor.hxx"
namespace simgear { namespace simgear {
HLAAbstractVariantDataElement::HLAAbstractVariantDataElement(const HLAVariantDataType* dataType) : HLAAbstractVariantDataElement::HLAAbstractVariantDataElement(const HLAVariantDataType* dataType) :
@ -30,6 +32,18 @@ HLAAbstractVariantDataElement::~HLAAbstractVariantDataElement()
{ {
} }
void
HLAAbstractVariantDataElement::accept(HLADataElementVisitor& visitor)
{
visitor.apply(*this);
}
void
HLAAbstractVariantDataElement::accept(HLAConstDataElementVisitor& visitor) const
{
visitor.apply(*this);
}
bool bool
HLAAbstractVariantDataElement::decode(HLADecodeStream& stream) HLAAbstractVariantDataElement::decode(HLADecodeStream& stream)
{ {

View File

@ -30,6 +30,9 @@ public:
HLAAbstractVariantDataElement(const HLAVariantDataType* dataType); HLAAbstractVariantDataElement(const HLAVariantDataType* dataType);
virtual ~HLAAbstractVariantDataElement(); virtual ~HLAAbstractVariantDataElement();
virtual void accept(HLADataElementVisitor& visitor);
virtual void accept(HLAConstDataElementVisitor& visitor) const;
virtual bool decode(HLADecodeStream& stream); virtual bool decode(HLADecodeStream& stream);
virtual bool encode(HLAEncodeStream& stream) const; virtual bool encode(HLAEncodeStream& stream) const;

View File

@ -11,6 +11,7 @@ libsghla_a_HEADERS = \
HLABasicDataElement.hxx \ HLABasicDataElement.hxx \
HLABasicDataType.hxx \ HLABasicDataType.hxx \
HLADataElement.hxx \ HLADataElement.hxx \
HLADataElementVisitor.hxx \
HLADataType.hxx \ HLADataType.hxx \
HLADataTypeVisitor.hxx \ HLADataTypeVisitor.hxx \
HLAEnumeratedDataElement.hxx \ HLAEnumeratedDataElement.hxx \