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:
david
2002-07-06 13:19:02 +00:00
parent d8b7e5b8fd
commit 90e8287f43
2 changed files with 32 additions and 12 deletions
+22 -12
View File
@@ -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
+10
View File
@@ -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;