diff --git a/simgear/props/props.cxx b/simgear/props/props.cxx index 49dbdad8..b0dbd10c 100644 --- a/simgear/props/props.cxx +++ b/simgear/props/props.cxx @@ -2443,7 +2443,8 @@ SGPropertyNode::fireValueChanged (SGPropertyNode * node) { if (_listeners != 0) { for (unsigned int i = 0; i < _listeners->size(); i++) { - (*_listeners)[i]->valueChanged(node); + if ((*_listeners)[i]) + (*_listeners)[i]->valueChanged(node); } } if (_parent != 0) @@ -2581,53 +2582,77 @@ std::ostream& SGRawBase::printOn(std::ostream& stream) const namespace simgear { #if !PROPS_STANDALONE -template<> -std::istream& readFrom(std::istream& stream, SGVec4d& result) -{ - for (int i = 0; i < 4; ++i) { - stream >> result[i]; + template<> + std::istream& readFrom(std::istream& stream, SGVec4d& result) + { + for (int i = 0; i < 4; ++i) { + stream >> result[i]; + } + return stream; } - return stream; -} #endif -namespace -{ -bool compareNodeValue(const SGPropertyNode& lhs, const SGPropertyNode& rhs) -{ - props::Type ltype = lhs.getType(); - props::Type rtype = rhs.getType(); - if (ltype != rtype) - return false; - switch (ltype) { - case props::NONE: - return true; - case props::ALIAS: - return false; // XXX Should we look in aliases? - case props::BOOL: - return lhs.getValue() == rhs.getValue(); - case props::INT: - return lhs.getValue() == rhs.getValue(); - case props::LONG: - return lhs.getValue() == rhs.getValue(); - case props::FLOAT: - return lhs.getValue() == rhs.getValue(); - case props::DOUBLE: - return lhs.getValue() == rhs.getValue(); - case props::STRING: - case props::UNSPECIFIED: - return !strcmp(lhs.getStringValue(), rhs.getStringValue()); + namespace + { + bool compareNodeValue(const SGPropertyNode& lhs, const SGPropertyNode& rhs) + { + props::Type ltype = lhs.getType(); + props::Type rtype = rhs.getType(); + if (ltype != rtype) + return false; + switch (ltype) { + case props::NONE: + return true; + case props::ALIAS: + return false; // XXX Should we look in aliases? + case props::BOOL: + return lhs.getValue() == rhs.getValue(); + case props::INT: + return lhs.getValue() == rhs.getValue(); + case props::LONG: + return lhs.getValue() == rhs.getValue(); + case props::FLOAT: + return lhs.getValue() == rhs.getValue(); + case props::DOUBLE: + return lhs.getValue() == rhs.getValue(); + case props::STRING: + case props::UNSPECIFIED: + return !strcmp(lhs.getStringValue(), rhs.getStringValue()); #if !PROPS_STANDALONE - case props::VEC3D: - return lhs.getValue() == rhs.getValue(); - case props::VEC4D: - return lhs.getValue() == rhs.getValue(); + case props::VEC3D: + return lhs.getValue() == rhs.getValue(); + case props::VEC4D: + return lhs.getValue() == rhs.getValue(); #endif - default: - return false; + default: + return false; + } + } } } -} + + +void SGPropertyNode::copy(SGPropertyNode *to) +{ + if (nChildren()) + { + for (int i = 0; i < nChildren(); i++) { + SGPropertyNode *child = getChild(i); + SGPropertyNode *to_child = to->getChild(child->getName()); + if (!to_child) + to_child = to->addChild(child->getName()); + if (child->nChildren()) + { + child->copy(to_child); + } + else + { + to_child->setValue(child->getStringValue()); + } + } + } + else + to->setValue(getStringValue()); } bool SGPropertyNode::compare(const SGPropertyNode& lhs, diff --git a/simgear/props/props.hxx b/simgear/props/props.hxx index 620928b5..1f56e80e 100644 --- a/simgear/props/props.hxx +++ b/simgear/props/props.hxx @@ -1105,6 +1105,11 @@ public: */ SGPropertyNode * getNode (const char * relative_path, bool create = false); + /** + * deep copy one node to another. + */ + void copy(SGPropertyNode *to); + /** * Get a pointer to another node by relative path. */