Added accessors for the nth child of a config object.

This commit is contained in:
Guillaume Melquiond 2010-03-27 18:49:14 +00:00
parent 8833d48c71
commit 8f32240573
4 changed files with 23 additions and 38 deletions

View file

@ -210,25 +210,13 @@ const config::child_list& config::get_children(const std::string& key) const
}
}
config &config::child(const std::string& key)
config &config::child(const std::string& key, int n)
{
check_valid();
const child_map::const_iterator i = children.find(key);
if(i != children.end() && i->second.empty() == false) {
return *i->second.front();
} else {
return invalid;
}
}
const config &config::child(const std::string& key) const
{
check_valid();
const child_map::const_iterator i = children.find(key);
if(i != children.end() && i->second.empty() == false) {
return *i->second.front();
if (i != children.end() && i->second.size() > size_t(n)) {
return *i->second[n];
} else {
return invalid;
}

View file

@ -227,16 +227,17 @@ public:
config child_or_empty(const std::string &key) const;
/**
* Returns the first child with the given @a key, or
* Returns the nth child with the given @a key, or
* a reference to an invalid config if there is none.
*/
config &child(const std::string& key);
config &child(const std::string& key, int n = 0);
/**
* Returns the first child with the given @a key, or
* Returns the nth child with the given @a key, or
* a reference to an invalid config if there is none.
*/
const config &child(const std::string& key) const;
const config &child(const std::string& key, int n = 0) const
{ return const_cast<config *>(this)->child(key, n); }
config& add_child(const std::string& key);
config& add_child(const std::string& key, const config& val);

View file

@ -170,16 +170,16 @@ int rng::get_random_private(bool check)
return r;
}
const config::child_list random(random_->get_children("random"));
if (random_child_ >= random.size()) {
random_child_ = random.size() + 1;
size_t random_size = random_->child_count("random");
if (random_child_ >= random_size) {
random_child_ = random_size + 1;
int res = generator_.get_next_random() & 0x7FFFFFFF;
(random_->add_child("random"))["value"] = lexical_cast<std::string>(res);
LOG_RND << "get_random() returning " << res << " (added to random_)\n";
return res;
} else {
int mine = generator_.get_next_random();
int stored = lexical_cast_default<int>((*random[random_child_++])["value"], 0);
int stored = lexical_cast_default<int>(random_->child("random", random_child_++)["value"]);
if (mine != stored) {
if (check) {
ERR_RND << "Random number mismatch, mine " << mine << " vs " << stored << "\n";
@ -197,9 +197,8 @@ const config* rng::get_random_results()
{
assert(random_ != NULL);
const config::child_list random(random_->get_children("random"));
if (random_child_ <= 0 ||random_child_ > random.size()) return NULL;
const config &res = random[random_child_-1]->child("results");
if (random_child_ <= 0 ||random_child_ > random_->child_count("random")) return NULL;
const config &res = random_->child("random", random_child_ - 1).child("results");
return res ? &res : NULL;
}
@ -207,10 +206,10 @@ void rng::set_random_results(const config& cfg)
{
assert(random_ != NULL);
const config::child_list random(random_->get_children("random"));
if (random_child_ <= 0 || random_child_ > random.size()) return;
random[random_child_-1]->clear_children("results");
random[random_child_-1]->add_child("results",cfg);
if (random_child_ <= 0 ||random_child_ > random_->child_count("random")) return;
config &r = random_->child("random", random_child_ - 1);
r.clear_children("results");
r.add_child("results", cfg);
}
config* rng::random()

View file

@ -647,8 +647,7 @@ variable_info::variable_info(const std::string& varname,
return;
}
//std::cerr << "Entering " << element << "[" << inner_index << "] of [" << vars->get_children(element).size() << "]\n";
vars = vars->get_children(element)[inner_index];
vars = &vars->child(element, inner_index);
itor = std::find(key.begin(),key.end(),'.');
dot_index = key.find('.');
} // end subvar access
@ -665,7 +664,7 @@ variable_info::variable_info(const std::string& varname,
index = game_config::max_loop;
}
key = std::string(key.begin(),index_start);
size_t size = vars->get_children(key).size();
size_t size = vars->child_count(key);
if(size <= index) {
if(!force_valid) {
WRN_NG << "variable_info: invalid WML array index, " << varname << std::endl;
@ -677,12 +676,12 @@ variable_info::variable_info(const std::string& varname,
}
switch(vartype) {
case variable_info::TYPE_ARRAY:
vars = vars->get_children(key)[index];
vars = &vars->child(key, index);
key = "__array";
is_valid = force_valid || vars->child(key);
break;
case variable_info::TYPE_SCALAR:
vars = vars->get_children(key)[index];
vars = &vars->child(key, index);
key = "__value";
is_valid = force_valid || vars->has_attribute(key);
break;
@ -725,9 +724,7 @@ config& variable_info::as_container() {
assert(is_valid);
if(explicit_index) {
// Empty data for explicit index was already created if it was needed
config::child_iterator i = vars->child_range(key).first;
std::advance(i, index);
return *i;
return vars->child(key, index);
}
if (config &temp = vars->child(key)) {
// The container exists, index not specified, return index 0