Add method to copy entire properry subtree

This commit is contained in:
Richard Harrison 2017-10-15 16:54:36 +02:00
parent b57dca66be
commit 7be1fcc32e
2 changed files with 71 additions and 41 deletions

View File

@ -2443,7 +2443,8 @@ SGPropertyNode::fireValueChanged (SGPropertyNode * node)
{ {
if (_listeners != 0) { if (_listeners != 0) {
for (unsigned int i = 0; i < _listeners->size(); i++) { for (unsigned int i = 0; i < _listeners->size(); i++) {
(*_listeners)[i]->valueChanged(node); if ((*_listeners)[i])
(*_listeners)[i]->valueChanged(node);
} }
} }
if (_parent != 0) if (_parent != 0)
@ -2581,53 +2582,77 @@ std::ostream& SGRawBase<SGVec4d>::printOn(std::ostream& stream) const
namespace simgear namespace simgear
{ {
#if !PROPS_STANDALONE #if !PROPS_STANDALONE
template<> template<>
std::istream& readFrom<SGVec4d>(std::istream& stream, SGVec4d& result) std::istream& readFrom<SGVec4d>(std::istream& stream, SGVec4d& result)
{ {
for (int i = 0; i < 4; ++i) { for (int i = 0; i < 4; ++i) {
stream >> result[i]; stream >> result[i];
}
return stream;
} }
return stream;
}
#endif #endif
namespace namespace
{ {
bool compareNodeValue(const SGPropertyNode& lhs, const SGPropertyNode& rhs) bool compareNodeValue(const SGPropertyNode& lhs, const SGPropertyNode& rhs)
{ {
props::Type ltype = lhs.getType(); props::Type ltype = lhs.getType();
props::Type rtype = rhs.getType(); props::Type rtype = rhs.getType();
if (ltype != rtype) if (ltype != rtype)
return false; return false;
switch (ltype) { switch (ltype) {
case props::NONE: case props::NONE:
return true; return true;
case props::ALIAS: case props::ALIAS:
return false; // XXX Should we look in aliases? return false; // XXX Should we look in aliases?
case props::BOOL: case props::BOOL:
return lhs.getValue<bool>() == rhs.getValue<bool>(); return lhs.getValue<bool>() == rhs.getValue<bool>();
case props::INT: case props::INT:
return lhs.getValue<int>() == rhs.getValue<int>(); return lhs.getValue<int>() == rhs.getValue<int>();
case props::LONG: case props::LONG:
return lhs.getValue<long>() == rhs.getValue<long>(); return lhs.getValue<long>() == rhs.getValue<long>();
case props::FLOAT: case props::FLOAT:
return lhs.getValue<float>() == rhs.getValue<float>(); return lhs.getValue<float>() == rhs.getValue<float>();
case props::DOUBLE: case props::DOUBLE:
return lhs.getValue<double>() == rhs.getValue<double>(); return lhs.getValue<double>() == rhs.getValue<double>();
case props::STRING: case props::STRING:
case props::UNSPECIFIED: case props::UNSPECIFIED:
return !strcmp(lhs.getStringValue(), rhs.getStringValue()); return !strcmp(lhs.getStringValue(), rhs.getStringValue());
#if !PROPS_STANDALONE #if !PROPS_STANDALONE
case props::VEC3D: case props::VEC3D:
return lhs.getValue<SGVec3d>() == rhs.getValue<SGVec3d>(); return lhs.getValue<SGVec3d>() == rhs.getValue<SGVec3d>();
case props::VEC4D: case props::VEC4D:
return lhs.getValue<SGVec4d>() == rhs.getValue<SGVec4d>(); return lhs.getValue<SGVec4d>() == rhs.getValue<SGVec4d>();
#endif #endif
default: default:
return false; 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, bool SGPropertyNode::compare(const SGPropertyNode& lhs,

View File

@ -1105,6 +1105,11 @@ public:
*/ */
SGPropertyNode * getNode (const char * relative_path, bool create = false); 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. * Get a pointer to another node by relative path.
*/ */