]> git.mxchange.org Git - simgear.git/blobdiff - simgear/props/props_io.cxx
Melchior FRANZ: fix SGPropertyNode::LAST_USED_ATTRIBUTE
[simgear.git] / simgear / props / props_io.cxx
index 44380186cf891d061e34ebd40732cd4cffd7e711..9fea449730bf94122e3eea9c23c826b4eae5de68 100644 (file)
@@ -187,16 +187,17 @@ PropsVisitor::startElement (const char * name, const XMLAttributes &atts)
                                // Get the index.
     attval = atts.getValue("n");
     int index = 0;
+    string strName(name);
     if (attval != 0) {
       index = atoi(attval);
-      st.counters[name] = SG_MAX2(st.counters[name], index+1);
+      st.counters[strName] = SG_MAX2(st.counters[strName], index+1);
     } else {
-      index = st.counters[name];
-      st.counters[name]++;
+      index = st.counters[strName];
+      st.counters[strName]++;
     }
 
                                // Got the index, so grab the node.
-    SGPropertyNode * node = st.node->getChild(name, index, true);
+    SGPropertyNode * node = st.node->getChild(strName, index, true);
     if (!node->getAttribute(SGPropertyNode::WRITE)) {
       SG_LOG(SG_INPUT, SG_ALERT, "Not overwriting write-protected property "
           << node->getPath(true));
@@ -226,6 +227,9 @@ PropsVisitor::startElement (const char * name, const XMLAttributes &atts)
     attval = atts.getValue("userarchive");
     if (checkFlag(attval, false))
       mode |= SGPropertyNode::USERARCHIVE;
+    attval = atts.getValue("preserve");
+    if (checkFlag(attval, false))
+      mode |= SGPropertyNode::PRESERVE;
 
                                // Check for an alias.
     attval = atts.getValue("alias");
@@ -437,6 +441,8 @@ getTypeName (simgear::props::Type type)
   case props::ALIAS:
   case props::NONE:
     return "unspecified";
+  default: // avoid compiler warning
+    break;
   }
 
   // keep the compiler from squawking
@@ -599,6 +605,13 @@ writeProperties (const string &file, const SGPropertyNode * start_node,
   }
 }
 
+// Another variation, useful when called from gdb
+void
+writeProperties (const char* file, const SGPropertyNode * start_node)
+{
+    writeProperties(string(file), start_node, true);
+}
+
 
 \f
 ////////////////////////////////////////////////////////////////////////
@@ -611,11 +624,16 @@ writeProperties (const string &file, const SGPropertyNode * start_node,
  * 
  * @param in The source property tree.
  * @param out The destination property tree.
+ * @param attr_value Only copy properties with given attribute values.
+ * @param attr_mask  Mask for attributes to be considered by attr_value
+ *                   (default is 0 = attributes not considered, all
+ *                   properties copied).
  * @return true if all properties were copied, false if some failed
  *  (for example, if the property's value is tied read-only).
  */
 bool
-copyProperties (const SGPropertyNode *in, SGPropertyNode *out)
+copyProperties (const SGPropertyNode *in, SGPropertyNode *out,
+                int attr_value, int attr_mask)
 {
   using namespace simgear;
   bool retval = true;
@@ -669,18 +687,41 @@ copyProperties (const SGPropertyNode *in, SGPropertyNode *out)
     }
   }
 
-                               // copy the attributes.
+  // copy the attributes.
   out->setAttributes( in->getAttributes() );
 
-                               // Next, copy the children.
+  // Next, copy the children.
   int nChildren = in->nChildren();
   for (int i = 0; i < nChildren; i++) {
     const SGPropertyNode * in_child = in->getChild(i);
-    SGPropertyNode * out_child = out->getChild(in_child->getName(),
-                                              in_child->getIndex(),
-                                              true);
-    if (!copyProperties(in_child, out_child))
-      retval = false;
+    int mask = attr_mask;
+    /* attributes have no meaning for nodes without values - except
+     * the PRESERVE flag. So ignore them. */
+    if (!in_child->hasValue())
+        mask &= SGPropertyNode::PRESERVE;
+    if ((in_child->getAttributes() & mask) == (attr_value & mask))
+    {
+      SGPropertyNode * out_child = out->getChild(in_child->getNameString(),
+                             in_child->getIndex(),
+                             false);
+      if (!out_child)
+      {
+          out_child = out->getChild(in_child->getNameString(),
+                                    in_child->getIndex(),
+                                    true);
+      }
+      else
+      {
+          mask = attr_mask;
+          if (!out_child->hasValue())
+              mask &= SGPropertyNode::PRESERVE;
+          if ((out_child->getAttributes() & mask) != (attr_value & mask))
+              out_child = NULL;
+      }
+      if (out_child &&
+          (!copyProperties(in_child, out_child, attr_value, attr_mask)))
+          retval = false;
+    }
   }
 
   return retval;