#include "propertyObject.hxx"
+#include <simgear/structure/exception.hxx>
+
namespace simgear
{
}
PropertyObjectBase::PropertyObjectBase(const PropertyObjectBase& aOther) :
- _base(aOther._base),
_path(aOther._path),
_prop(aOther._prop)
{
}
PropertyObjectBase::PropertyObjectBase(const char* aChild) :
- _base(NULL),
_path(aChild),
_prop(NULL)
{
}
PropertyObjectBase::PropertyObjectBase(SGPropertyNode* aNode, const char* aChild) :
- _base(aNode),
_path(aChild),
- _prop(NULL)
+ _prop(aNode)
{
}
SGPropertyNode* PropertyObjectBase::node(bool aCreate) const
{
- if (_prop) {
+ if (_path == NULL) { // already resolved
return _prop;
}
- _prop = _base ? _base : static_defaultRoot;
- if (_path) {
- _prop = _prop->getNode(_path, aCreate);
- }
+ SGPropertyNode* r = _prop ? _prop : static_defaultRoot;
+ _prop = r->getNode(_path, aCreate);
+ if (_prop) {
+ // resolve worked, we will cache from now on, so clear _path
+ _path = NULL;
+ }
+
return _prop;
}
+SGPropertyNode* PropertyObjectBase::getOrThrow() const
+{
+ SGPropertyNode* n = node(false);
+ if (!n) {
+ std::string path;
+ if (_prop) {
+ path = _prop->getPath();
+ if (_path) {
+ path += '/';
+ }
+ }
+
+ if (_path) {
+ path += _path;
+ }
+
+ throw sg_exception("Unknown property:" + path);
+ }
+
+ return n;
+}
+
} // of namespace simgear
#define SG_PROPERTY_OBJECT
#include <simgear/props/props.hxx>
-#include <simgear/structure/exception.hxx>
namespace simgear
{
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;
};
// conversion operators
operator T () const
{
- SGPropertyNode* n = node();
- if (!n) {
- throw sg_exception("read of undefined property:", _path);
- }
-
- return n->getValue<T>();
+ return getOrThrow()->getValue<T>();
}
T operator=(const T& aValue)
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)
} // 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
#include "propertyObject.hxx"
+#include <simgear/structure/exception.hxx>
+
using std::cout;
using std::cerr;
using std::endl;
using namespace simgear;
+
SGPropertyNode* testRoot = NULL;
bool testBasic()
return true;
}
+void testRelative()
+{
+ SGPropertyNode* n = testRoot->getNode("a");
+ assert(n);
+
+ PropertyObject<int> a1(n, "bar");
+ assert(a1 == 1234);
+
+ PropertyObject<int> a5(n, "some/child/path");
+ a5 = 4321;
+ assert(n->getIntValue("some/child/path") == 4321);
+
+ SGPropertyNode* m = testRoot->getNode("a/alice");
+ PropertyObject<std::string> a4(m);
+ assert(a4 == "aaaa");
+}
+
void testString()
{
PropertyObject<std::string> sp("a/alice");
return EXIT_FAILURE;
}
+ testRelative();
testReadMissing();
testString();
testAssignment();