Cleanup of properties
Change most uses of the SGPropertyNode _value union to use static_cast. Move SGPropertyNode::Type out of the class into simgear::props namespace. Add a PropertyTraits class so that templates can calculate the property type tag based on a C++ type. In destructor, delete _value.val if it is not 0 (and the property is not aliased).
This commit is contained in:
@@ -144,8 +144,9 @@ SGOrCondition::addCondition (SGCondition * condition)
|
||||
static int
|
||||
doComparison (const SGPropertyNode * left, const SGPropertyNode *right)
|
||||
{
|
||||
using namespace simgear::props;
|
||||
switch (left->getType()) {
|
||||
case SGPropertyNode::BOOL: {
|
||||
case BOOL: {
|
||||
bool v1 = left->getBoolValue();
|
||||
bool v2 = right->getBoolValue();
|
||||
if (v1 < v2)
|
||||
@@ -156,7 +157,7 @@ doComparison (const SGPropertyNode * left, const SGPropertyNode *right)
|
||||
return SGComparisonCondition::EQUALS;
|
||||
break;
|
||||
}
|
||||
case SGPropertyNode::INT: {
|
||||
case INT: {
|
||||
int v1 = left->getIntValue();
|
||||
int v2 = right->getIntValue();
|
||||
if (v1 < v2)
|
||||
@@ -167,7 +168,7 @@ doComparison (const SGPropertyNode * left, const SGPropertyNode *right)
|
||||
return SGComparisonCondition::EQUALS;
|
||||
break;
|
||||
}
|
||||
case SGPropertyNode::LONG: {
|
||||
case LONG: {
|
||||
long v1 = left->getLongValue();
|
||||
long v2 = right->getLongValue();
|
||||
if (v1 < v2)
|
||||
@@ -178,7 +179,7 @@ doComparison (const SGPropertyNode * left, const SGPropertyNode *right)
|
||||
return SGComparisonCondition::EQUALS;
|
||||
break;
|
||||
}
|
||||
case SGPropertyNode::FLOAT: {
|
||||
case FLOAT: {
|
||||
float v1 = left->getFloatValue();
|
||||
float v2 = right->getFloatValue();
|
||||
if (v1 < v2)
|
||||
@@ -189,7 +190,7 @@ doComparison (const SGPropertyNode * left, const SGPropertyNode *right)
|
||||
return SGComparisonCondition::EQUALS;
|
||||
break;
|
||||
}
|
||||
case SGPropertyNode::DOUBLE: {
|
||||
case DOUBLE: {
|
||||
double v1 = left->getDoubleValue();
|
||||
double v2 = right->getDoubleValue();
|
||||
if (v1 < v2)
|
||||
@@ -200,9 +201,9 @@ doComparison (const SGPropertyNode * left, const SGPropertyNode *right)
|
||||
return SGComparisonCondition::EQUALS;
|
||||
break;
|
||||
}
|
||||
case SGPropertyNode::STRING:
|
||||
case SGPropertyNode::NONE:
|
||||
case SGPropertyNode::UNSPECIFIED: {
|
||||
case STRING:
|
||||
case NONE:
|
||||
case UNSPECIFIED: {
|
||||
string v1 = left->getStringValue();
|
||||
string v2 = right->getStringValue();
|
||||
if (v1 < v2)
|
||||
|
||||
@@ -39,6 +39,8 @@ using std::string;
|
||||
using std::vector;
|
||||
using std::stringstream;
|
||||
|
||||
using namespace simgear;
|
||||
using namespace simgear::props;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
@@ -64,8 +66,6 @@ public:
|
||||
|
||||
#define TEST_READ(dflt) if (!getAttribute(READ)) return dflt
|
||||
#define TEST_WRITE if (!getAttribute(WRITE)) return false
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Default values for every type.
|
||||
@@ -77,8 +77,6 @@ template<> const long SGRawValue<long>::DefaultValue = 0L;
|
||||
template<> const float SGRawValue<float>::DefaultValue = 0.0;
|
||||
template<> const double SGRawValue<double>::DefaultValue = 0.0L;
|
||||
template<> const char * const SGRawValue<const char *>::DefaultValue = "";
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Local path normalization code.
|
||||
@@ -342,7 +340,7 @@ inline bool
|
||||
SGPropertyNode::get_bool () const
|
||||
{
|
||||
if (_tied)
|
||||
return _value.bool_val->getValue();
|
||||
return static_cast<SGRawValue<bool>*>(_value.val)->getValue();
|
||||
else
|
||||
return _local_val.bool_val;
|
||||
}
|
||||
@@ -351,7 +349,7 @@ inline int
|
||||
SGPropertyNode::get_int () const
|
||||
{
|
||||
if (_tied)
|
||||
return _value.int_val->getValue();
|
||||
return (static_cast<SGRawValue<int>*>(_value.val))->getValue();
|
||||
else
|
||||
return _local_val.int_val;
|
||||
}
|
||||
@@ -360,7 +358,7 @@ inline long
|
||||
SGPropertyNode::get_long () const
|
||||
{
|
||||
if (_tied)
|
||||
return _value.long_val->getValue();
|
||||
return static_cast<SGRawValue<long>*>(_value.val)->getValue();
|
||||
else
|
||||
return _local_val.long_val;
|
||||
}
|
||||
@@ -369,7 +367,7 @@ inline float
|
||||
SGPropertyNode::get_float () const
|
||||
{
|
||||
if (_tied)
|
||||
return _value.float_val->getValue();
|
||||
return static_cast<SGRawValue<float>*>(_value.val)->getValue();
|
||||
else
|
||||
return _local_val.float_val;
|
||||
}
|
||||
@@ -378,7 +376,7 @@ inline double
|
||||
SGPropertyNode::get_double () const
|
||||
{
|
||||
if (_tied)
|
||||
return _value.double_val->getValue();
|
||||
return static_cast<SGRawValue<double>*>(_value.val)->getValue();
|
||||
else
|
||||
return _local_val.double_val;
|
||||
}
|
||||
@@ -387,7 +385,7 @@ inline const char *
|
||||
SGPropertyNode::get_string () const
|
||||
{
|
||||
if (_tied)
|
||||
return _value.string_val->getValue();
|
||||
return static_cast<SGRawValue<const char*>*>(_value.val)->getValue();
|
||||
else
|
||||
return _local_val.string_val;
|
||||
}
|
||||
@@ -396,7 +394,7 @@ inline bool
|
||||
SGPropertyNode::set_bool (bool val)
|
||||
{
|
||||
if (_tied) {
|
||||
if (_value.bool_val->setValue(val)) {
|
||||
if (static_cast<SGRawValue<bool>*>(_value.val)->setValue(val)) {
|
||||
fireValueChanged();
|
||||
return true;
|
||||
} else {
|
||||
@@ -413,7 +411,7 @@ inline bool
|
||||
SGPropertyNode::set_int (int val)
|
||||
{
|
||||
if (_tied) {
|
||||
if (_value.int_val->setValue(val)) {
|
||||
if (static_cast<SGRawValue<int>*>(_value.val)->setValue(val)) {
|
||||
fireValueChanged();
|
||||
return true;
|
||||
} else {
|
||||
@@ -430,7 +428,7 @@ inline bool
|
||||
SGPropertyNode::set_long (long val)
|
||||
{
|
||||
if (_tied) {
|
||||
if (_value.long_val->setValue(val)) {
|
||||
if (static_cast<SGRawValue<long>*>(_value.val)->setValue(val)) {
|
||||
fireValueChanged();
|
||||
return true;
|
||||
} else {
|
||||
@@ -447,7 +445,7 @@ inline bool
|
||||
SGPropertyNode::set_float (float val)
|
||||
{
|
||||
if (_tied) {
|
||||
if (_value.float_val->setValue(val)) {
|
||||
if (static_cast<SGRawValue<float>*>(_value.val)->setValue(val)) {
|
||||
fireValueChanged();
|
||||
return true;
|
||||
} else {
|
||||
@@ -464,7 +462,7 @@ inline bool
|
||||
SGPropertyNode::set_double (double val)
|
||||
{
|
||||
if (_tied) {
|
||||
if (_value.double_val->setValue(val)) {
|
||||
if (static_cast<SGRawValue<double>*>(_value.val)->setValue(val)) {
|
||||
fireValueChanged();
|
||||
return true;
|
||||
} else {
|
||||
@@ -481,7 +479,7 @@ inline bool
|
||||
SGPropertyNode::set_string (const char * val)
|
||||
{
|
||||
if (_tied) {
|
||||
if (_value.string_val->setValue(val)) {
|
||||
if (static_cast<SGRawValue<const char*>*>(_value.val)->setValue(val)) {
|
||||
fireValueChanged();
|
||||
return true;
|
||||
} else {
|
||||
@@ -498,61 +496,39 @@ SGPropertyNode::set_string (const char * val)
|
||||
void
|
||||
SGPropertyNode::clearValue ()
|
||||
{
|
||||
switch (_type) {
|
||||
case NONE:
|
||||
break;
|
||||
case ALIAS:
|
||||
put(_value.alias);
|
||||
_value.alias = 0;
|
||||
break;
|
||||
case BOOL:
|
||||
if (_tied) {
|
||||
delete _value.bool_val;
|
||||
_value.bool_val = 0;
|
||||
if (_type == ALIAS) {
|
||||
put(_value.alias);
|
||||
_value.alias = 0;
|
||||
} else if (_type != NONE) {
|
||||
switch (_type) {
|
||||
case BOOL:
|
||||
_local_val.bool_val = SGRawValue<bool>::DefaultValue;
|
||||
break;
|
||||
case INT:
|
||||
_local_val.int_val = SGRawValue<int>::DefaultValue;
|
||||
break;
|
||||
case LONG:
|
||||
_local_val.long_val = SGRawValue<long>::DefaultValue;
|
||||
break;
|
||||
case FLOAT:
|
||||
_local_val.float_val = SGRawValue<float>::DefaultValue;
|
||||
break;
|
||||
case DOUBLE:
|
||||
_local_val.double_val = SGRawValue<double>::DefaultValue;
|
||||
break;
|
||||
case STRING:
|
||||
case UNSPECIFIED:
|
||||
if (!_tied) {
|
||||
delete [] _local_val.string_val;
|
||||
}
|
||||
_local_val.string_val = 0;
|
||||
break;
|
||||
}
|
||||
delete _value.val;
|
||||
_value.val = 0;
|
||||
}
|
||||
_local_val.bool_val = SGRawValue<bool>::DefaultValue;
|
||||
break;
|
||||
case INT:
|
||||
if (_tied) {
|
||||
delete _value.int_val;
|
||||
_value.int_val = 0;
|
||||
}
|
||||
_local_val.int_val = SGRawValue<int>::DefaultValue;
|
||||
break;
|
||||
case LONG:
|
||||
if (_tied) {
|
||||
delete _value.long_val;
|
||||
_value.long_val = 0L;
|
||||
}
|
||||
_local_val.long_val = SGRawValue<long>::DefaultValue;
|
||||
break;
|
||||
case FLOAT:
|
||||
if (_tied) {
|
||||
delete _value.float_val;
|
||||
_value.float_val = 0;
|
||||
}
|
||||
_local_val.float_val = SGRawValue<float>::DefaultValue;
|
||||
break;
|
||||
case DOUBLE:
|
||||
if (_tied) {
|
||||
delete _value.double_val;
|
||||
_value.double_val = 0;
|
||||
}
|
||||
_local_val.double_val = SGRawValue<double>::DefaultValue;
|
||||
break;
|
||||
case STRING:
|
||||
case UNSPECIFIED:
|
||||
if (_tied) {
|
||||
delete _value.string_val;
|
||||
_value.string_val = 0;
|
||||
} else {
|
||||
delete [] _local_val.string_val;
|
||||
}
|
||||
_local_val.string_val = 0;
|
||||
break;
|
||||
}
|
||||
_tied = false;
|
||||
_type = NONE;
|
||||
_tied = false;
|
||||
_type = NONE;
|
||||
}
|
||||
|
||||
|
||||
@@ -665,6 +641,7 @@ SGPropertyNode::SGPropertyNode ()
|
||||
_listeners(0)
|
||||
{
|
||||
_local_val.string_val = 0;
|
||||
_value.val = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -682,6 +659,7 @@ SGPropertyNode::SGPropertyNode (const SGPropertyNode &node)
|
||||
_listeners(0) // CHECK!!
|
||||
{
|
||||
_local_val.string_val = 0;
|
||||
_value.val = 0;
|
||||
switch (_type) {
|
||||
case NONE:
|
||||
break;
|
||||
@@ -693,7 +671,7 @@ SGPropertyNode::SGPropertyNode (const SGPropertyNode &node)
|
||||
case BOOL:
|
||||
if (_tied) {
|
||||
_tied = true;
|
||||
_value.bool_val = node._value.bool_val->clone();
|
||||
_value.val = static_cast<SGRawValue<bool>*>(node._value.val)->clone();
|
||||
} else {
|
||||
_tied = false;
|
||||
set_bool(node.get_bool());
|
||||
@@ -702,7 +680,7 @@ SGPropertyNode::SGPropertyNode (const SGPropertyNode &node)
|
||||
case INT:
|
||||
if (_tied) {
|
||||
_tied = true;
|
||||
_value.int_val = node._value.int_val->clone();
|
||||
_value.val = static_cast<SGRawValue<int>*>(node._value.val)->clone();
|
||||
} else {
|
||||
_tied = false;
|
||||
set_int(node.get_int());
|
||||
@@ -711,7 +689,7 @@ SGPropertyNode::SGPropertyNode (const SGPropertyNode &node)
|
||||
case LONG:
|
||||
if (_tied) {
|
||||
_tied = true;
|
||||
_value.long_val = node._value.long_val->clone();
|
||||
_value.val = static_cast<SGRawValue<long>*>(node._value.val)->clone();
|
||||
} else {
|
||||
_tied = false;
|
||||
set_long(node.get_long());
|
||||
@@ -720,7 +698,7 @@ SGPropertyNode::SGPropertyNode (const SGPropertyNode &node)
|
||||
case FLOAT:
|
||||
if (_tied) {
|
||||
_tied = true;
|
||||
_value.float_val = node._value.float_val->clone();
|
||||
_value.val = static_cast<SGRawValue<float>*>(node._value.val)->clone();
|
||||
} else {
|
||||
_tied = false;
|
||||
set_float(node.get_float());
|
||||
@@ -729,7 +707,7 @@ SGPropertyNode::SGPropertyNode (const SGPropertyNode &node)
|
||||
case DOUBLE:
|
||||
if (_tied) {
|
||||
_tied = true;
|
||||
_value.double_val = node._value.double_val->clone();
|
||||
_value.val = static_cast<SGRawValue<double>*>(node._value.val)->clone();
|
||||
} else {
|
||||
_tied = false;
|
||||
set_double(node.get_double());
|
||||
@@ -739,7 +717,7 @@ SGPropertyNode::SGPropertyNode (const SGPropertyNode &node)
|
||||
case UNSPECIFIED:
|
||||
if (_tied) {
|
||||
_tied = true;
|
||||
_value.string_val = node._value.string_val->clone();
|
||||
_value.val = static_cast<SGRawValue<const char*>*>(node._value.val)->clone();
|
||||
} else {
|
||||
_tied = false;
|
||||
set_string(node.get_string());
|
||||
@@ -764,11 +742,11 @@ SGPropertyNode::SGPropertyNode (const char * name,
|
||||
_listeners(0)
|
||||
{
|
||||
int i = 0;
|
||||
_local_val.string_val = 0;
|
||||
_value.val = 0;
|
||||
_name = parse_name(name, i);
|
||||
if (i != int(strlen(name)) || name[0] == '.')
|
||||
throw string("plain name expected instead of '") + name + '\'';
|
||||
|
||||
_local_val.string_val = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1070,7 +1048,7 @@ SGPropertyNode::getPath (bool simplify) const
|
||||
return _path.c_str();
|
||||
}
|
||||
|
||||
SGPropertyNode::Type
|
||||
Type
|
||||
SGPropertyNode::getType () const
|
||||
{
|
||||
if (_type == ALIAS)
|
||||
@@ -1604,139 +1582,27 @@ SGPropertyNode::setUnspecifiedValue (const char * value)
|
||||
return result;
|
||||
}
|
||||
|
||||
bool
|
||||
SGPropertyNode::tie (const SGRawValue<bool> &rawValue, bool useDefault)
|
||||
template<>
|
||||
bool SGPropertyNode::tie (const SGRawValue<const char *> &rawValue,
|
||||
bool useDefault)
|
||||
{
|
||||
if (_type == ALIAS || _tied)
|
||||
return false;
|
||||
if (_type == ALIAS || _tied)
|
||||
return false;
|
||||
|
||||
useDefault = useDefault && hasValue();
|
||||
bool old_val = false;
|
||||
if (useDefault)
|
||||
old_val = getBoolValue();
|
||||
useDefault = useDefault && hasValue();
|
||||
std::string old_val;
|
||||
if (useDefault)
|
||||
old_val = getStringValue();
|
||||
clearValue();
|
||||
_type = STRING;
|
||||
_tied = true;
|
||||
_value.val = rawValue.clone();
|
||||
|
||||
clearValue();
|
||||
_type = BOOL;
|
||||
_tied = true;
|
||||
_value.bool_val = rawValue.clone();
|
||||
if (useDefault)
|
||||
setStringValue(old_val.c_str());
|
||||
|
||||
if (useDefault)
|
||||
setBoolValue(old_val);
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
SGPropertyNode::tie (const SGRawValue<int> &rawValue, bool useDefault)
|
||||
{
|
||||
if (_type == ALIAS || _tied)
|
||||
return false;
|
||||
|
||||
useDefault = useDefault && hasValue();
|
||||
int old_val = 0;
|
||||
if (useDefault)
|
||||
old_val = getIntValue();
|
||||
|
||||
clearValue();
|
||||
_type = INT;
|
||||
_tied = true;
|
||||
_value.int_val = rawValue.clone();
|
||||
|
||||
if (useDefault)
|
||||
setIntValue(old_val);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
SGPropertyNode::tie (const SGRawValue<long> &rawValue, bool useDefault)
|
||||
{
|
||||
if (_type == ALIAS || _tied)
|
||||
return false;
|
||||
|
||||
useDefault = useDefault && hasValue();
|
||||
long old_val = 0;
|
||||
if (useDefault)
|
||||
old_val = getLongValue();
|
||||
|
||||
clearValue();
|
||||
_type = LONG;
|
||||
_tied = true;
|
||||
_value.long_val = rawValue.clone();
|
||||
|
||||
if (useDefault)
|
||||
setLongValue(old_val);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
SGPropertyNode::tie (const SGRawValue<float> &rawValue, bool useDefault)
|
||||
{
|
||||
if (_type == ALIAS || _tied)
|
||||
return false;
|
||||
|
||||
useDefault = useDefault && hasValue();
|
||||
float old_val = 0.0;
|
||||
if (useDefault)
|
||||
old_val = getFloatValue();
|
||||
|
||||
clearValue();
|
||||
_type = FLOAT;
|
||||
_tied = true;
|
||||
_value.float_val = rawValue.clone();
|
||||
|
||||
if (useDefault)
|
||||
setFloatValue(old_val);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
SGPropertyNode::tie (const SGRawValue<double> &rawValue, bool useDefault)
|
||||
{
|
||||
if (_type == ALIAS || _tied)
|
||||
return false;
|
||||
|
||||
useDefault = useDefault && hasValue();
|
||||
double old_val = 0.0;
|
||||
if (useDefault)
|
||||
old_val = getDoubleValue();
|
||||
|
||||
clearValue();
|
||||
_type = DOUBLE;
|
||||
_tied = true;
|
||||
_value.double_val = rawValue.clone();
|
||||
|
||||
if (useDefault)
|
||||
setDoubleValue(old_val);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool
|
||||
SGPropertyNode::tie (const SGRawValue<const char *> &rawValue, bool useDefault)
|
||||
{
|
||||
if (_type == ALIAS || _tied)
|
||||
return false;
|
||||
|
||||
useDefault = useDefault && hasValue();
|
||||
string old_val;
|
||||
if (useDefault)
|
||||
old_val = getStringValue();
|
||||
|
||||
clearValue();
|
||||
_type = STRING;
|
||||
_tied = true;
|
||||
_value.string_val = rawValue.clone();
|
||||
|
||||
if (useDefault)
|
||||
setStringValue(old_val.c_str());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
SGPropertyNode::untie ()
|
||||
{
|
||||
@@ -1874,7 +1740,7 @@ SGPropertyNode::hasValue (const char * relative_path) const
|
||||
/**
|
||||
* Get the value type for another node.
|
||||
*/
|
||||
SGPropertyNode::Type
|
||||
Type
|
||||
SGPropertyNode::getType (const char * relative_path) const
|
||||
{
|
||||
const SGPropertyNode * node = getNode(relative_path);
|
||||
|
||||
@@ -30,6 +30,14 @@
|
||||
#include <simgear/structure/SGReferenced.hxx>
|
||||
#include <simgear/structure/SGSharedPtr.hxx>
|
||||
|
||||
// XXX This whole file should be in the simgear namespace, but I don't
|
||||
// have the guts yet...
|
||||
|
||||
namespace simgear
|
||||
{
|
||||
/**
|
||||
* Property value types.
|
||||
*/
|
||||
|
||||
#ifdef NONE
|
||||
#pragma warn A sloppy coder has defined NONE as a macro!
|
||||
@@ -76,6 +84,66 @@
|
||||
#undef STRING
|
||||
#endif
|
||||
|
||||
namespace props
|
||||
{
|
||||
enum Type {
|
||||
NONE = 0,
|
||||
ALIAS,
|
||||
BOOL,
|
||||
INT,
|
||||
LONG,
|
||||
FLOAT,
|
||||
DOUBLE,
|
||||
STRING,
|
||||
UNSPECIFIED
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
struct PropertyTraits
|
||||
{
|
||||
static const Type type_tag = NONE;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct PropertyTraits<bool>
|
||||
{
|
||||
static const Type type_tag = BOOL;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct PropertyTraits<int>
|
||||
{
|
||||
static const Type type_tag = INT;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct PropertyTraits<long>
|
||||
{
|
||||
static const Type type_tag = LONG;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct PropertyTraits<float>
|
||||
{
|
||||
static const Type type_tag = FLOAT;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct PropertyTraits<double>
|
||||
{
|
||||
static const Type type_tag = DOUBLE;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct PropertyTraits<const char *>
|
||||
{
|
||||
static const Type type_tag = STRING;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
@@ -90,6 +158,13 @@
|
||||
// a small performance hit for that.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** Base for virtual destructor
|
||||
*/
|
||||
class SGRawBase
|
||||
{
|
||||
public:
|
||||
virtual ~SGRawBase() {}
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstract base class for a raw value.
|
||||
@@ -129,7 +204,7 @@
|
||||
* @see SGRawValueMethodsIndexed
|
||||
*/
|
||||
template <class T>
|
||||
class SGRawValue
|
||||
class SGRawValue : public SGRawBase
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -194,6 +269,16 @@ public:
|
||||
virtual SGRawValue * clone () const = 0;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Default values for every type.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<> const bool SGRawValue<bool>::DefaultValue;
|
||||
template<> const int SGRawValue<int>::DefaultValue;
|
||||
template<> const long SGRawValue<long>::DefaultValue;
|
||||
template<> const float SGRawValue<float>::DefaultValue;
|
||||
template<> const double SGRawValue<double>::DefaultValue;
|
||||
template<> const char * const SGRawValue<const char *>::DefaultValue;
|
||||
|
||||
/**
|
||||
* A raw value bound to a pointer.
|
||||
@@ -484,22 +569,6 @@ public:
|
||||
MAX_STRING_LEN = 1024
|
||||
};
|
||||
|
||||
/**
|
||||
* Property value types.
|
||||
*/
|
||||
enum Type {
|
||||
NONE = 0,
|
||||
ALIAS,
|
||||
BOOL,
|
||||
INT,
|
||||
LONG,
|
||||
FLOAT,
|
||||
DOUBLE,
|
||||
STRING,
|
||||
UNSPECIFIED
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Access mode attributes.
|
||||
*
|
||||
@@ -550,7 +619,7 @@ public:
|
||||
/**
|
||||
* Test whether this node contains a primitive leaf value.
|
||||
*/
|
||||
bool hasValue () const { return (_type != NONE); }
|
||||
bool hasValue () const { return (_type != simgear::props::NONE); }
|
||||
|
||||
|
||||
/**
|
||||
@@ -729,7 +798,7 @@ public:
|
||||
/**
|
||||
* Test whether the node's leaf value is aliased to another's.
|
||||
*/
|
||||
bool isAlias () const { return (_type == ALIAS); }
|
||||
bool isAlias () const { return (_type == simgear::props::ALIAS); }
|
||||
|
||||
|
||||
/**
|
||||
@@ -874,7 +943,7 @@ public:
|
||||
/**
|
||||
* Get the type of leaf value, if any, for this node.
|
||||
*/
|
||||
Type getType () const;
|
||||
simgear::props::Type getType () const;
|
||||
|
||||
|
||||
/**
|
||||
@@ -972,42 +1041,11 @@ public:
|
||||
*/
|
||||
bool isTied () const { return _tied; }
|
||||
|
||||
|
||||
/**
|
||||
* Bind this node to an external bool source.
|
||||
*/
|
||||
bool tie (const SGRawValue<bool> &rawValue, bool useDefault = true);
|
||||
|
||||
|
||||
/**
|
||||
* Bind this node to an external int source.
|
||||
*/
|
||||
bool tie (const SGRawValue<int> &rawValue, bool useDefault = true);
|
||||
|
||||
|
||||
/**
|
||||
* Bind this node to an external long int source.
|
||||
*/
|
||||
bool tie (const SGRawValue<long> &rawValue, bool useDefault = true);
|
||||
|
||||
|
||||
/**
|
||||
* Bind this node to an external float source.
|
||||
*/
|
||||
bool tie (const SGRawValue<float> &rawValue, bool useDefault = true);
|
||||
|
||||
|
||||
/**
|
||||
* Bind this node to an external double source.
|
||||
*/
|
||||
bool tie (const SGRawValue<double> &rawValue, bool useDefault = true);
|
||||
|
||||
|
||||
/**
|
||||
* Bind this node to an external string source.
|
||||
*/
|
||||
bool tie (const SGRawValue<const char *> &rawValue, bool useDefault = true);
|
||||
|
||||
/**
|
||||
* Bind this node to an external source.
|
||||
*/
|
||||
template<typename T>
|
||||
bool tie(const SGRawValue<T> &rawValue, bool useDefault = true);
|
||||
|
||||
/**
|
||||
* Unbind this node from any external data source.
|
||||
@@ -1024,12 +1062,12 @@ public:
|
||||
/**
|
||||
* Get another node's type.
|
||||
*/
|
||||
Type getType (const char * relative_path) const;
|
||||
simgear::props::Type getType (const char * relative_path) const;
|
||||
|
||||
/**
|
||||
* Get another node's type.
|
||||
*/
|
||||
Type getType (const std::string& relative_path) const
|
||||
simgear::props::Type getType (const std::string& relative_path) const
|
||||
{ return getType(relative_path.c_str()); }
|
||||
|
||||
/**
|
||||
@@ -1423,19 +1461,14 @@ private:
|
||||
mutable std::string _path;
|
||||
mutable std::string _buffer;
|
||||
hash_table * _path_cache;
|
||||
Type _type;
|
||||
simgear::props::Type _type;
|
||||
bool _tied;
|
||||
int _attr;
|
||||
|
||||
// The right kind of pointer...
|
||||
union {
|
||||
SGPropertyNode * alias;
|
||||
SGRawValue<bool> * bool_val;
|
||||
SGRawValue<int> * int_val;
|
||||
SGRawValue<long> * long_val;
|
||||
SGRawValue<float> * float_val;
|
||||
SGRawValue<double> * double_val;
|
||||
SGRawValue<const char *> * string_val;
|
||||
SGRawBase* val;
|
||||
} _value;
|
||||
|
||||
union {
|
||||
@@ -1512,7 +1545,7 @@ private:
|
||||
|
||||
};
|
||||
|
||||
// Convenice functions for use in templates
|
||||
// Convenience functions for use in templates
|
||||
template<typename T>
|
||||
T getValue(const SGPropertyNode*);
|
||||
|
||||
@@ -1578,6 +1611,31 @@ inline bool setValue (SGPropertyNode* node, const std::string& value)
|
||||
return node->setStringValue(value.c_str());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool SGPropertyNode::tie(const SGRawValue<T> &rawValue, bool useDefault)
|
||||
{
|
||||
if (_type == simgear::props::ALIAS || _tied)
|
||||
return false;
|
||||
|
||||
useDefault = useDefault && hasValue();
|
||||
T old_val = SGRawValue<T>::DefaultValue;
|
||||
if (useDefault)
|
||||
old_val = getValue<T>(this);
|
||||
clearValue();
|
||||
_type = simgear::props::PropertyTraits<T>::type_tag;
|
||||
_tied = true;
|
||||
_value.val = rawValue.clone();
|
||||
|
||||
if (useDefault)
|
||||
setValue(this, old_val);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<>
|
||||
bool SGPropertyNode::tie (const SGRawValue<const char *> &rawValue,
|
||||
bool useDefault);
|
||||
|
||||
#endif // __PROPS_HXX
|
||||
|
||||
// end of props.hxx
|
||||
|
||||
@@ -400,25 +400,26 @@ void readProperties (const char *buf, const int size,
|
||||
* Return the type name.
|
||||
*/
|
||||
static const char *
|
||||
getTypeName (SGPropertyNode::Type type)
|
||||
getTypeName (simgear::props::Type type)
|
||||
{
|
||||
using namespace simgear::props;
|
||||
switch (type) {
|
||||
case SGPropertyNode::UNSPECIFIED:
|
||||
case UNSPECIFIED:
|
||||
return "unspecified";
|
||||
case SGPropertyNode::BOOL:
|
||||
case BOOL:
|
||||
return "bool";
|
||||
case SGPropertyNode::INT:
|
||||
case INT:
|
||||
return "int";
|
||||
case SGPropertyNode::LONG:
|
||||
case LONG:
|
||||
return "long";
|
||||
case SGPropertyNode::FLOAT:
|
||||
case FLOAT:
|
||||
return "float";
|
||||
case SGPropertyNode::DOUBLE:
|
||||
case DOUBLE:
|
||||
return "double";
|
||||
case SGPropertyNode::STRING:
|
||||
case STRING:
|
||||
return "string";
|
||||
case SGPropertyNode::ALIAS:
|
||||
case SGPropertyNode::NONE:
|
||||
case ALIAS:
|
||||
case NONE:
|
||||
return "unspecified";
|
||||
}
|
||||
|
||||
@@ -525,7 +526,7 @@ writeNode (ostream &output, const SGPropertyNode * node,
|
||||
output << " alias=\"" << node->getAliasTarget()->getPath()
|
||||
<< "\"/>" << endl;
|
||||
} else {
|
||||
if (node->getType() != SGPropertyNode::UNSPECIFIED)
|
||||
if (node->getType() != simgear::props::UNSPECIFIED)
|
||||
output << " type=\"" << getTypeName(node->getType()) << '"';
|
||||
output << '>';
|
||||
writeData(output, node->getStringValue());
|
||||
@@ -600,37 +601,38 @@ writeProperties (const string &file, const SGPropertyNode * start_node,
|
||||
bool
|
||||
copyProperties (const SGPropertyNode *in, SGPropertyNode *out)
|
||||
{
|
||||
using namespace simgear::props;
|
||||
bool retval = true;
|
||||
|
||||
// First, copy the actual value,
|
||||
// if any.
|
||||
if (in->hasValue()) {
|
||||
switch (in->getType()) {
|
||||
case SGPropertyNode::BOOL:
|
||||
case BOOL:
|
||||
if (!out->setBoolValue(in->getBoolValue()))
|
||||
retval = false;
|
||||
break;
|
||||
case SGPropertyNode::INT:
|
||||
case INT:
|
||||
if (!out->setIntValue(in->getIntValue()))
|
||||
retval = false;
|
||||
break;
|
||||
case SGPropertyNode::LONG:
|
||||
case LONG:
|
||||
if (!out->setLongValue(in->getLongValue()))
|
||||
retval = false;
|
||||
break;
|
||||
case SGPropertyNode::FLOAT:
|
||||
case FLOAT:
|
||||
if (!out->setFloatValue(in->getFloatValue()))
|
||||
retval = false;
|
||||
break;
|
||||
case SGPropertyNode::DOUBLE:
|
||||
case DOUBLE:
|
||||
if (!out->setDoubleValue(in->getDoubleValue()))
|
||||
retval = false;
|
||||
break;
|
||||
case SGPropertyNode::STRING:
|
||||
case STRING:
|
||||
if (!out->setStringValue(in->getStringValue()))
|
||||
retval = false;
|
||||
break;
|
||||
case SGPropertyNode::UNSPECIFIED:
|
||||
case UNSPECIFIED:
|
||||
if (!out->setUnspecifiedValue(in->getStringValue()))
|
||||
retval = false;
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user