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:
timoore
2009-07-15 23:08:01 +00:00
committed by Tim Moore
parent ff17b44a41
commit d4c6530a72
4 changed files with 135 additions and 15 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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);
/**