Shrink PropertyObjectBase by a pointer, don't pull exception header into the header.
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user