#include <stdio.h>
#include <string.h>
+#include <simgear/math/SGMath.hxx>
+
#if PROPS_STANDALONE
#include <iostream>
#else
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();
\f
////////////////////////////////////////////////////////////////////////
// Local path normalization code.
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 "";
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;
_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
#endif
-
+#include <simgear/math/SGMathFwd.hxx>
#include <simgear/structure/SGReferenced.hxx>
#include <simgear/structure/SGSharedPtr.hxx>
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.
*/
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;
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 };
+};
}
}
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.
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;
+
\f
/**
* The smart pointer that manage reference counting
#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>
{
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 () {}
string _base;
sg_io_exception _exception;
bool _hasException;
+ bool _extended;
};
void
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);
}
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);
}
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) {
*/
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();
*/
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();
* @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();
return "double";
case STRING:
return "string";
+ case VEC3D:
+ return "vec3d";
+ case VEC4D:
+ return "vec4d";
case ALIAS:
case NONE:
return "unspecified";
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;
* 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);
/**