]> git.mxchange.org Git - simgear.git/commitdiff
Made SGPropertyNode::getPath extremely efficient: it now caches its
authordavid <david>
Sat, 6 Jul 2002 13:19:02 +0000 (13:19 +0000)
committerdavid <david>
Sat, 6 Jul 2002 13:19:02 +0000 (13:19 +0000)
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();
  }

simgear/misc/props.cxx
simgear/misc/props.hxx

index 0abecaa11675fcb20bbd42d4c1b573a5ea6e8122..7da884a70e4638d489527b8c18d8cf555c053ead 100644 (file)
@@ -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
index b4a429974c5b5ea485a10d4ed47b2f474949ccb9..ca61a2f2fbad38a18f2a0c732a340a1a87628811 100644 (file)
@@ -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;