Added some new functionality to the property manager:

1. Nodes cache previous relative paths so that they do not have to
parse the paths each time.

2. There are new getNode() methods that include indices, so that users
do not have to sprintf to a buffer to iterate through indexed nodes.
This commit is contained in:
david 2002-01-19 03:06:22 +00:00
parent c3b21e143c
commit a6251606dd
2 changed files with 63 additions and 8 deletions

View File

@ -299,6 +299,7 @@ SGPropertyNode::SGPropertyNode ()
: _name(""), : _name(""),
_index(0), _index(0),
_parent(0), _parent(0),
_path_cache(0),
_type(NONE), _type(NONE),
_tied(false), _tied(false),
_attr(READ|WRITE) _attr(READ|WRITE)
@ -313,6 +314,7 @@ SGPropertyNode::SGPropertyNode (const SGPropertyNode &node)
: _name(node._name), : _name(node._name),
_index(node._index), _index(node._index),
_parent(0), // don't copy the parent _parent(0), // don't copy the parent
_path_cache(0),
_type(node._type), _type(node._type),
_tied(node._tied), _tied(node._tied),
_attr(node._attr) _attr(node._attr)
@ -351,8 +353,13 @@ SGPropertyNode::SGPropertyNode (const SGPropertyNode &node)
*/ */
SGPropertyNode::SGPropertyNode (const string &name, SGPropertyNode::SGPropertyNode (const string &name,
int index, SGPropertyNode * parent) int index, SGPropertyNode * parent)
: _name(name), _index(index), _parent(parent), _type(NONE), : _name(name),
_tied(false), _attr(READ|WRITE) _index(index),
_parent(parent),
_path_cache(0),
_type(NONE),
_tied(false),
_attr(READ|WRITE)
{ {
} }
@ -365,6 +372,7 @@ SGPropertyNode::~SGPropertyNode ()
for (int i = 0; i < (int)_children.size(); i++) { for (int i = 0; i < (int)_children.size(); i++) {
delete _children[i]; delete _children[i];
} }
delete _path_cache;
clear_value(); clear_value();
} }
@ -1278,21 +1286,42 @@ SGPropertyNode::getRootNode () const
SGPropertyNode * SGPropertyNode *
SGPropertyNode::getNode (const string &relative_path, bool create) SGPropertyNode::getNode (const string &relative_path, bool create)
{
if (_path_cache == 0)
_path_cache = new cache_map;
SGPropertyNode * result = (*_path_cache)[relative_path];
if (result == 0) {
vector<PathComponent> components;
parse_path(relative_path, components);
result = find_node(this, components, 0, create);
(*_path_cache)[relative_path] = result;
}
return result;
}
SGPropertyNode *
SGPropertyNode::getNode (const string &relative_path, int index, bool create)
{ {
vector<PathComponent> components; vector<PathComponent> components;
parse_path(relative_path, components); parse_path(relative_path, components);
if (components.size() > 0)
components[components.size()-1].index = index;
return find_node(this, components, 0, create); return find_node(this, components, 0, create);
} }
const SGPropertyNode * const SGPropertyNode *
SGPropertyNode::getNode (const string &relative_path) const SGPropertyNode::getNode (const string &relative_path) const
{ {
vector<PathComponent> components; return ((SGPropertyNode *)this)->getNode(relative_path, false);
parse_path(relative_path, components);
// FIXME: cast away const
return find_node((SGPropertyNode *)this, components, 0, false);
} }
const SGPropertyNode *
SGPropertyNode::getNode (const string &relative_path, int index) const
{
return ((SGPropertyNode *)this)->getNode(relative_path, index, false);
}
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////

View File

@ -18,10 +18,12 @@
#include STL_STRING #include STL_STRING
#include <vector> #include <vector>
#include <map>
#include STL_IOSTREAM #include STL_IOSTREAM
SG_USING_STD(string); SG_USING_STD(string);
SG_USING_STD(vector); SG_USING_STD(vector);
SG_USING_STD(map);
#if !defined(SG_HAVE_NATIVE_SGI_COMPILERS) #if !defined(SG_HAVE_NATIVE_SGI_COMPILERS)
SG_USING_STD(istream); SG_USING_STD(istream);
SG_USING_STD(ostream); SG_USING_STD(ostream);
@ -688,12 +690,36 @@ public:
SGPropertyNode * getNode (const string &relative_path, bool create = false); SGPropertyNode * getNode (const string &relative_path, bool create = false);
/**
* Get a pointer to another node by relative path.
*
* This method leaves the index off the last member of the path,
* so that the user can specify it separately (and save some
* string building). For example, getNode("/bar[1]/foo", 3) is
* exactly equivalent to getNode("bar[1]/foo[3]"). The index
* provided overrides any given in the path itself for the last
* component.
*/
SGPropertyNode * getNode (const string &relative_path, int index,
bool create = false);
/** /**
* Get a const pointer to another node by relative path. * Get a const pointer to another node by relative path.
*/ */
const SGPropertyNode * getNode (const string &relative_path) const; const SGPropertyNode * getNode (const string &relative_path) const;
/**
* Get a const pointer to another node by relative path.
*
* This method leaves the index off the last member of the path,
* so that the user can specify it separate.
*/
const SGPropertyNode * getNode (const string &relative_path,
int index) const;
// //
// Access Mode. // Access Mode.
// //
@ -1062,8 +1088,8 @@ private:
int _index; int _index;
SGPropertyNode * _parent; SGPropertyNode * _parent;
vector<SGPropertyNode *> _children; vector<SGPropertyNode *> _children;
typedef map<const string,SGPropertyNode *> cache_map;
cache_map * _path_cache;
Type _type; Type _type;
bool _tied; bool _tied;
int _attr; int _attr;