From: david Date: Sat, 6 Jul 2002 13:19:02 +0000 (+0000) Subject: Made SGPropertyNode::getPath extremely efficient: it now caches its X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=90e8287f43cf0f5e0da8e2404912df70a58e4e96;p=simgear.git 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(); } --- diff --git a/simgear/misc/props.cxx b/simgear/misc/props.cxx index 0abecaa1..7da884a7 100644 --- a/simgear/misc/props.cxx +++ b/simgear/misc/props.cxx @@ -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 diff --git a/simgear/misc/props.hxx b/simgear/misc/props.hxx index b4a42997..ca61a2f2 100644 --- a/simgear/misc/props.hxx +++ b/simgear/misc/props.hxx @@ -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 _children; vector _removedChildren; + mutable char * _path; hash_table * _path_cache; Type _type; bool _tied;