diff --git a/simgear/props/props.cxx b/simgear/props/props.cxx index d690cbe6..d2691747 100644 --- a/simgear/props/props.cxx +++ b/simgear/props/props.cxx @@ -14,6 +14,7 @@ #include "vectorPropTemplates.hxx" #include +#include #include #include @@ -216,6 +217,26 @@ find_last_child (const char * name, const PropertyList& nodes) return index; } +/** + * Get first unused index for child nodes with the given name + */ +static int +first_unused_index( const char * name, + const PropertyList& nodes, + int min_index ) +{ + const char* nameEnd = name + strlen(name); + + for( int index = min_index; index < std::numeric_limits::max(); ++index ) + { + if( find_child(name, nameEnd, index, nodes) < 0 ) + return index; + } + + SG_LOG(SG_GENERAL, SG_ALERT, "Too much nodes: " << name); + return -1; +} + template inline SGPropertyNode* SGPropertyNode::getExistingChild (Itr begin, Itr end, int index, bool create) @@ -858,9 +879,11 @@ SGPropertyNode::getAliasTarget () const * create a non-const child by name after the last node with the same name. */ SGPropertyNode * -SGPropertyNode::addChild (const char * name) +SGPropertyNode::addChild(const char * name, int min_index, bool append) { - int pos = find_last_child(name, _children)+1; + int pos = append + ? std::max(find_last_child(name, _children) + 1, min_index) + : first_unused_index(name, _children, min_index); SGPropertyNode_ptr node; node = new SGPropertyNode(name, name + strlen(name), pos, this); diff --git a/simgear/props/props.hxx b/simgear/props/props.hxx index ff174c39..bf0e563e 100644 --- a/simgear/props/props.hxx +++ b/simgear/props/props.hxx @@ -748,7 +748,6 @@ public: */ static const int LAST_USED_ATTRIBUTE; - /** * Default constructor. */ @@ -853,8 +852,18 @@ public: /** * Create a child node after the last node with the same name. + * + * @param min_index Minimal index for new node (skips lower indices) + * @param append Whether to simply use the index after the last used index + * or use a lower, unused index if it exists */ - SGPropertyNode * addChild (const char * name); + SGPropertyNode * addChild ( const char* name, + int min_index = 0, + bool append = true ); + SGPropertyNode * addChild ( const std::string& name, + int min_index = 0, + bool append = true ) + { return addChild(name.c_str(), min_index, append); } /** * Get a child node by name and index.