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)
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user