mirror of
https://github.com/wesnoth/wesnoth
synced 2025-05-19 18:22:09 +00:00
made simple wml ordered properly
This commit is contained in:
parent
809feea121
commit
23a329f25b
@ -162,11 +162,12 @@ node::node(document& doc, node* parent, const char** str, int depth) :
|
||||
throw error("unterminated element");
|
||||
}
|
||||
|
||||
child_list& list = get_children(string_span(s, end - s));
|
||||
const int list_index = get_children(string_span(s, end - s));
|
||||
|
||||
s = end + 1;
|
||||
|
||||
list.push_back(new node(doc, this, str, depth+1));
|
||||
children_[list_index].second.push_back(new node(doc, this, str, depth+1));
|
||||
ordered_children_.push_back(node_pos(list_index, children_[list_index].second.size() - 1));
|
||||
|
||||
break;
|
||||
}
|
||||
@ -339,12 +340,14 @@ node& node::add_child_at(const char* name, size_t index)
|
||||
{
|
||||
set_dirty();
|
||||
|
||||
child_list& list = get_children(name);
|
||||
const int list_index = get_children(name);
|
||||
child_list& list = children_[list_index].second;
|
||||
if(index > list.size()) {
|
||||
index = list.size();
|
||||
}
|
||||
|
||||
list.insert(list.begin() + index, new node(*doc_, this));
|
||||
insert_ordered_child(list_index, index);
|
||||
return *list[index];
|
||||
}
|
||||
|
||||
@ -353,8 +356,10 @@ node& node::add_child(const char* name)
|
||||
{
|
||||
set_dirty();
|
||||
|
||||
child_list& list = get_children(name);
|
||||
const int list_index = get_children(name);
|
||||
child_list& list = children_[list_index].second;
|
||||
list.push_back(new node(*doc_, this));
|
||||
ordered_children_.push_back(node_pos(list_index, list.size() - 1));
|
||||
return *list.back();
|
||||
}
|
||||
|
||||
@ -373,14 +378,64 @@ void node::remove_child(const string_span& name, size_t index)
|
||||
return;
|
||||
}
|
||||
|
||||
remove_ordered_child(itor - children_.begin(), index);
|
||||
|
||||
debug_delete(list[index]);
|
||||
list.erase(list.begin() + index);
|
||||
|
||||
if(list.empty()) {
|
||||
remove_ordered_child_list(itor - children_.begin());
|
||||
children_.erase(itor);
|
||||
}
|
||||
}
|
||||
|
||||
void node::insert_ordered_child(int child_map_index, int child_list_index)
|
||||
{
|
||||
|
||||
std::vector<node_pos>::iterator i = ordered_children_.begin();
|
||||
while(i != ordered_children_.end()) {
|
||||
if(i->child_map_index == child_map_index && i->child_list_index > child_list_index) {
|
||||
i->child_list_index++;
|
||||
} else if(i->child_map_index == child_map_index && i->child_list_index == child_list_index) {
|
||||
i->child_list_index++;
|
||||
i = ordered_children_.insert(i, node_pos(child_map_index, child_list_index));
|
||||
++i;
|
||||
}
|
||||
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
void node::remove_ordered_child(int child_map_index, int child_list_index)
|
||||
{
|
||||
std::vector<node_pos>::iterator i = ordered_children_.begin();
|
||||
while(i != ordered_children_.end()) {
|
||||
if(i->child_map_index == child_map_index && i->child_list_index == child_list_index) {
|
||||
i = ordered_children_.erase(i);
|
||||
} else {
|
||||
if(i->child_map_index == child_map_index && i->child_list_index > child_list_index) {
|
||||
i->child_list_index--;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void node::remove_ordered_child_list(int child_map_index)
|
||||
{
|
||||
std::vector<node_pos>::iterator i = ordered_children_.begin();
|
||||
while(i != ordered_children_.end()) {
|
||||
if(i->child_map_index == child_map_index) {
|
||||
i = ordered_children_.erase(i);
|
||||
} else {
|
||||
if(i->child_map_index > child_map_index) {
|
||||
i->child_map_index--;
|
||||
}
|
||||
i->child_map_index--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void node::remove_child(const char* name, size_t index)
|
||||
{
|
||||
remove_child(string_span(name), index);
|
||||
@ -425,21 +480,21 @@ const node::child_list& node::children(const char* name) const
|
||||
return empty;
|
||||
}
|
||||
|
||||
node::child_list& node::get_children(const char* name)
|
||||
int node::get_children(const char* name)
|
||||
{
|
||||
return get_children(string_span(name));
|
||||
}
|
||||
|
||||
node::child_list& node::get_children(const string_span& name)
|
||||
int node::get_children(const string_span& name)
|
||||
{
|
||||
for(child_map::iterator i = children_.begin(); i != children_.end(); ++i) {
|
||||
if(i->first == name) {
|
||||
return i->second;
|
||||
return i - children_.begin();
|
||||
}
|
||||
}
|
||||
|
||||
children_.push_back(child_pair(string_span(name), child_list()));
|
||||
return children_.back().second;
|
||||
return children_.size() - 1;
|
||||
}
|
||||
|
||||
node::child_map::const_iterator node::find_in_map(const child_map& m, const string_span& attr)
|
||||
@ -487,13 +542,17 @@ int node::output_size() const
|
||||
res += i->first.size() + i->second.size() + 4;
|
||||
}
|
||||
|
||||
int count_children = 0;
|
||||
for(child_map::const_iterator i = children_.begin(); i != children_.end(); ++i) {
|
||||
for(child_list::const_iterator j = i->second.begin(); j != i->second.end(); ++j) {
|
||||
res += i->first.size()*2 + 7;
|
||||
res += (*j)->output_size();
|
||||
++count_children;
|
||||
}
|
||||
}
|
||||
|
||||
assert(count_children == ordered_children_.size());
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -541,23 +600,24 @@ void node::output(char*& buf)
|
||||
*buf++ = '\n';
|
||||
}
|
||||
|
||||
for(child_map::iterator i = children_.begin(); i != children_.end(); ++i) {
|
||||
assert(i->second.empty() == false);
|
||||
for(child_list::iterator j = i->second.begin(); j != i->second.end(); ++j) {
|
||||
*buf++ = '[';
|
||||
memcpy(buf, i->first.begin(), i->first.size());
|
||||
i->first = string_span(buf, i->first.size());
|
||||
buf += i->first.size();
|
||||
*buf++ = ']';
|
||||
*buf++ = '\n';
|
||||
(*j)->output(buf);
|
||||
*buf++ = '[';
|
||||
*buf++ = '/';
|
||||
memcpy(buf, i->first.begin(), i->first.size());
|
||||
buf += i->first.size();
|
||||
*buf++ = ']';
|
||||
*buf++ = '\n';
|
||||
}
|
||||
for(std::vector<node_pos>::const_iterator i = ordered_children_.begin();
|
||||
i != ordered_children_.end(); ++i) {
|
||||
assert(i->child_map_index < children_.size());
|
||||
assert(i->child_list_index < children_[i->child_map_index].second.size());
|
||||
string_span& attr = children_[i->child_map_index].first;
|
||||
*buf++ = '[';
|
||||
memcpy(buf, attr.begin(), attr.size());
|
||||
attr = string_span(buf, attr.size());
|
||||
buf += attr.size();
|
||||
*buf++ = ']';
|
||||
*buf++ = '\n';
|
||||
children_[i->child_map_index].second[i->child_list_index]->output(buf);
|
||||
*buf++ = '[';
|
||||
*buf++ = '/';
|
||||
memcpy(buf, attr.begin(), attr.size());
|
||||
buf += attr.size();
|
||||
*buf++ = ']';
|
||||
*buf++ = '\n';
|
||||
}
|
||||
|
||||
output_cache_ = string_span(begin, buf - begin);
|
||||
@ -574,17 +634,13 @@ void node::copy_into(node& n) const
|
||||
n.set_attr(key, value);
|
||||
}
|
||||
|
||||
for(child_map::const_iterator i = children_.begin(); i != children_.end(); ++i) {
|
||||
if(i->second.empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
char* buf = i->first.duplicate();
|
||||
for(std::vector<node_pos>::const_iterator i = ordered_children_.begin();
|
||||
i != ordered_children_.end(); ++i) {
|
||||
assert(i->child_map_index < children_.size());
|
||||
assert(i->child_list_index < children_[i->child_map_index].second.size());
|
||||
char* buf = children_[i->child_map_index].first.duplicate();
|
||||
n.doc_->take_ownership_of_buffer(buf);
|
||||
|
||||
for(child_list::const_iterator j = i->second.begin(); j != i->second.end(); ++j) {
|
||||
(*j)->copy_into(n.add_child(buf));
|
||||
}
|
||||
children_[i->child_map_index].second[i->child_list_index]->copy_into(n.add_child(buf));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -144,8 +144,8 @@ private:
|
||||
node(const node&);
|
||||
void operator=(const node&);
|
||||
|
||||
child_list& get_children(const string_span& name);
|
||||
child_list& get_children(const char* name);
|
||||
int get_children(const string_span& name);
|
||||
int get_children(const char* name);
|
||||
|
||||
void set_dirty();
|
||||
void shift_buffers(ptrdiff_t offset);
|
||||
@ -164,6 +164,23 @@ private:
|
||||
static child_map::iterator find_in_map(child_map& m, const string_span& attr);
|
||||
child_map children_;
|
||||
|
||||
//a node position indicates the index into the child map where the node
|
||||
//is, and then the index into the child list within where the node is.
|
||||
struct node_pos {
|
||||
node_pos(int child_map_index, int child_list_index)
|
||||
: child_map_index(child_map_index), child_list_index(child_list_index)
|
||||
{}
|
||||
unsigned short child_map_index;
|
||||
unsigned short child_list_index;
|
||||
};
|
||||
|
||||
//a list of all the children in order.
|
||||
std::vector<node_pos> ordered_children_;
|
||||
|
||||
void insert_ordered_child(int child_map_index, int child_list_index);
|
||||
void remove_ordered_child(int child_map_index, int child_list_index);
|
||||
void remove_ordered_child_list(int child_map_index);
|
||||
|
||||
string_span output_cache_;
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user