#include <simgear/compiler.h>
-#include <stdlib.h> // atof() atoi()
+#include <stdlib.h> // atof() atoi()
#include <simgear/sg_inlines.h>
#include <simgear/debug/logstream.hxx>
-#include <simgear/math/SGMath.hxx>
#include <simgear/misc/sg_path.hxx>
#include <simgear/xml/easyxml.hxx>
+#include <simgear/misc/ResourceManager.hxx>
#include "props.hxx"
#include "props_io.hxx"
+#include "vectorPropTemplates.hxx"
#include <iostream>
#include <fstream>
#include <string>
-#include <cstring> // strcmp()
+#include <cstring> // strcmp()
#include <vector>
#include <map>
// Check for an include.
attval = atts.getValue("include");
if (attval != 0) {
- SGPath path(SGPath(_base).dir());
- path.append(attval);
try {
- readProperties(path.str(), _root, 0, _extended);
+ SGPath path = simgear::ResourceManager::instance()->findPath(attval, SGPath(_base).dir());
+ if (path.isNull())
+ {
+ throw sg_io_exception("Cannot open file", sg_location(attval));
+ }
+ readProperties(path.str(), _root, 0, _extended);
} catch (sg_io_exception &e) {
- setException(e);
+ setException(e);
}
}
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");
bool omit = false;
attval = atts.getValue("include");
if (attval != 0) {
- SGPath path(SGPath(_base).dir());
- path.append(attval);
try {
- readProperties(path.str(), node, 0, _extended);
+ SGPath path = simgear::ResourceManager::instance()->findPath(attval, SGPath(_base).dir());
+ if (path.isNull())
+ {
+ throw sg_io_exception("Cannot open file", sg_location(attval));
+ }
+ readProperties(path.str(), node, 0, _extended);
} catch (sg_io_exception &e) {
- setException(e);
+ setException(e);
}
attval = atts.getValue("omit-node");
}
const char *type = atts.getValue("type");
- if (type)
+ // if a type is given and the node is tied,
+ // don't clear the value because
+ // clearValue() unties the property
+ if (type && false == node->isTied() )
node->clearValue();
push_state(node, type, mode, omit);
}
*
* @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;
}
}
- // 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->getNameString(),
- 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;