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:
James Turner
2013-12-10 17:37:37 +00:00
parent 6b0f7e8512
commit 890cc46825
3 changed files with 103 additions and 50 deletions

View 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,

View 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

View 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