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:
parent
d8b7e5b8fd
commit
90e8287f43
@ -635,6 +635,7 @@ SGPropertyNode::SGPropertyNode ()
|
||||
: _name(copy_string("")),
|
||||
_index(0),
|
||||
_parent(0),
|
||||
_path(0),
|
||||
_path_cache(0),
|
||||
_type(NONE),
|
||||
_tied(false),
|
||||
@ -652,6 +653,7 @@ SGPropertyNode::SGPropertyNode ()
|
||||
SGPropertyNode::SGPropertyNode (const SGPropertyNode &node)
|
||||
: _index(node._index),
|
||||
_parent(0), // don't copy the parent
|
||||
_path(0),
|
||||
_path_cache(0),
|
||||
_type(node._type),
|
||||
_tied(node._tied),
|
||||
@ -735,6 +737,7 @@ SGPropertyNode::SGPropertyNode (const char * name,
|
||||
SGPropertyNode * parent)
|
||||
: _index(index),
|
||||
_parent(parent),
|
||||
_path(0),
|
||||
_path_cache(0),
|
||||
_type(NONE),
|
||||
_tied(false),
|
||||
@ -753,6 +756,7 @@ SGPropertyNode::SGPropertyNode (const char * name,
|
||||
SGPropertyNode::~SGPropertyNode ()
|
||||
{
|
||||
delete [] _name;
|
||||
delete _path;
|
||||
delete _path_cache;
|
||||
clear_value();
|
||||
delete _listeners;
|
||||
@ -930,19 +934,25 @@ SGPropertyNode::removeChild (const char * name, int index, bool keep)
|
||||
const char *
|
||||
SGPropertyNode::getPath (bool simplify) const
|
||||
{
|
||||
if (_parent == 0)
|
||||
return "";
|
||||
|
||||
string path = _parent->getPath(simplify);
|
||||
path += '/';
|
||||
path += _name;
|
||||
if (_index != 0 || !simplify) {
|
||||
char buffer[128];
|
||||
sprintf(buffer, "[%d]", _index);
|
||||
path += buffer;
|
||||
// Calculate the complete path only once.
|
||||
if (_path == 0) {
|
||||
string path;
|
||||
if (_parent == 0) {
|
||||
path = "";
|
||||
} else {
|
||||
path = _parent->getPath(simplify);
|
||||
path += '/';
|
||||
path += _name;
|
||||
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
|
||||
|
@ -674,6 +674,15 @@ public:
|
||||
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.
|
||||
*/
|
||||
@ -1236,6 +1245,7 @@ private:
|
||||
SGPropertyNode * _parent;
|
||||
vector<SGPropertyNode_ptr> _children;
|
||||
vector<SGPropertyNode_ptr> _removedChildren;
|
||||
mutable char * _path;
|
||||
hash_table * _path_cache;
|
||||
Type _type;
|
||||
bool _tied;
|
||||
|
Loading…
Reference in New Issue
Block a user