Made SGPropertyNode::getPath extremely efficient: it now caches its
result, so after the first call for any node, it simply tests and
returns a pointer. This also fixes the problem of buffer conflicts
with make_string.
Added SGPropertyNode::hasChild(const char * name, int index = 0) to
provide a syntactically-cleaner way to test for the existence of a
child node, i.e.
for (int i = 0; i < 9; i++) {
if (node->hasChild("foo", i))
foo[i] = node->getChild("foo", i)->getDoubleValue();
}
This commit is contained in:
+22
-12
@@ -635,6 +635,7 @@ SGPropertyNode::SGPropertyNode ()
|
|||||||
: _name(copy_string("")),
|
: _name(copy_string("")),
|
||||||
_index(0),
|
_index(0),
|
||||||
_parent(0),
|
_parent(0),
|
||||||
|
_path(0),
|
||||||
_path_cache(0),
|
_path_cache(0),
|
||||||
_type(NONE),
|
_type(NONE),
|
||||||
_tied(false),
|
_tied(false),
|
||||||
@@ -652,6 +653,7 @@ SGPropertyNode::SGPropertyNode ()
|
|||||||
SGPropertyNode::SGPropertyNode (const SGPropertyNode &node)
|
SGPropertyNode::SGPropertyNode (const SGPropertyNode &node)
|
||||||
: _index(node._index),
|
: _index(node._index),
|
||||||
_parent(0), // don't copy the parent
|
_parent(0), // don't copy the parent
|
||||||
|
_path(0),
|
||||||
_path_cache(0),
|
_path_cache(0),
|
||||||
_type(node._type),
|
_type(node._type),
|
||||||
_tied(node._tied),
|
_tied(node._tied),
|
||||||
@@ -735,6 +737,7 @@ SGPropertyNode::SGPropertyNode (const char * name,
|
|||||||
SGPropertyNode * parent)
|
SGPropertyNode * parent)
|
||||||
: _index(index),
|
: _index(index),
|
||||||
_parent(parent),
|
_parent(parent),
|
||||||
|
_path(0),
|
||||||
_path_cache(0),
|
_path_cache(0),
|
||||||
_type(NONE),
|
_type(NONE),
|
||||||
_tied(false),
|
_tied(false),
|
||||||
@@ -753,6 +756,7 @@ SGPropertyNode::SGPropertyNode (const char * name,
|
|||||||
SGPropertyNode::~SGPropertyNode ()
|
SGPropertyNode::~SGPropertyNode ()
|
||||||
{
|
{
|
||||||
delete [] _name;
|
delete [] _name;
|
||||||
|
delete _path;
|
||||||
delete _path_cache;
|
delete _path_cache;
|
||||||
clear_value();
|
clear_value();
|
||||||
delete _listeners;
|
delete _listeners;
|
||||||
@@ -930,19 +934,25 @@ SGPropertyNode::removeChild (const char * name, int index, bool keep)
|
|||||||
const char *
|
const char *
|
||||||
SGPropertyNode::getPath (bool simplify) const
|
SGPropertyNode::getPath (bool simplify) const
|
||||||
{
|
{
|
||||||
if (_parent == 0)
|
// Calculate the complete path only once.
|
||||||
return "";
|
if (_path == 0) {
|
||||||
|
string path;
|
||||||
string path = _parent->getPath(simplify);
|
if (_parent == 0) {
|
||||||
path += '/';
|
path = "";
|
||||||
path += _name;
|
} else {
|
||||||
if (_index != 0 || !simplify) {
|
path = _parent->getPath(simplify);
|
||||||
char buffer[128];
|
path += '/';
|
||||||
sprintf(buffer, "[%d]", _index);
|
path += _name;
|
||||||
path += buffer;
|
if (_index != 0 || !simplify) {
|
||||||
|
char buffer[64];
|
||||||
|
sprintf(buffer, "[%d]", _index);
|
||||||
|
path += buffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_path = copy_string(path.c_str());
|
||||||
}
|
}
|
||||||
strncpy(_buffer, path.c_str(), MAX_STRING_LEN);
|
|
||||||
return _buffer;
|
return _path;
|
||||||
}
|
}
|
||||||
|
|
||||||
SGPropertyNode::Type
|
SGPropertyNode::Type
|
||||||
|
|||||||
@@ -674,6 +674,15 @@ public:
|
|||||||
const SGPropertyNode * getChild (int position) const;
|
const SGPropertyNode * getChild (int position) const;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test whether a named child exists.
|
||||||
|
*/
|
||||||
|
bool hasChild (const char * name, int index = 0) const
|
||||||
|
{
|
||||||
|
return (getChild(name, index) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a child node by name and index.
|
* Get a child node by name and index.
|
||||||
*/
|
*/
|
||||||
@@ -1236,6 +1245,7 @@ private:
|
|||||||
SGPropertyNode * _parent;
|
SGPropertyNode * _parent;
|
||||||
vector<SGPropertyNode_ptr> _children;
|
vector<SGPropertyNode_ptr> _children;
|
||||||
vector<SGPropertyNode_ptr> _removedChildren;
|
vector<SGPropertyNode_ptr> _removedChildren;
|
||||||
|
mutable char * _path;
|
||||||
hash_table * _path_cache;
|
hash_table * _path_cache;
|
||||||
Type _type;
|
Type _type;
|
||||||
bool _tied;
|
bool _tied;
|
||||||
|
|||||||
Reference in New Issue
Block a user