#define SG_PROPERTY_OBJECT
#include <simgear/props/props.hxx>
-#include <simgear/structure/exception.hxx>
namespace simgear
{
public:
static void setDefaultRoot(SGPropertyNode* aRoot);
+ PropertyObjectBase();
+
PropertyObjectBase(const PropertyObjectBase& aOther);
PropertyObjectBase(const char* aChild);
SGPropertyNode* node(bool aCreate) const;
+ /**
+ * Resolve the property node, or throw an exception if it could not
+ * be resolved.
+ */
+ SGPropertyNode* getOrThrow() const;
protected:
- SGPropertyNode* _base;
- const char* _path;
+ 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;
};
class PropertyObject : PropertyObjectBase
{
public:
+ PropertyObject()
+ {}
+
/**
* Create from path relative to the default root, and option default value
*/
- PropertyObject(const char* aChild) :
+ explicit PropertyObject(const char* aChild) :
PropertyObjectBase(aChild)
{ }
/**
* Create from a node, with optional relative path
*/
- PropertyObject(SGPropertyNode* aNode, const char* aChild = NULL) :
+ explicit PropertyObject(SGPropertyNode* aNode, const char* aChild = NULL) :
PropertyObjectBase(aNode, aChild)
{
// conversion operators
operator T () const
{
- SGPropertyNode* n = node();
- if (!n) {
- throw sg_exception("read of undefined property:", _path);
- }
-
- return n->getValue<T>();
+ return getOrThrow()->template getValue<T>();
}
T operator=(const T& aValue)
{
SGPropertyNode* n = PropertyObjectBase::node(true);
- if (!n) {
+ 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() const
{
return PropertyObjectBase::node(false);
class PropertyObject<std::string> : PropertyObjectBase
{
public:
- PropertyObject(const char* aChild) :
+ explicit PropertyObject(const char* aChild) :
PropertyObjectBase(aChild)
{ }
- PropertyObject(SGPropertyNode* aNode, const char* aChild = NULL) :
+ 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* 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
{
- SGPropertyNode* n = node();
- if (!n) {
- throw sg_exception("read of undefined property:", _path);
- }
-
- return n->getStringValue();
+ return getOrThrow()->getStringValue();
}
const char* operator=(const char* aValue)