]> git.mxchange.org Git - simgear.git/commitdiff
Reset: alternate property copying strategy.
authorJames Turner <zakalawe@mac.com>
Tue, 10 Dec 2013 17:37:37 +0000 (17:37 +0000)
committerJames Turner <zakalawe@mac.com>
Tue, 10 Dec 2013 17:37:37 +0000 (17:37 +0000)
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
simgear/props/props_io.cxx
simgear/props/props_io.hxx

index cbf604765b40bee68de1f8c1b516fa691a76cd8d..a43bd2e1999e5b7f3c6021595710182c7ff9df2f 100644 (file)
@@ -731,6 +731,7 @@ public:
    * whether the property should normally be saved and restored.</p>
    */
   enum Attribute {
+    NO_ATTR = 0,
     READ = 1,
     WRITE = 2,
     ARCHIVE = 4,
index fb16c3f53e3f04848f43edfb7e85ad2080a33866..c86f9d6cc7ed3183894d53ef647ad6aa3d1edf99 100644 (file)
@@ -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<SGVec3d>()))
+                retval = false;
+            break;
+        case props::VEC4D:
+            if (!out->setValue(in->getValue<SGVec4d>()))
+                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<SGVec3d>()))
-        retval = false;
-      break;
-    case props::VEC4D:
-      if (!out->setValue(in->getValue<SGVec4d>()))
-        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
index 743866a1b9754183742714623b31cb2697674bf9..a1eee30a6f42d95cec0556eb8e6b592b5ff03070 100644 (file)
@@ -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