diff --git a/simgear/props/props.cxx b/simgear/props/props.cxx index 9817d547..da3c482a 100644 --- a/simgear/props/props.cxx +++ b/simgear/props/props.cxx @@ -11,8 +11,6 @@ #endif #include "props.hxx" -#include "PropertyInterpolationMgr.hxx" -#include "vectorPropTemplates.hxx" #include #include @@ -24,31 +22,30 @@ #include #include -#include -#include -#include -#include -#include -#include - #if PROPS_STANDALONE -#include +# include +using std::cerr; #else +# include +# include +# include +# include +# include +# include +# include +# include -#include -#include +# include "PropertyInterpolationMgr.hxx" +# include "vectorPropTemplates.hxx" -#if ( _MSC_VER == 1200 ) +# if ( _MSC_VER == 1200 ) // MSVC 6 is buggy, and needs something strange here using std::vector; using std::vector; using std::vector; -#endif +# endif #endif -#if PROPS_STANDALONE -using std::cerr; -#endif using std::endl; using std::find; using std::sort; @@ -84,6 +81,14 @@ public: // Local path normalization code. //////////////////////////////////////////////////////////////////////// +#if PROPS_STANDALONE +struct PathComponent +{ + string name; + int index; +}; +#endif + /** * Parse the name for a path component. * @@ -146,10 +151,149 @@ inline bool validateName(const std::string& name) return false; if (!isalpha(name[0]) && name[0] != '_') return false; +#if PROPS_STANDALONE + std::string is_any_of("_-."); + bool rv = true; + for(unsigned i=1; i &components) +{ + int pos = 0; + int max = (int)path.size(); + + // Check for initial '/' + if (path[pos] == '/') { + PathComponent root; + root.name = ""; + root.index = -1; + components.push_back(root); + pos++; + while (pos < max && path[pos] == '/') + pos++; + } + + while (pos < max) { + components.push_back(parse_component(path, pos)); + while (pos < max && path[pos] == '/') + pos++; + } +} +#endif + + //////////////////////////////////////////////////////////////////////// // Other static utility functions. //////////////////////////////////////////////////////////////////////// @@ -182,6 +326,13 @@ static int find_child (Itr begin, Itr end, int index, const PropertyList& nodes) { size_t nNodes = nodes.size(); +#if PROPS_STANDALONE + for (int i = 0; i < nNodes; i++) { + SGPropertyNode * node = nodes[i]; + if (node->getIndex() == index && compare_strings(node->getName(), begin)) + return i; + } +#else boost::iterator_range name(begin, end); for (size_t i = 0; i < nNodes; i++) { SGPropertyNode * node = nodes[i]; @@ -191,6 +342,7 @@ find_child (Itr begin, Itr end, int index, const PropertyList& nodes) if (node->getIndex() == index && boost::equals(node->getName(), name)) return static_cast(i); } +#endif return -1; } @@ -333,11 +485,57 @@ find_node_aux(SGPropertyNode * current, SplitItr& itr, bool create, // Internal function for parsing property paths. last_index provides // and index value for the last node name token, if supplied. +#if PROPS_STANDALONE +static SGPropertyNode * +find_node (SGPropertyNode * current, + const vector &components, + int position, + bool create) +{ + // Run off the end of the list + if (current == 0) { + return 0; + } + + // Success! This is the one we want. + else if (position >= (int)components.size()) { + return (current->getAttribute(SGPropertyNode::REMOVED) ? 0 : current); + } + + // Empty component means root. + else if (components[position].name == "") { + return find_node(current->getRootNode(), components, position + 1, create); + } + + // . means current directory + else if (components[position].name == ".") { + return find_node(current, components, position + 1, create); + } + + // .. means parent directory + else if (components[position].name == "..") { + SGPropertyNode * parent = current->getParent(); + if (parent == 0) + throw string("Attempt to move past root with '..'"); + else + return find_node(parent, components, position + 1, create); + } + + // Otherwise, a child name + else { + SGPropertyNode * child = + current->getChild(components[position].name.c_str(), + components[position].index, + create); + return find_node(child, components, position + 1, create); + } +} +#else template SGPropertyNode* find_node (SGPropertyNode * current, const Range& path, - bool create, + bool create, int last_index = -1) { using namespace boost; @@ -351,6 +549,7 @@ find_node (SGPropertyNode * current, else return find_node_aux(current, itr, create, last_index); } +#endif //////////////////////////////////////////////////////////////////////// // Private methods from SGPropertyNode (may be inlined for speed). @@ -611,13 +810,8 @@ SGPropertyNode::make_string () const void SGPropertyNode::trace_write () const { -#if PROPS_STANDALONE - cerr << "TRACE: Write node " << getPath () << ", value \"" - << make_string() << '"' << endl; -#else SG_LOG(SG_GENERAL, SG_ALERT, "TRACE: Write node " << getPath() << ", value \"" << make_string() << '"'); -#endif } /** @@ -626,13 +820,8 @@ SGPropertyNode::trace_write () const void SGPropertyNode::trace_read () const { -#if PROPS_STANDALONE - cerr << "TRACE: Write node " << getPath () << ", value \"" - << make_string() << '"' << endl; -#else SG_LOG(SG_GENERAL, SG_ALERT, "TRACE: Read node " << getPath() << ", value \"" << make_string() << '"'); -#endif } //////////////////////////////////////////////////////////////////////// @@ -786,8 +975,6 @@ SGPropertyNode::alias (SGPropertyNode * target) return true; } -#if PROPS_STANDALONE -#else if (!target) { SG_LOG(SG_GENERAL, SG_ALERT, @@ -809,7 +996,6 @@ SGPropertyNode::alias (SGPropertyNode * target) SG_LOG(SG_GENERAL, SG_ALERT, "Failed to create alias at " << target->getPath() << ". " "Source " << getPath() << " is a tied property."); } -#endif return false; } @@ -957,11 +1143,18 @@ SGPropertyNode::getChild (const char * name, int index, bool create) SGPropertyNode * SGPropertyNode::getChild (const std::string& name, int index, bool create) { +#if PROPS_STANDALONE + const char *n = name.c_str(); + int pos = find_child(n, n + strlen(n), index, _children); + if (pos >= 0) { + return _children[pos]; +#else SGPropertyNode* node = getExistingChild(name.begin(), name.end(), index); if (node) { return node; +#endif } else if (create) { - node = new SGPropertyNode(name, index, this); + SGPropertyNode* node = new SGPropertyNode(name, index, this); _children.push_back(node); fireChildAdded(node); return node; @@ -1635,12 +1828,14 @@ SGPropertyNode::setUnspecifiedValue (const char * value) case props::UNSPECIFIED: result = set_string(value); break; +#if !PROPS_STANDALONE case props::VEC3D: result = static_cast*>(_value.val)->setValue(parseString(value)); break; case props::VEC4D: result = static_cast*>(_value.val)->setValue(parseString(value)); break; +#endif case props::NONE: default: break; @@ -1652,6 +1847,7 @@ SGPropertyNode::setUnspecifiedValue (const char * value) } //------------------------------------------------------------------------------ +#if !PROPS_STANDALONE bool SGPropertyNode::interpolate( const std::string& type, const SGPropertyNode& target, double duration, @@ -1701,6 +1897,7 @@ simgear::PropertyInterpolationMgr* SGPropertyNode::getInterpolationMgr() } simgear::PropertyInterpolationMgr* SGPropertyNode::_interpolation_mgr = 0; +#endif //------------------------------------------------------------------------------ std::ostream& SGPropertyNode::printOn(std::ostream& stream) const @@ -1854,20 +2051,37 @@ SGPropertyNode::getRootNode () const SGPropertyNode * SGPropertyNode::getNode (const char * relative_path, bool create) { +#if PROPS_STANDALONE + vector components; + parse_path(relative_path, components); + return find_node(this, components, 0, create); + +#else using namespace boost; return find_node(this, make_iterator_range(relative_path, relative_path + strlen(relative_path)), create); +#endif } SGPropertyNode * SGPropertyNode::getNode (const char * relative_path, int index, bool create) { +#if PROPS_STANDALONE + vector components; + parse_path(relative_path, components); + if (components.size() > 0) + components.back().index = index; + return find_node(this, components, 0, create); + +#else using namespace boost; + return find_node(this, make_iterator_range(relative_path, relative_path + strlen(relative_path)), create, index); +#endif } const SGPropertyNode * @@ -2315,6 +2529,7 @@ SGPropertyChangeListener::unregister_property (SGPropertyNode * node) _properties.erase(it); } +#if !PROPS_STANDALONE template<> std::ostream& SGRawBase::printOn(std::ostream& stream) const { @@ -2351,9 +2566,11 @@ std::ostream& SGRawBase::printOn(std::ostream& stream) const } return stream; } +#endif namespace simgear { +#if !PROPS_STANDALONE template<> std::istream& readFrom(std::istream& stream, SGVec4d& result) { @@ -2362,6 +2579,7 @@ std::istream& readFrom(std::istream& stream, SGVec4d& result) } return stream; } +#endif namespace { @@ -2389,10 +2607,12 @@ bool compareNodeValue(const SGPropertyNode& lhs, const SGPropertyNode& rhs) case props::STRING: case props::UNSPECIFIED: return !strcmp(lhs.getStringValue(), rhs.getStringValue()); +#if !PROPS_STANDALONE case props::VEC3D: return lhs.getValue() == rhs.getValue(); case props::VEC4D: return lhs.getValue() == rhs.getValue(); +#endif default: return false; } @@ -2449,10 +2669,10 @@ struct PropertyPlaceLess { } }; +#if !PROPS_STANDALONE size_t hash_value(const SGPropertyNode& node) { using namespace boost; - if (node.nChildren() == 0) { switch (node.getType()) { case props::NONE: @@ -2503,5 +2723,6 @@ size_t hash_value(const SGPropertyNode& node) return seed; } } +#endif // end of props.cxx diff --git a/simgear/props/props.hxx b/simgear/props/props.hxx index 52a2bf91..595e013d 100644 --- a/simgear/props/props.hxx +++ b/simgear/props/props.hxx @@ -22,24 +22,54 @@ #include #include -#include -#include - -#if PROPS_STANDALONE -#else #include -#include +#if PROPS_STANDALONE +// taken from: boost/utility/enable_if.hpp +#ifndef SG_LOG +# define SG_GENERAL 0 +# define SG_ALERT 0 +# define SG_WARN 1 +# define SG_LOG(type, level, message) (type) ? (std::cerr < + struct enable_if_c { + typedef T type; + }; + template + struct enable_if_c {}; -#include -#include + template + struct enable_if : public enable_if_c {}; + + template + struct disable_if_c { + typedef T type; + }; + + template + struct disable_if_c {}; + + template + struct disable_if : public disable_if_c {}; +} +#else +# include +# include + +# include +# include +# include +#endif #include #include // XXX This whole file should be in the simgear namespace, but I don't // have the guts yet... +using namespace std; + namespace simgear { @@ -1275,6 +1305,7 @@ public: return ret; } +#if !PROPS_STANDALONE /** * Interpolate current value to target value within given time. * @@ -1310,6 +1341,7 @@ public: * Get the interpolation manager */ static simgear::PropertyInterpolationMgr* getInterpolationMgr(); +#endif /** * Print the value of the property to a stream. @@ -1807,7 +1839,11 @@ private: // Convenience functions for use in templates template +#if PROPS_STANDALONE +T +#else typename boost::disable_if, T>::type +#endif getValue(const SGPropertyNode*); template<> @@ -1871,7 +1907,11 @@ namespace simgear /** Extract enum from SGPropertyNode */ template +#if PROPS_STANDALONE +inline T +#else inline typename boost::enable_if, T>::type +#endif getValue(const SGPropertyNode* node) { typedef simgear::enum_traits Traits;