From d4c6530a7222deafd2a7dac67f3c88d461766235 Mon Sep 17 00:00:00 2001 From: timoore Date: Wed, 15 Jul 2009 23:08:01 +0000 Subject: [PATCH] Add VEC3D and VEC4D property types Add "extended" argument to readProperties, which controls whether the vector property types are accepted by the XML reader. --- simgear/props/props.cxx | 63 ++++++++++++++++++++++++++++++++++++++ simgear/props/props.hxx | 35 +++++++++++++++++++-- simgear/props/props_io.cxx | 44 ++++++++++++++++++++------ simgear/props/props_io.hxx | 8 +++-- 4 files changed, 135 insertions(+), 15 deletions(-) diff --git a/simgear/props/props.cxx b/simgear/props/props.cxx index 042275e4..9db543b6 100644 --- a/simgear/props/props.cxx +++ b/simgear/props/props.cxx @@ -15,6 +15,8 @@ #include #include +#include + #if PROPS_STANDALONE #include #else @@ -78,6 +80,8 @@ template<> const long SGRawValue::DefaultValue = 0L; template<> const float SGRawValue::DefaultValue = 0.0; template<> const double SGRawValue::DefaultValue = 0.0L; template<> const char * const SGRawValue::DefaultValue = ""; +template<> const SGVec3d SGRawValue::DefaultValue = SGVec3d(); +template<> const SGVec4d SGRawValue::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(_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*>(_value.val)->setValue(parseString(value)); + break; + case VEC4D: + result = static_cast*>(_value.val)->setValue(parseString(value)); + break; case NONE: default: break; @@ -2296,5 +2312,52 @@ SGPropertyChangeListener::unregister_property (SGPropertyNode * node) _properties.erase(it); } +namespace simgear +{ +template<> +std::ostream& SGRawBase::printOn(std::ostream& stream) const +{ + const SGVec3d vec + = static_cast*>(this)->getValue(); + for (int i = 0; i < 3; ++i) { + stream << vec[i]; + if (i < 2) + stream << ' '; + } + return stream; +} + +template<> +std::istream& readFrom(std::istream& stream, SGVec3d& result) +{ + for (int i = 0; i < 3; ++i) { + stream >> result[i]; + } + return stream; +} + +template<> +std::ostream& SGRawBase::printOn(std::ostream& stream) const +{ + const SGVec4d vec + = static_cast*>(this)->getValue(); + for (int i = 0; i < 4; ++i) { + stream << vec[i]; + if (i < 3) + stream << ' '; + } + return stream; +} + +template<> +std::istream& readFrom(std::istream& stream, SGVec4d& result) +{ + for (int i = 0; i < 4; ++i) { + stream >> result[i]; + } + return stream; +} + +} // end of props.cxx diff --git a/simgear/props/props.hxx b/simgear/props/props.hxx index 960d2aea..8e3647ee 100644 --- a/simgear/props/props.hxx +++ b/simgear/props/props.hxx @@ -30,7 +30,7 @@ #endif - +#include #include #include @@ -63,6 +63,13 @@ inline T parseString(const std::string& str) return result; } +// Extended properties +template<> +std::istream& readFrom(std::istream& stream, SGVec3d& result); +template<> +std::istream& readFrom(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 struct PropertyTraits; @@ -153,6 +163,19 @@ DEFINTERNALPROP(double, DOUBLE); DEFINTERNALPROP(const char *, STRING); #undef DEFINTERNALPROP +template<> +struct PropertyTraits +{ + static const Type type_tag = VEC3D; + enum { Internal = 0 }; +}; + +template<> +struct PropertyTraits +{ + static const Type type_tag = VEC4D; + enum { Internal = 0 }; +}; } } @@ -351,6 +374,8 @@ template<> const long SGRawValue::DefaultValue; template<> const float SGRawValue::DefaultValue; template<> const double SGRawValue::DefaultValue; template<> const char * const SGRawValue::DefaultValue; +template<> const SGVec3d SGRawValue::DefaultValue; +template<> const SGVec4d SGRawValue::DefaultValue; /** * A raw value bound to a pointer. @@ -658,6 +683,12 @@ std::istream& SGRawBase::readFrom(std::istream& stream) static_cast*>(this)->setValue(value); return stream; } + +template<> +std::ostream& SGRawBase::printOn(std::ostream& stream) const; +template<> +std::ostream& SGRawBase::printOn(std::ostream& stream) const; + /** * The smart pointer that manage reference counting diff --git a/simgear/props/props_io.cxx b/simgear/props/props_io.cxx index 881abe8c..f6aa8d78 100644 --- a/simgear/props/props_io.cxx +++ b/simgear/props/props_io.cxx @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -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(_data)); + } else if (st.type == "vec4d" && _extended) { + ret = st.node + ->setValue(simgear::parseString(_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())) + retval = false; + break; + case VEC4D: + if (!out->setValue(in->getValue())) + retval = false; + break; default: if (in->isAlias()) break; diff --git a/simgear/props/props_io.hxx b/simgear/props/props_io.hxx index c8f46997..b619c04b 100644 --- a/simgear/props/props_io.hxx +++ b/simgear/props/props_io.hxx @@ -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); /** -- 2.39.5