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