From 890cc46825b39b3ec50c84a6de390666b73398ee Mon Sep 17 00:00:00 2001 From: James Turner Date: Tue, 10 Dec 2013 17:37:37 +0000 Subject: [PATCH] Reset: alternate property copying strategy. Search the tree for leaves / sub-trees with a particular attribute set. This permits both sparse selection as well as selection by sub-tree. (This is needed for PRESERVE attribute, and once new reset is switched on, will enable 'normal' copyProperties to revert to ignoring attributes completely) --- simgear/props/props.hxx | 1 + simgear/props/props_io.cxx | 149 ++++++++++++++++++++++++------------- simgear/props/props_io.hxx | 3 + 3 files changed, 103 insertions(+), 50 deletions(-) diff --git a/simgear/props/props.hxx b/simgear/props/props.hxx index cbf60476..a43bd2e1 100644 --- a/simgear/props/props.hxx +++ b/simgear/props/props.hxx @@ -731,6 +731,7 @@ public: * whether the property should normally be saved and restored.

*/ enum Attribute { + NO_ATTR = 0, READ = 1, WRITE = 2, ARCHIVE = 4, diff --git a/simgear/props/props_io.cxx b/simgear/props/props_io.cxx index fb16c3f5..c86f9d6c 100644 --- a/simgear/props/props_io.cxx +++ b/simgear/props/props_io.cxx @@ -640,6 +640,64 @@ writeProperties (const char* file, const SGPropertyNode * start_node) //////////////////////////////////////////////////////////////////////// +bool +copyPropertyValue(const SGPropertyNode *in, SGPropertyNode *out) +{ + using namespace simgear; + bool retval = true; + + if (!in->hasValue()) { + return true; + } + + switch (in->getType()) { + case props::BOOL: + if (!out->setBoolValue(in->getBoolValue())) + retval = false; + break; + case props::INT: + if (!out->setIntValue(in->getIntValue())) + retval = false; + break; + case props::LONG: + if (!out->setLongValue(in->getLongValue())) + retval = false; + break; + case props::FLOAT: + if (!out->setFloatValue(in->getFloatValue())) + retval = false; + break; + case props::DOUBLE: + if (!out->setDoubleValue(in->getDoubleValue())) + retval = false; + break; + case props::STRING: + if (!out->setStringValue(in->getStringValue())) + retval = false; + break; + case props::UNSPECIFIED: + if (!out->setUnspecifiedValue(in->getStringValue())) + retval = false; + break; + case props::VEC3D: + if (!out->setValue(in->getValue())) + retval = false; + break; + case props::VEC4D: + if (!out->setValue(in->getValue())) + retval = false; + break; + default: + if (in->isAlias()) + break; + string message = "Unknown internal SGPropertyNode type"; + message += in->getType(); + throw sg_error(message, "SimGear Property Reader"); + } + + return retval; +} + /** * Copy one property tree to another. * @@ -657,57 +715,11 @@ copyProperties (const SGPropertyNode *in, SGPropertyNode *out, int attr_value, int attr_mask) { using namespace simgear; - bool retval = true; - - // First, copy the actual value, - // if any. - if (in->hasValue()) { - switch (in->getType()) { - case props::BOOL: - if (!out->setBoolValue(in->getBoolValue())) - retval = false; - break; - case props::INT: - if (!out->setIntValue(in->getIntValue())) - retval = false; - break; - case props::LONG: - if (!out->setLongValue(in->getLongValue())) - retval = false; - break; - case props::FLOAT: - if (!out->setFloatValue(in->getFloatValue())) - retval = false; - break; - case props::DOUBLE: - if (!out->setDoubleValue(in->getDoubleValue())) - retval = false; - break; - case props::STRING: - if (!out->setStringValue(in->getStringValue())) - retval = false; - break; - case props::UNSPECIFIED: - if (!out->setUnspecifiedValue(in->getStringValue())) - retval = false; - break; - case props::VEC3D: - if (!out->setValue(in->getValue())) - retval = false; - break; - case props::VEC4D: - if (!out->setValue(in->getValue())) - retval = false; - break; - default: - if (in->isAlias()) - break; - string message = "Unknown internal SGPropertyNode type"; - message += in->getType(); - throw sg_error(message, "SimGear Property Reader"); - } + bool retval = copyPropertyValue(in, out); + if (!retval) { + return false; } - + // copy the attributes. out->setAttributes( in->getAttributes() ); @@ -748,4 +760,41 @@ copyProperties (const SGPropertyNode *in, SGPropertyNode *out, return retval; } + +bool +copyPropertiesWithAttribute(const SGPropertyNode *in, SGPropertyNode *out, + SGPropertyNode::Attribute attr) +{ + bool retval = copyPropertyValue(in, out); + if (!retval) { + return false; + } + out->setAttributes( in->getAttributes() ); + + // if attribute is set directly on this node, we don't require it on + // descendent nodes. (Allows setting an attribute on an entire sub-tree + // of nodes) + if ((attr != SGPropertyNode::NO_ATTR) && out->getAttribute(attr)) { + attr = SGPropertyNode::NO_ATTR; + } + + int nChildren = in->nChildren(); + for (int i = 0; i < nChildren; i++) { + const SGPropertyNode* in_child = in->getChild(i); + if ((attr != SGPropertyNode::NO_ATTR) && !isArchivable(in_child, attr)) + continue; + + SGPropertyNode* out_child = out->getChild(in_child->getNameString(), + in_child->getIndex(), + true); + + bool ok = copyPropertiesWithAttribute(in_child, out_child, attr); + if (!ok) { + return false; + } + }// of children iteration + + return true; +} + // end of props_io.cxx diff --git a/simgear/props/props_io.hxx b/simgear/props/props_io.hxx index 743866a1..a1eee30a 100644 --- a/simgear/props/props_io.hxx +++ b/simgear/props/props_io.hxx @@ -65,6 +65,9 @@ bool copyProperties (const SGPropertyNode *in, SGPropertyNode *out, int attr_value=0, int attr_mask=0); +bool copyPropertiesWithAttribute(const SGPropertyNode *in, SGPropertyNode *out, + SGPropertyNode::Attribute attr); + #endif // __PROPS_IO_HXX // end of props_io.hxx -- 2.39.5