269 lines
6.0 KiB
C++
269 lines
6.0 KiB
C++
// Copyright (C) 2010 James Turner - zakalawe@mac.com
|
|
//
|
|
// 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 SG_PROPERTY_OBJECT
|
|
#define SG_PROPERTY_OBJECT
|
|
|
|
#include <simgear/props/props.hxx>
|
|
|
|
namespace simgear
|
|
{
|
|
|
|
class PropertyObjectBase
|
|
{
|
|
public:
|
|
static void setDefaultRoot(SGPropertyNode* aRoot);
|
|
|
|
PropertyObjectBase();
|
|
|
|
PropertyObjectBase(const PropertyObjectBase& aOther);
|
|
|
|
PropertyObjectBase(const char* aChild);
|
|
|
|
PropertyObjectBase(SGPropertyNode* aNode, const char* aChild = NULL);
|
|
|
|
SGPropertyNode* node(bool aCreate) const;
|
|
|
|
/**
|
|
* Resolve the property node, or throw an exception if it could not
|
|
* be resolved.
|
|
*/
|
|
SGPropertyNode* getOrThrow() const;
|
|
protected:
|
|
mutable const char* _path;
|
|
|
|
/**
|
|
* Important - if _path is NULL, this is the actual prop.
|
|
* If path is non-NULL, this is the parent which path should be resolved
|
|
* against (or NULL, if _path is absolute). Use node() instead of accessing
|
|
* this directly, and the above is handled automatically.
|
|
*/
|
|
mutable SGPropertyNode* _prop;
|
|
};
|
|
|
|
template <typename T>
|
|
class PropertyObject : PropertyObjectBase
|
|
{
|
|
public:
|
|
PropertyObject()
|
|
{}
|
|
|
|
/**
|
|
* Create from path relative to the default root, and option default value
|
|
*/
|
|
explicit PropertyObject(const char* aChild) :
|
|
PropertyObjectBase(aChild)
|
|
{ }
|
|
|
|
/**
|
|
* Create from a node, with optional relative path
|
|
*/
|
|
explicit PropertyObject(SGPropertyNode* aNode, const char* aChild = NULL) :
|
|
PropertyObjectBase(aNode, aChild)
|
|
{
|
|
|
|
}
|
|
|
|
// copy-constructor
|
|
PropertyObject(const PropertyObject<T>& aOther) :
|
|
PropertyObjectBase(aOther)
|
|
{
|
|
}
|
|
|
|
// create() form creates the property immediately
|
|
static PropertyObject<T> create(const char* aPath, T aValue)
|
|
{
|
|
PropertyObject<T> p(aPath);
|
|
p = aValue;
|
|
return p;
|
|
}
|
|
|
|
static PropertyObject<T> create(SGPropertyNode_ptr aNode)
|
|
{
|
|
PropertyObject<T> p(aNode);
|
|
return p;
|
|
}
|
|
|
|
static PropertyObject<T> create(SGPropertyNode* aNode, T aValue)
|
|
{
|
|
PropertyObject<T> p(aNode);
|
|
p = aValue;
|
|
return p;
|
|
}
|
|
|
|
static PropertyObject<T> create(SGPropertyNode* aNode, const char* aChild, T aValue)
|
|
{
|
|
PropertyObject<T> p(aNode, aChild);
|
|
p = aValue;
|
|
return p;
|
|
}
|
|
|
|
// conversion operators
|
|
operator T () const
|
|
{
|
|
return getOrThrow()->template getValue<T>();
|
|
}
|
|
|
|
T operator=(const T& aValue)
|
|
{
|
|
SGPropertyNode* n = PropertyObjectBase::node(true);
|
|
if( !n )
|
|
return aValue;
|
|
|
|
n->setValue<T>(aValue);
|
|
return aValue;
|
|
}
|
|
|
|
#define SG_DEF_ASSIGN_OP(op)\
|
|
T operator op##=(const T rhs)\
|
|
{\
|
|
SGPropertyNode* n = getOrThrow();\
|
|
T new_val = n->getValue<T>() op rhs;\
|
|
n->setValue<T>(new_val);\
|
|
return new_val;\
|
|
}
|
|
|
|
SG_DEF_ASSIGN_OP(+)
|
|
SG_DEF_ASSIGN_OP(-)
|
|
SG_DEF_ASSIGN_OP(*)
|
|
SG_DEF_ASSIGN_OP(/)
|
|
SG_DEF_ASSIGN_OP(%)
|
|
SG_DEF_ASSIGN_OP(>>)
|
|
SG_DEF_ASSIGN_OP(<<)
|
|
SG_DEF_ASSIGN_OP(&)
|
|
SG_DEF_ASSIGN_OP(^)
|
|
SG_DEF_ASSIGN_OP(|)
|
|
|
|
#undef SG_DEF_ASSIGN_OP
|
|
|
|
SGPropertyNode* node(bool aCreate = false) const
|
|
{
|
|
return PropertyObjectBase::node(aCreate);
|
|
}
|
|
}; // of template PropertyObject
|
|
|
|
|
|
// specialization for const char* / std::string
|
|
|
|
template <>
|
|
class PropertyObject<std::string> : PropertyObjectBase
|
|
{
|
|
public:
|
|
PropertyObject() = default;
|
|
|
|
explicit PropertyObject(const char* aChild) :
|
|
PropertyObjectBase(aChild)
|
|
{ }
|
|
|
|
|
|
|
|
explicit PropertyObject(SGPropertyNode* aNode, const char* aChild = NULL) :
|
|
PropertyObjectBase(aNode, aChild)
|
|
{
|
|
|
|
}
|
|
|
|
// copy-constructor
|
|
PropertyObject(const PropertyObject<std::string>& aOther) :
|
|
PropertyObjectBase(aOther)
|
|
{
|
|
}
|
|
|
|
// create form
|
|
static PropertyObject<std::string> create(const char* aPath, const std::string& aValue)
|
|
{
|
|
PropertyObject<std::string> p(aPath);
|
|
p = aValue;
|
|
return p;
|
|
}
|
|
|
|
static PropertyObject<std::string> create(SGPropertyNode_ptr aNode)
|
|
{
|
|
PropertyObject<std::string> p(aNode);
|
|
return p;
|
|
}
|
|
|
|
static PropertyObject<std::string> create(SGPropertyNode* aNode, const std::string& aValue)
|
|
{
|
|
PropertyObject<std::string> p(aNode);
|
|
p = aValue;
|
|
return p;
|
|
}
|
|
|
|
static PropertyObject<std::string> create(SGPropertyNode* aNode, const char* aChild, const std::string& aValue)
|
|
{
|
|
PropertyObject<std::string> p(aNode, aChild);
|
|
p = aValue;
|
|
return p;
|
|
}
|
|
|
|
|
|
operator std::string () const
|
|
{
|
|
return getOrThrow()->getStringValue();
|
|
}
|
|
|
|
const char* operator=(const char* aValue)
|
|
{
|
|
SGPropertyNode* n = PropertyObjectBase::node(true);
|
|
if (!n) {
|
|
return aValue;
|
|
}
|
|
|
|
n->setStringValue(aValue);
|
|
return aValue;
|
|
}
|
|
|
|
std::string operator=(const std::string& aValue)
|
|
{
|
|
SGPropertyNode* n = PropertyObjectBase::node(true);
|
|
if (!n) {
|
|
return aValue;
|
|
}
|
|
|
|
n->setStringValue(aValue);
|
|
return aValue;
|
|
}
|
|
|
|
bool operator==(const char* value) const
|
|
{
|
|
std::string s(*this);
|
|
return (s == value);
|
|
}
|
|
|
|
bool operator==(const std::string& value) const
|
|
{
|
|
std::string s(*this);
|
|
return (s == value);
|
|
}
|
|
|
|
SGPropertyNode* node(bool aCreate = false) const
|
|
{
|
|
return PropertyObjectBase::node(aCreate);
|
|
}
|
|
private:
|
|
};
|
|
|
|
} // of namespace simgear
|
|
|
|
typedef simgear::PropertyObject<double> SGPropObjDouble;
|
|
typedef simgear::PropertyObject<bool> SGPropObjBool;
|
|
typedef simgear::PropertyObject<std::string> SGPropObjString;
|
|
typedef simgear::PropertyObject<long> SGPropObjInt;
|
|
|
|
#endif
|