From c3c97f2956d3546d28ad7f036462dd2401a3bab1 Mon Sep 17 00:00:00 2001 From: James Turner Date: Sat, 20 Nov 2010 03:31:42 -0800 Subject: [PATCH] Shrink PropertyObjectBase by a pointer, don't pull exception header into the header. --- simgear/props/propertyObject.cxx | 42 +++++++++++++++++++++------ simgear/props/propertyObject.hxx | 32 ++++++++++---------- simgear/props/propertyObject_test.cxx | 21 ++++++++++++++ 3 files changed, 71 insertions(+), 24 deletions(-) diff --git a/simgear/props/propertyObject.cxx b/simgear/props/propertyObject.cxx index 0685ae91..3eea0ac2 100644 --- a/simgear/props/propertyObject.cxx +++ b/simgear/props/propertyObject.cxx @@ -21,6 +21,8 @@ #include "propertyObject.hxx" +#include + namespace simgear { @@ -32,7 +34,6 @@ void PropertyObjectBase::setDefaultRoot(SGPropertyNode* aRoot) } PropertyObjectBase::PropertyObjectBase(const PropertyObjectBase& aOther) : - _base(aOther._base), _path(aOther._path), _prop(aOther._prop) { @@ -40,33 +41,56 @@ PropertyObjectBase::PropertyObjectBase(const PropertyObjectBase& aOther) : } 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 diff --git a/simgear/props/propertyObject.hxx b/simgear/props/propertyObject.hxx index 7aeb0337..33921c7a 100644 --- a/simgear/props/propertyObject.hxx +++ b/simgear/props/propertyObject.hxx @@ -19,7 +19,6 @@ #define SG_PROPERTY_OBJECT #include -#include namespace simgear { @@ -37,9 +36,20 @@ public: 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; }; @@ -94,12 +104,7 @@ public: // conversion operators operator T () const { - SGPropertyNode* n = node(); - if (!n) { - throw sg_exception("read of undefined property:", _path); - } - - return n->getValue(); + return getOrThrow()->getValue(); } T operator=(const T& aValue) @@ -142,12 +147,7 @@ public: 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) @@ -193,9 +193,11 @@ private: } // of namespace simgear +/* typedef simgear::PropertyObject SGPropObjDouble; typedef simgear::PropertyObject SGPropObjBool; typedef simgear::PropertyObject SGPropObjString; typedef simgear::PropertyObject SGPropObjInt; +*/ #endif diff --git a/simgear/props/propertyObject_test.cxx b/simgear/props/propertyObject_test.cxx index 38e925e8..2b2ee1ec 100644 --- a/simgear/props/propertyObject_test.cxx +++ b/simgear/props/propertyObject_test.cxx @@ -7,12 +7,15 @@ #include "propertyObject.hxx" +#include + using std::cout; using std::cerr; using std::endl; using namespace simgear; + SGPropertyNode* testRoot = NULL; bool testBasic() @@ -41,6 +44,23 @@ bool testBasic() return true; } +void testRelative() +{ + SGPropertyNode* n = testRoot->getNode("a"); + assert(n); + + PropertyObject a1(n, "bar"); + assert(a1 == 1234); + + PropertyObject a5(n, "some/child/path"); + a5 = 4321; + assert(n->getIntValue("some/child/path") == 4321); + + SGPropertyNode* m = testRoot->getNode("a/alice"); + PropertyObject a4(m); + assert(a4 == "aaaa"); +} + void testString() { PropertyObject sp("a/alice"); @@ -145,6 +165,7 @@ int main(int argc, char* argv[]) return EXIT_FAILURE; } + testRelative(); testReadMissing(); testString(); testAssignment(); -- 2.39.5