Add VEC3D and VEC4D property types
Add "extended" argument to readProperties, which controls whether the vector property types are accepted by the XML reader.
This commit is contained in:
@@ -15,6 +15,8 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <simgear/math/SGMath.hxx>
|
||||
|
||||
#if PROPS_STANDALONE
|
||||
#include <iostream>
|
||||
#else
|
||||
@@ -78,6 +80,8 @@ 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 = "";
|
||||
template<> const SGVec3d SGRawValue<SGVec3d>::DefaultValue = SGVec3d();
|
||||
template<> const SGVec4d SGRawValue<SGVec4d>::DefaultValue = SGVec4d();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Local path normalization code.
|
||||
@@ -569,7 +573,13 @@ SGPropertyNode::make_string () const
|
||||
sstr << std::setprecision(10) << get_double();
|
||||
break;
|
||||
case EXTENDED:
|
||||
{
|
||||
Type realType = _value.val->getType();
|
||||
// Perhaps this should be done for all types?
|
||||
if (realType == VEC3D || realType == VEC4D)
|
||||
sstr.precision(10);
|
||||
static_cast<SGRawExtended*>(_value.val)->printOn(sstr);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return "";
|
||||
@@ -1544,6 +1554,12 @@ SGPropertyNode::setUnspecifiedValue (const char * value)
|
||||
case UNSPECIFIED:
|
||||
result = set_string(value);
|
||||
break;
|
||||
case VEC3D:
|
||||
result = static_cast<SGRawValue<SGVec3d>*>(_value.val)->setValue(parseString<SGVec3d>(value));
|
||||
break;
|
||||
case VEC4D:
|
||||
result = static_cast<SGRawValue<SGVec4d>*>(_value.val)->setValue(parseString<SGVec4d>(value));
|
||||
break;
|
||||
case NONE:
|
||||
default:
|
||||
break;
|
||||
@@ -2296,5 +2312,52 @@ SGPropertyChangeListener::unregister_property (SGPropertyNode * node)
|
||||
_properties.erase(it);
|
||||
}
|
||||
|
||||
namespace simgear
|
||||
{
|
||||
template<>
|
||||
std::ostream& SGRawBase<SGVec3d>::printOn(std::ostream& stream) const
|
||||
{
|
||||
const SGVec3d vec
|
||||
= static_cast<const SGRawValue<SGVec3d>*>(this)->getValue();
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
stream << vec[i];
|
||||
if (i < 2)
|
||||
stream << ' ';
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
template<>
|
||||
std::istream& readFrom<SGVec3d>(std::istream& stream, SGVec3d& result)
|
||||
{
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
stream >> result[i];
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
template<>
|
||||
std::ostream& SGRawBase<SGVec4d>::printOn(std::ostream& stream) const
|
||||
{
|
||||
const SGVec4d vec
|
||||
= static_cast<const SGRawValue<SGVec4d>*>(this)->getValue();
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
stream << vec[i];
|
||||
if (i < 3)
|
||||
stream << ' ';
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
template<>
|
||||
std::istream& readFrom<SGVec4d>(std::istream& stream, SGVec4d& result)
|
||||
{
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
stream >> result[i];
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// end of props.cxx
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#include <simgear/math/SGMathFwd.hxx>
|
||||
#include <simgear/structure/SGReferenced.hxx>
|
||||
#include <simgear/structure/SGSharedPtr.hxx>
|
||||
|
||||
@@ -63,6 +63,13 @@ inline T parseString(const std::string& str)
|
||||
return result;
|
||||
}
|
||||
|
||||
// Extended properties
|
||||
template<>
|
||||
std::istream& readFrom<SGVec3d>(std::istream& stream, SGVec3d& result);
|
||||
template<>
|
||||
std::istream& readFrom<SGVec4d>(std::istream& stream, SGVec4d& result);
|
||||
|
||||
|
||||
/**
|
||||
* Property value types.
|
||||
*/
|
||||
@@ -128,11 +135,14 @@ enum Type {
|
||||
DOUBLE,
|
||||
STRING,
|
||||
UNSPECIFIED,
|
||||
EXTENDED /**< The node's value is not stored in the property;
|
||||
EXTENDED, /**< The node's value is not stored in the property;
|
||||
* the actual value and type is retrieved from an
|
||||
* SGRawValue node. This type is never returned by @see
|
||||
* SGPropertyNode::getType.
|
||||
*/
|
||||
// Extended properties
|
||||
VEC3D,
|
||||
VEC4D
|
||||
};
|
||||
|
||||
template<typename T> struct PropertyTraits;
|
||||
@@ -153,6 +163,19 @@ DEFINTERNALPROP(double, DOUBLE);
|
||||
DEFINTERNALPROP(const char *, STRING);
|
||||
#undef DEFINTERNALPROP
|
||||
|
||||
template<>
|
||||
struct PropertyTraits<SGVec3d>
|
||||
{
|
||||
static const Type type_tag = VEC3D;
|
||||
enum { Internal = 0 };
|
||||
};
|
||||
|
||||
template<>
|
||||
struct PropertyTraits<SGVec4d>
|
||||
{
|
||||
static const Type type_tag = VEC4D;
|
||||
enum { Internal = 0 };
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -351,6 +374,8 @@ 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;
|
||||
template<> const SGVec3d SGRawValue<SGVec3d>::DefaultValue;
|
||||
template<> const SGVec4d SGRawValue<SGVec4d>::DefaultValue;
|
||||
|
||||
/**
|
||||
* A raw value bound to a pointer.
|
||||
@@ -658,6 +683,12 @@ std::istream& SGRawBase<T, 0>::readFrom(std::istream& stream)
|
||||
static_cast<SGRawValue<T>*>(this)->setValue(value);
|
||||
return stream;
|
||||
}
|
||||
|
||||
template<>
|
||||
std::ostream& SGRawBase<SGVec3d>::printOn(std::ostream& stream) const;
|
||||
template<>
|
||||
std::ostream& SGRawBase<SGVec4d>::printOn(std::ostream& stream) const;
|
||||
|
||||
|
||||
/**
|
||||
* The smart pointer that manage reference counting
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#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>
|
||||
|
||||
@@ -53,8 +54,11 @@ class PropsVisitor : public XMLVisitor
|
||||
{
|
||||
public:
|
||||
|
||||
PropsVisitor (SGPropertyNode * root, const string &base, int default_mode = 0)
|
||||
: _default_mode(default_mode), _root(root), _level(0), _base(base), _hasException(false) {}
|
||||
PropsVisitor (SGPropertyNode * root, const string &base, int default_mode = 0,
|
||||
bool extended = false)
|
||||
: _default_mode(default_mode), _root(root), _level(0), _base(base),
|
||||
_hasException(false), _extended(extended)
|
||||
{}
|
||||
|
||||
virtual ~PropsVisitor () {}
|
||||
|
||||
@@ -111,6 +115,7 @@ private:
|
||||
string _base;
|
||||
sg_io_exception _exception;
|
||||
bool _hasException;
|
||||
bool _extended;
|
||||
};
|
||||
|
||||
void
|
||||
@@ -168,7 +173,7 @@ PropsVisitor::startElement (const char * name, const XMLAttributes &atts)
|
||||
SGPath path(SGPath(_base).dir());
|
||||
path.append(attval);
|
||||
try {
|
||||
readProperties(path.str(), _root);
|
||||
readProperties(path.str(), _root, 0, _extended);
|
||||
} catch (sg_io_exception &e) {
|
||||
setException(e);
|
||||
}
|
||||
@@ -236,7 +241,7 @@ PropsVisitor::startElement (const char * name, const XMLAttributes &atts)
|
||||
SGPath path(SGPath(_base).dir());
|
||||
path.append(attval);
|
||||
try {
|
||||
readProperties(path.str(), node);
|
||||
readProperties(path.str(), node, 0, _extended);
|
||||
} catch (sg_io_exception &e) {
|
||||
setException(e);
|
||||
}
|
||||
@@ -276,6 +281,12 @@ PropsVisitor::endElement (const char * name)
|
||||
ret = st.node->setDoubleValue(strtod(_data.c_str(), 0));
|
||||
} else if (st.type == "string") {
|
||||
ret = st.node->setStringValue(_data.c_str());
|
||||
} else if (st.type == "vec3d" && _extended) {
|
||||
ret = st.node
|
||||
->setValue(simgear::parseString<SGVec3d>(_data));
|
||||
} else if (st.type == "vec4d" && _extended) {
|
||||
ret = st.node
|
||||
->setValue(simgear::parseString<SGVec4d>(_data));
|
||||
} else if (st.type == "unspecified") {
|
||||
ret = st.node->setUnspecifiedValue(_data.c_str());
|
||||
} else if (_level == 1) {
|
||||
@@ -345,9 +356,9 @@ PropsVisitor::warning (const char * message, int line, int column)
|
||||
*/
|
||||
void
|
||||
readProperties (istream &input, SGPropertyNode * start_node,
|
||||
const string &base, int default_mode)
|
||||
const string &base, int default_mode, bool extended)
|
||||
{
|
||||
PropsVisitor visitor(start_node, base, default_mode);
|
||||
PropsVisitor visitor(start_node, base, default_mode, extended);
|
||||
readXML(input, visitor, base);
|
||||
if (visitor.hasException())
|
||||
throw visitor.getException();
|
||||
@@ -363,9 +374,9 @@ readProperties (istream &input, SGPropertyNode * start_node,
|
||||
*/
|
||||
void
|
||||
readProperties (const string &file, SGPropertyNode * start_node,
|
||||
int default_mode)
|
||||
int default_mode, bool extended)
|
||||
{
|
||||
PropsVisitor visitor(start_node, file, default_mode);
|
||||
PropsVisitor visitor(start_node, file, default_mode, extended);
|
||||
readXML(file, visitor);
|
||||
if (visitor.hasException())
|
||||
throw visitor.getException();
|
||||
@@ -381,9 +392,10 @@ readProperties (const string &file, SGPropertyNode * start_node,
|
||||
* @return true if the read succeeded, false otherwise.
|
||||
*/
|
||||
void readProperties (const char *buf, const int size,
|
||||
SGPropertyNode * start_node, int default_mode)
|
||||
SGPropertyNode * start_node, int default_mode,
|
||||
bool extended)
|
||||
{
|
||||
PropsVisitor visitor(start_node, "", default_mode);
|
||||
PropsVisitor visitor(start_node, "", default_mode, extended);
|
||||
readXML(buf, size, visitor);
|
||||
if (visitor.hasException())
|
||||
throw visitor.getException();
|
||||
@@ -418,6 +430,10 @@ getTypeName (simgear::props::Type type)
|
||||
return "double";
|
||||
case STRING:
|
||||
return "string";
|
||||
case VEC3D:
|
||||
return "vec3d";
|
||||
case VEC4D:
|
||||
return "vec4d";
|
||||
case ALIAS:
|
||||
case NONE:
|
||||
return "unspecified";
|
||||
@@ -636,6 +652,14 @@ copyProperties (const SGPropertyNode *in, SGPropertyNode *out)
|
||||
if (!out->setUnspecifiedValue(in->getStringValue()))
|
||||
retval = false;
|
||||
break;
|
||||
case VEC3D:
|
||||
if (!out->setValue(in->getValue<SGVec3d>()))
|
||||
retval = false;
|
||||
break;
|
||||
case VEC4D:
|
||||
if (!out->setValue(in->getValue<SGVec4d>()))
|
||||
retval = false;
|
||||
break;
|
||||
default:
|
||||
if (in->isAlias())
|
||||
break;
|
||||
|
||||
@@ -26,21 +26,23 @@
|
||||
* Read properties from an XML input stream.
|
||||
*/
|
||||
void readProperties (std::istream &input, SGPropertyNode * start_node,
|
||||
const std::string &base = "", int default_mode = 0);
|
||||
const std::string &base = "", int default_mode = 0,
|
||||
bool extended = false);
|
||||
|
||||
|
||||
/**
|
||||
* Read properties from an XML file.
|
||||
*/
|
||||
void readProperties (const std::string &file, SGPropertyNode * start_node,
|
||||
int default_mode = 0);
|
||||
int default_mode = 0, bool extended = false);
|
||||
|
||||
|
||||
/**
|
||||
* Read properties from an in-memory buffer.
|
||||
*/
|
||||
void readProperties (const char *buf, const int size,
|
||||
SGPropertyNode * start_node, int default_mode = 0);
|
||||
SGPropertyNode * start_node, int default_mode = 0,
|
||||
bool extended = false);
|
||||
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user