-
-\f
-////////////////////////////////////////////////////////////////////////
-// Implementation of SGPropertyNode.
-////////////////////////////////////////////////////////////////////////
-
-
-/**
- * Utility function: given a value, find the property node.
- */
-static SGPropertyNode *
-find_node_by_value (SGPropertyNode * start_node, const SGValue * value)
-{
- if (start_node->getValue() == value) {
- return start_node;
- } else for (int i = 0; i < start_node->nChildren(); i++) {
- SGPropertyNode * child =
- find_node_by_value(start_node->getChild(i), value);
- if (child != 0)
- return child;
- }
- return 0;
-}
-
-
-/**
- * Default constructor: always creates a root node.
- */
-SGPropertyNode::SGPropertyNode ()
- : _value(0), _name(""), _index(0), _parent(0), _target(0)
-{
-}
-
-
-/**
- * Convenience constructor.
- */
-SGPropertyNode::SGPropertyNode (const string &name,
- int index, SGPropertyNode * parent)
- : _value(0), _name(name), _index(index), _parent(parent), _target(0)
-{
-}
-
-
-/**
- * Destructor.
- */
-SGPropertyNode::~SGPropertyNode ()
-{
- delete _value;
- for (int i = 0; i < (int)_children.size(); i++)
- delete _children[i];
-}
-
-
-/**
- * Get a value, optionally creating it if not present.
- */
-SGValue *
-SGPropertyNode::getValue (bool create)
-{
- if (_value == 0 && create)
- _value = new SGValue();
- return _value;
-}
-
-
-/**
- * Alias to another node.
- */
-bool
-SGPropertyNode::alias (SGPropertyNode * target)
-{
- if (_value == 0)
- _value = new SGValue();
- _target = target;
- return _value->alias(target->getValue(true));
-}
-
-
-/**
- * Alias to another node by path.
- */
-bool
-SGPropertyNode::alias (const string &path)
-{
- return alias(getNode(path, true));
-}
-
-
-/**
- * Remove an alias.
- */
-bool
-SGPropertyNode::unalias ()
-{
- _target = 0;
- return (_value != 0 ? _value->unalias() : false);
-}
-
-
-/**
- * Test whether this node is aliased.
- */
-bool
-SGPropertyNode::isAlias () const
-{
- return (_value != 0 ? _value->isAlias() : false);
-}
-
-
-/**
- * Get the target of an alias.
- *
- * This is tricky, because it is actually the value that is aliased,
- * and someone could realias or unalias the value directly without
- * going through the property node. The node caches its best guess,
- * but it may have to search the whole property tree.
- *
- * @return The target node for the alias, or 0 if the node is not aliased.
- */
-SGPropertyNode *
-SGPropertyNode::getAliasTarget ()
-{
- if (_value == 0 || !_value->isAlias()) {
- return 0;
- } else if (_target != 0 && _target->getValue() == _value->getAlias()) {
- return _target;
- } else {
- _target = find_node_by_value(getRootNode(), _value->getAlias());
- return _target;
- }
-}
-
-
-const SGPropertyNode *
-SGPropertyNode::getAliasTarget () const
-{
- if (_value == 0 || !_value->isAlias()) {
- return 0;
- } else if (_target != 0 && _target->getValue() == _value->getAlias()) {
- return _target;
- } else {
- // FIXME: const cast
- _target =
- find_node_by_value((SGPropertyNode *)getRootNode(), _value->getAlias());
- return _target;
- }
-}
-
-
-/**
- * Get a non-const child by index.
- */
-SGPropertyNode *
-SGPropertyNode::getChild (int position)
-{
- if (position >= 0 && position < nChildren())
- return _children[position];
- else
- return 0;
-}
-
-
-/**
- * Get a const child by index.
- */
-const SGPropertyNode *
-SGPropertyNode::getChild (int position) const
-{
- if (position >= 0 && position < nChildren())
- return _children[position];
- else
- return 0;
-}
-
-
-/**
- * Get a non-const child by name and index, creating if necessary.
- */
-SGPropertyNode *
-SGPropertyNode::getChild (const string &name, int index, bool create)
-{
- int pos = find_child(name, index, _children);
- if (pos >= 0) {
- return _children[pos];
- } else if (create) {
- _children.push_back(new SGPropertyNode(name, index, this));
- return _children[_children.size()-1];
- } else {
- return 0;
- }
-}
-
-
-/**
- * Get a const child by name and index.
- */
-const SGPropertyNode *
-SGPropertyNode::getChild (const string &name, int index) const
-{
- int pos = find_child(name, index, _children);
- if (pos >= 0)
- return _children[pos];
- else
- return 0;
-}
-
-
-/**
- * Get all children with the same name (but different indices).
- */
-vector<SGPropertyNode *>
-SGPropertyNode::getChildren (const string &name)
-{
- vector<SGPropertyNode *> children;
- int max = _children.size();
-
- for (int i = 0; i < max; i++)
- if (_children[i]->getName() == name)
- children.push_back(_children[i]);
-
- sort(children.begin(), children.end(), CompareIndices());
- return children;
-}
-
-
-/**
- * Get all children const with the same name (but different indices).
- */
-vector<const SGPropertyNode *>
-SGPropertyNode::getChildren (const string &name) const
-{
- vector<const SGPropertyNode *> children;
- int max = _children.size();
-
- for (int i = 0; i < max; i++)
- if (_children[i]->getName() == name)
- children.push_back(_children[i]);
-
- sort(children.begin(), children.end(), CompareIndices());
- return children;
-}
-
-
-string
-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;
- }
- return path;
-}
-
-SGPropertyNode::Type
-SGPropertyNode::getType () const
-{
- if (_value != 0)
- return (Type)(_value->getType());
- else
- return UNKNOWN;
-}
-
-
-bool
-SGPropertyNode::getBoolValue () const
-{
- return (_value == 0 ? SGRawValue<bool>::DefaultValue
- : _value->getBoolValue());
-}
-
-int
-SGPropertyNode::getIntValue () const
-{
- return (_value == 0 ? SGRawValue<int>::DefaultValue
- : _value->getIntValue());
-}
-
-long
-SGPropertyNode::getLongValue () const
-{
- return (_value == 0 ? SGRawValue<long>::DefaultValue
- : _value->getLongValue());
-}
-
-float
-SGPropertyNode::getFloatValue () const
-{
- return (_value == 0 ? SGRawValue<float>::DefaultValue
- : _value->getFloatValue());
-}
-
-double
-SGPropertyNode::getDoubleValue () const
-{
- return (_value == 0 ? SGRawValue<double>::DefaultValue
- : _value->getDoubleValue());
-}
-
-string
-SGPropertyNode::getStringValue () const
-{
- return (_value == 0 ? SGRawValue<string>::DefaultValue
- : _value->getStringValue());
-}
-
-bool
-SGPropertyNode::setBoolValue (bool val)
-{
- if (_value == 0)
- _value = new SGValue();
- return _value->setBoolValue(val);
-}
-
-bool
-SGPropertyNode::setIntValue (int val)
-{
- if (_value == 0)
- _value = new SGValue();
- return _value->setIntValue(val);
-}
-
-bool
-SGPropertyNode::setLongValue (long val)
-{
- if (_value == 0)
- _value = new SGValue();
- return _value->setLongValue(val);
-}
-
-bool
-SGPropertyNode::setFloatValue (float val)
-{
- if (_value == 0)
- _value = new SGValue();
- return _value->setFloatValue(val);
-}
-
-bool
-SGPropertyNode::setDoubleValue (double val)
-{
- if (_value == 0)
- _value = new SGValue();
- return _value->setDoubleValue(val);
-}
-
-bool
-SGPropertyNode::setStringValue (string val)
-{
- if (_value == 0)
- _value = new SGValue();
- return _value->setStringValue(val);
-}
-
-bool
-SGPropertyNode::setUnknownValue (string val)
-{
- if (_value == 0)
- _value = new SGValue();
- return _value->setUnknownValue(val);
-}
-
-bool
-SGPropertyNode::isTied () const
-{
- return (_value == 0 ? false : _value->isTied());
-}
-
-bool
-SGPropertyNode::tie (const SGRawValue<bool> &rawValue, bool useDefault)
-{
- if (_value == 0)
- _value = new SGValue();
- return _value->tie(rawValue, useDefault);
-}
-
-bool
-SGPropertyNode::tie (const SGRawValue<int> &rawValue, bool useDefault)
-{
- if (_value == 0)
- _value = new SGValue();
- return _value->tie(rawValue, useDefault);
-}
-
-bool
-SGPropertyNode::tie (const SGRawValue<long> &rawValue, bool useDefault)
-{
- if (_value == 0)
- _value = new SGValue();
- return _value->tie(rawValue, useDefault);
-}
-
-bool
-SGPropertyNode::tie (const SGRawValue<float> &rawValue, bool useDefault)
-{
- if (_value == 0)
- _value = new SGValue();
- return _value->tie(rawValue, useDefault);
-}
-
-bool
-SGPropertyNode::tie (const SGRawValue<double> &rawValue, bool useDefault)
-{
- if (_value == 0)
- _value = new SGValue();
- return _value->tie(rawValue, useDefault);
-}
-
-bool
-SGPropertyNode::tie (const SGRawValue<string> &rawValue, bool useDefault)
-{
- if (_value == 0)
- _value = new SGValue();
- return _value->tie(rawValue, useDefault);
-}
-
-bool
-SGPropertyNode::untie ()
-{
- return (_value == 0 ? false : _value->untie());
-}
-