Shrink PropertyObjectBase by a pointer, don't pull exception header into the header.

This commit is contained in:
James Turner
2010-11-20 03:31:42 -08:00
parent ac535de2fa
commit c3c97f2956
3 changed files with 71 additions and 24 deletions

View File

@@ -21,6 +21,8 @@
#include "propertyObject.hxx"
#include <simgear/structure/exception.hxx>
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

View File

@@ -19,7 +19,6 @@
#define SG_PROPERTY_OBJECT
#include <simgear/props/props.hxx>
#include <simgear/structure/exception.hxx>
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<T>();
return getOrThrow()->getValue<T>();
}
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<double> SGPropObjDouble;
typedef simgear::PropertyObject<bool> SGPropObjBool;
typedef simgear::PropertyObject<std::string> SGPropObjString;
typedef simgear::PropertyObject<long> SGPropObjInt;
*/
#endif

View File

@@ -7,12 +7,15 @@
#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()
@@ -41,6 +44,23 @@ 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");
@@ -145,6 +165,7 @@ int main(int argc, char* argv[])
return EXIT_FAILURE;
}
testRelative();
testReadMissing();
testString();
testAssignment();