Cleaning up the unit_type stuff, to provide a much better encapsulation:

- get rid of redundant functionality

- make the unit_type_data interface more easily accessible

- reduce the public interface of unit_type_data

- rename unit_type_factory to unit_type_map_wrapper

- add a whole lot of "const"
This commit is contained in:
Jörg Hinrichs 2008-04-01 21:51:29 +00:00
parent 5a9bd1db8d
commit 7e491a85c4
15 changed files with 226 additions and 288 deletions

View file

@ -1103,9 +1103,9 @@ attack::attack(game_display& gui, const gamemap& map,
// plague units make new units on the target hex
unit_type_data::unit_type_map::const_iterator reanimitor;
LOG_NG<<"trying to reanimate "<<a_stats_->plague_type<<std::endl;
reanimitor = unit_type_data::instance().unit_types.find(a_stats_->plague_type);
reanimitor = unit_type_data::types().find(a_stats_->plague_type);
LOG_NG<<"found unit type:"<<reanimitor->second.id()<<std::endl;
if(reanimitor != unit_type_data::instance().unit_types.end()) {
if(reanimitor != unit_type_data::types().end()) {
unit newunit=unit(&units_,&map_,&state_,&teams_,&reanimitor->second,a_->second.side(),true,true);
newunit.set_attacks(0);
// Apply variation
@ -1324,9 +1324,9 @@ attack::attack(game_display& gui, const gamemap& map,
// plague units make new units on the target hex.
unit_type_data::unit_type_map::const_iterator reanimitor;
LOG_NG<<"trying to reanimate "<<d_stats_->plague_type<<std::endl;
reanimitor = unit_type_data::instance().unit_types.find(d_stats_->plague_type);
reanimitor = unit_type_data::types().find(d_stats_->plague_type);
LOG_NG<<"found unit type:"<<reanimitor->second.id()<<std::endl;
if(reanimitor != unit_type_data::instance().unit_types.end()) {
if(reanimitor != unit_type_data::types().end()) {
unit newunit=unit(&units_,&map_,&state_,&teams_,&reanimitor->second,d_->second.side(),true,true);
// Apply variation
if(strcmp(undead_variation.c_str(),"null")){
@ -1657,9 +1657,9 @@ void calculate_healing(game_display& disp, const gamemap& map,
unit get_advanced_unit(unit_map& units,
const gamemap::location& loc, const std::string& advance_to)
{
const std::map<std::string,unit_type>::const_iterator new_type = unit_type_data::instance().unit_types.find(advance_to);
const std::map<std::string,unit_type>::const_iterator new_type = unit_type_data::types().find(advance_to);
const unit_map::iterator un = units.find(loc);
if(new_type != unit_type_data::instance().unit_types.end() && un != units.end()) {
if(new_type != unit_type_data::types().end() && un != units.end()) {
unit new_unit(un->second);
new_unit.get_experience(-new_unit.max_experience());
new_unit.advance_to(&(new_type->second));

View file

@ -267,7 +267,7 @@ bool ai::recruit_usage(const std::string& usage)
// matches the desired usage type, and comes in under budget.
const std::set<std::string>& recruits = current_team().recruits();
for(std::map<std::string,unit_type>::const_iterator i =
unit_type_data::instance().unit_types.begin(); i != unit_type_data::instance().unit_types.end(); ++i)
unit_type_data::types().begin(); i != unit_type_data::types().end(); ++i)
{
const std::string& name = i->second.id();
// If usage is empty consider any unit.
@ -317,8 +317,8 @@ bool ai_interface::recruit(const std::string& unit_name, location loc)
recorder.add_recruit(num,loc);
replay_undo replay_guard(recorder);
unit_type_data::unit_type_map::const_iterator u = unit_type_data::instance().unit_types.find(unit_name);
if(u == unit_type_data::instance().unit_types.end()) {
unit_type_data::unit_type_map::const_iterator u = unit_type_data::types().find(unit_name);
if(u == unit_type_data::types().end()) {
return false;
}
@ -1522,8 +1522,8 @@ void ai::analyze_potential_recruit_combat()
const std::set<std::string>& recruits = current_team().recruits();
std::set<std::string>::const_iterator i;
for(i = recruits.begin(); i != recruits.end(); ++i) {
const unit_type_data::unit_type_map::const_iterator info = unit_type_data::instance().unit_types.find(*i);
if(info == unit_type_data::instance().unit_types.end() || not_recommended_units_.count(*i)) {
const unit_type_data::unit_type_map::const_iterator info = unit_type_data::types().find(*i);
if(info == unit_type_data::types().end() || not_recommended_units_.count(*i)) {
continue;
}
@ -1535,8 +1535,8 @@ void ai::analyze_potential_recruit_combat()
}
unit const &un = j->second;
const unit_type_data::unit_type_map::const_iterator enemy_info = unit_type_data::instance().unit_types.find(un.type_id());
VALIDATE((enemy_info != unit_type_data::instance().unit_types.end()), _("Unknown unit type : ") + un.type_id());
const unit_type_data::unit_type_map::const_iterator enemy_info = unit_type_data::types().find(un.type_id());
VALIDATE((enemy_info != unit_type_data::types().end()), _("Unknown unit type : ") + un.type_id());
int weight = un.cost() * un.hitpoints() / un.max_hitpoints();
weighting += weight;
@ -1560,8 +1560,8 @@ void ai::analyze_potential_recruit_combat()
// if they have a score more than 600 below
// the best unit of that usage type.
for(i = recruits.begin(); i != recruits.end(); ++i) {
const unit_type_data::unit_type_map::const_iterator info = unit_type_data::instance().unit_types.find(*i);
if(info == unit_type_data::instance().unit_types.end() || not_recommended_units_.count(*i)) {
const unit_type_data::unit_type_map::const_iterator info = unit_type_data::types().find(*i);
if(info == unit_type_data::types().end() || not_recommended_units_.count(*i)) {
continue;
}
@ -1623,8 +1623,8 @@ void ai::analyze_potential_recruit_movements()
std::map<std::string,int> best_scores;
for(std::set<std::string>::const_iterator i = recruits.begin(); i != recruits.end(); ++i) {
const unit_type_data::unit_type_map::const_iterator info = unit_type_data::instance().unit_types.find(*i);
if(info == unit_type_data::instance().unit_types.end()) {
const unit_type_data::unit_type_map::const_iterator info = unit_type_data::types().find(*i);
if(info == unit_type_data::types().end()) {
continue;
}
@ -1672,9 +1672,9 @@ void ai::analyze_potential_recruit_movements()
j != unit_movement_scores_.end(); ++j) {
const unit_type_data::unit_type_map::const_iterator info =
unit_type_data::instance().unit_types.find(j->first);
unit_type_data::types().find(j->first);
if(info == unit_type_data::instance().unit_types.end()) {
if(info == unit_type_data::types().end()) {
continue;
}

View file

@ -167,10 +167,10 @@ PyObject* python_ai::unittype_advances_to( wesnoth_unittype* type, PyObject* arg
int r;
for (size_t advance = 0; advance < type->unit_type_->advances_to().size(); advance++)
{
std::map<std::string,unit_type>::const_iterator t =
unit_type_data::instance().unit_types.find(type->unit_type_->advances_to()[advance]);
std::map<std::string,unit_type>::const_iterator t =
unit_type_data::types().find(type->unit_type_->advances_to()[advance]);
assert(t != unit_type_data::instance().unit_types.end());
assert(t != unit_type_data::types().end());
r = PyList_SetItem(list,advance,wrap_unittype(t->second));
}
return list;
@ -220,10 +220,10 @@ static PyMethodDef unittype_methods[] = {
{ NULL, NULL, 0, NULL }
};
static int unittype_internal_compare(wesnoth_unittype* left,
static int unittype_internal_compare(wesnoth_unittype* left,
wesnoth_unittype* right)
{
return reinterpret_cast<long>(left->unit_type_) -
return reinterpret_cast<long>(left->unit_type_) -
reinterpret_cast<long>(right->unit_type_);
}
@ -1033,8 +1033,8 @@ PyObject* python_ai::wrapper_team_recruits( wesnoth_team* team, PyObject* args )
int idx = 0;
for (std::set<std::string>::const_iterator recruit = team->team_->recruits().begin(); recruit != team->team_->recruits().end(); ++recruit)
{
std::map<std::string,unit_type>::const_iterator t = unit_type_data::instance().unit_types.find(*recruit);
assert(t != unit_type_data::instance().unit_types.end());
std::map<std::string,unit_type>::const_iterator t = unit_type_data::types().find(*recruit);
assert(t != unit_type_data::types().end());
r = PyList_SetItem(list,idx++,wrap_unittype(t->second));
}
return list;
@ -1073,7 +1073,7 @@ static PyMethodDef team_methods[] = {
"Parameters: location\n"
"Returns: result\n"
"True if the team owns a village at the given location.")
MDEF("recruits", python_ai::wrapper_team_recruits,
MDEF("recruits", python_ai::wrapper_team_recruits,
"Returns: recruits\n"
"Returns a list of wesnoth.unittype objects"
" of all possible recruits for this team.")
@ -1460,7 +1460,7 @@ PyObject* python_ai::wrapper_attack_unit(PyObject* /*self*/, PyObject* args)
// and then the code below will horribly fail).
if (!tiles_adjacent(*from->location_, *to->location_))
return_none;
// check if units actually exist
bool fromexists = false;
bool toexists = false;
@ -1472,7 +1472,7 @@ PyObject* python_ai::wrapper_attack_unit(PyObject* /*self*/, PyObject* args)
toexists = true;
}
}
if (!fromexists or !toexists) return_none;
info& inf = running_instance->get_info();
@ -1720,16 +1720,16 @@ PyObject* python_ai::wrapper_test_move(PyObject* /*self*/, PyObject* args)
// loc initialises to x=-1000, y=-1000. i.e. temporarily moves the unit off the map
gamemap::location loc;
wesnoth_location* to = reinterpret_cast<wesnoth_location*>(wrap_location(loc));
if (!PyArg_ParseTuple(args, CC("O!|O!"), &wesnoth_location_type, &from,
&wesnoth_location_type, &to))
return NULL;
// Trivial case, just return the current move_maps
if (*from->location_ == *to->location_) {
// PyTuple_New creates a new reference (which we will return)
PyObject* ret = PyTuple_New(2);
/* wrap_move_map creates a new reference, PyTuple_SetItem takes away
* a reference - so this should cancel out and we don't need to
* change reference counts ourselves.
@ -1739,12 +1739,12 @@ PyObject* python_ai::wrapper_test_move(PyObject* /*self*/, PyObject* args)
return ret;
}
info& inf = running_instance->get_info();
unit_map::iterator u_it = inf.units.find(*from->location_);
if (u_it == inf.units.end()) return_none;
// Temporarily move our unit to the specified location, storing any
// unit that might happen to be there already.
std::pair<gamemap::location,unit> *temp = inf.units.extract(*to->location_);
@ -1752,35 +1752,35 @@ PyObject* python_ai::wrapper_test_move(PyObject* /*self*/, PyObject* args)
std::pair<gamemap::location,unit> *original = inf.units.extract(*from->location_);
std::pair<gamemap::location,unit> test(*to->location_, u_it->second);
inf.units.add(&test);
ai_interface::move_map test_src_dst;
ai_interface::move_map test_dst_src;
std::map<gamemap::location, paths> possible_moves;
running_instance->calculate_moves(inf.units, possible_moves, test_src_dst, test_dst_src, true);
// Restore old positions again
temp = inf.units.extract(*to->location_);
inf.units.add(original);
if (backup)
inf.units.add(backup);
PyObject* srcdst = wrap_move_map(test_src_dst);
PyObject* dstsrc = wrap_move_map(test_dst_src);
// possible_moves not used
PyObject* ret = PyTuple_New(2);
PyTuple_SetItem(ret, 0, srcdst);
PyTuple_SetItem(ret, 1, dstsrc);
return ret;
}
static PyMethodDef wesnoth_python_methods[] = {
MDEF("log_message", python_ai::wrapper_log_message,
MDEF("log_message", python_ai::wrapper_log_message,
"Parameters: string\n"
"Logs a message, displayed as a chat message, if debug is enabled." )
MDEF("log", python_ai::wrapper_log,
MDEF("log", python_ai::wrapper_log,
"Parameters: string\n"
"Writes a debug message to the AI log. This should be used instead of "
"print to not clutter stdout if AI logging is disabled.")
@ -1895,7 +1895,7 @@ void python_ai::initialize_python()
Py_Register(wesnoth_gamestatus_type, "gamestatus");
}
/***
/***
* Invoke the named python script using Wesnoth's builtin Python interpreter.
*/
void python_ai::invoke(std::string name)
@ -1931,7 +1931,7 @@ python_ai::python_ai(ai_interface::info& info) : ai_interface(info), exception(Q
python_ai::~python_ai()
{
// This is called whenever the AI is destroyed after its turn -
// This is called whenever the AI is destroyed after its turn -
// the Python interpreter itself will be auto cleaned up at program exit.
LOG_AI << "Closing Python instance.\n";
running_instance = NULL;
@ -1943,7 +1943,7 @@ void python_ai::play_turn()
std::string script_name = current_team().ai_parameters()["python_script"];
if (script_name.substr(script_name.length() - 3) != ".py") {
// Make sure the script ends in .py here -
// Make sure the script ends in .py here -
// Wesnoth will not execute any other files.
std::cerr << "\"" << script_name << "\" is not a valid script name.\n";
return;
@ -1959,7 +1959,7 @@ void python_ai::play_turn()
if (!game_config::path.empty()) path = game_config::path;
LOG_AI << "Executing Python script \"" << script << "\".\n";
LOG_AI << "Python path: \"" << path << "/data/ais" << "\"\n";
// Run the python script. We actually execute a short inline python script,
// Run the python script. We actually execute a short inline python script,
// which sets up the module search path to the data path,
// runs the script, and then resets the path.
std::string python_code;

View file

@ -459,8 +459,8 @@ void save_preview_pane::draw_contents()
int ypos = area.y;
const unit_type_data::unit_type_map::const_iterator leader = unit_type_data::instance().unit_types.find(summary["leader"]);
if(leader != unit_type_data::instance().unit_types.end()) {
const unit_type_data::unit_type_map::const_iterator leader = unit_type_data::types().find(summary["leader"]);
if(leader != unit_type_data::types().end()) {
#ifdef LOW_MEM
const surface image(image::get_image(leader->second.image()));
@ -977,7 +977,8 @@ const unit_types_preview_pane::details unit_types_preview_pane::get_details() co
if (t==NULL)
return det;
unit_type_data::instance().unit_types.build_unit_type(t->id(), unit_type::WITHOUT_ANIMATIONS);
//FIXME: There should be a better way to deal with this
unit_type_data::types().find(t->id(), unit_type::WITHOUT_ANIMATIONS);
std::string mod = "~RC(" + t->flag_rgb() + ">" + team::get_side_colour_index(side_) + ")";
det.image = image::get_image(t->image()+mod);

View file

@ -1891,7 +1891,7 @@ void game_controller::read_game_cfg(bool use_cache)
void game_controller::set_unit_data(){
const config* const units = game_config_.child("units");
if(units != NULL) {
unit_type_data::instance().set_config(*units);
unit_type_data::types().set_config(*units);
}
}

View file

@ -833,8 +833,8 @@ void event_handler::handle_event_command(const queued_event& event_info,
if (side_num >= teams->size()) side_num = 0;
const unit_race::GENDER gender = string_gender(cfg["gender"]);
const unit_type_data::unit_type_map::const_iterator itor = unit_type_data::instance().unit_types.find(type);
if(itor != unit_type_data::instance().unit_types.end()) {
const unit_type_data::unit_type_map::const_iterator itor = unit_type_data::types().find(type);
if(itor != unit_type_data::types().end()) {
assert(units != NULL);
assert(game_map != NULL);
assert(status_ptr != NULL);
@ -2225,7 +2225,7 @@ void event_handler::handle_event_command(const queued_event& event_info,
// Fire any events
else if(cmd == "fire_event") {
gamemap::location loc1,loc2;
config data;
config data;
if (cfg.has_child("primary_unit")) {
vconfig u = cfg.child("primary_unit");
if (u.has_attribute("x") && u.has_attribute("y"))
@ -2246,7 +2246,7 @@ void event_handler::handle_event_command(const queued_event& event_info,
}
game_events::fire(cfg["name"],loc1,loc2,data);
}
// Setting of menu items
else if(cmd == "set_menu_item") {
/*

View file

@ -1054,8 +1054,8 @@ std::vector<topic> generate_weapon_special_topics(const bool sort_generated)
std::vector<topic> topics;
std::map<std::string, std::string> special_description;
std::map<std::string, std::set<std::string> > special_units;
for(unit_type_data::unit_type_map::const_iterator i = unit_type_data::instance().unit_types.begin();
i != unit_type_data::instance().unit_types.end(); i++) {
for(unit_type_data::unit_type_map::const_iterator i = unit_type_data::types().begin();
i != unit_type_data::types().end(); i++) {
const unit_type &type = (*i).second;
// Only show the weapon special if we find it on a unit that
// detailed description should be shown about.
@ -1128,8 +1128,8 @@ std::vector<topic> generate_ability_topics(const bool sort_generated)
// should have a full description, if so, add this units abilities
// for display. We do not want to show abilities that the user has
// not encountered yet.
for(unit_type_data::unit_type_map::const_iterator i = unit_type_data::instance().unit_types.begin();
i != unit_type_data::instance().unit_types.end(); ++i) {
for(unit_type_data::unit_type_map::const_iterator i = unit_type_data::types().begin();
i != unit_type_data::types().end(); ++i) {
const unit_type &type = (*i).second;
if (description_type(type) == FULL_DESCRIPTION) {
std::vector<std::string> descriptions = type.ability_tooltips();
@ -1241,8 +1241,8 @@ public:
++from_iter)
{
std::string unit_id = *from_iter;
std::map<std::string,unit_type>::const_iterator type = unit_type_data::instance().unit_types.find(unit_id);
if (type != unit_type_data::instance().unit_types.end())
std::map<std::string,unit_type>::const_iterator type = unit_type_data::types().find(unit_id);
if (type != unit_type_data::types().end())
{
std::string lang_unit = type->second.language_name();
std::string ref_id;
@ -1269,8 +1269,8 @@ public:
advance_end = next_units.end();
advance_it != advance_end; ++advance_it) {
std::string unit_id = *advance_it;
std::map<std::string,unit_type>::const_iterator type = unit_type_data::instance().unit_types.find(unit_id);
if(type != unit_type_data::instance().unit_types.end()) {
std::map<std::string,unit_type>::const_iterator type = unit_type_data::types().find(unit_id);
if(type != unit_type_data::types().end()) {
std::string lang_unit = type->second.language_name();
std::string ref_id;
if (description_type(type->second) == FULL_DESCRIPTION && !type->second.hide_help()) {
@ -1291,8 +1291,8 @@ public:
// respective topic.
const std::string race_id = type_.race();
std::string race_name;
const race_map::const_iterator race_it = unit_type_data::instance().unit_types.races().find(race_id);
if (race_it != unit_type_data::instance().unit_types.races().end()) {
const race_map::const_iterator race_it = unit_type_data::types().races().find(race_id);
if (race_it != unit_type_data::types().races().end()) {
race_name = race_it->second.plural_name();
} else {
race_name = _ ("race^Miscellaneous");
@ -1520,8 +1520,8 @@ void generate_races_sections(const config *help_cfg, section &sec, int level)
std::set<std::string> races;
std::set<std::string> visible_races;
for(unit_type_data::unit_type_map::const_iterator i = unit_type_data::instance().unit_types.begin();
i != unit_type_data::instance().unit_types.end(); i++) {
for(unit_type_data::unit_type_map::const_iterator i = unit_type_data::types().begin();
i != unit_type_data::types().end(); i++) {
const unit_type &type = (*i).second;
UNIT_DESCRIPTION_TYPE desc_type = description_type(type);
if (desc_type == FULL_DESCRIPTION) {
@ -1542,8 +1542,8 @@ void generate_races_sections(const config *help_cfg, section &sec, int level)
section_cfg["id"] = hidden_symbol(hidden) + race_prefix + *it;
std::string title;
const race_map::const_iterator race_it = unit_type_data::instance().unit_types.races().find(*it);
if (race_it != unit_type_data::instance().unit_types.races().end()) {
const race_map::const_iterator race_it = unit_type_data::types().races().find(*it);
if (race_it != unit_type_data::types().races().end()) {
title = race_it->second.plural_name();
} else {
title = _ ("race^Miscellaneous");
@ -1563,8 +1563,8 @@ std::vector<topic> generate_unit_topics(const bool sort_generated, const std::st
std::vector<topic> topics;
std::set<std::string> race_units;
for(unit_type_data::unit_type_map::const_iterator i = unit_type_data::instance().unit_types.begin();
i != unit_type_data::instance().unit_types.end(); i++) {
for(unit_type_data::unit_type_map::const_iterator i = unit_type_data::types().begin();
i != unit_type_data::types().end(); i++) {
const unit_type &type = (*i).second;
if (type.race() != race)
@ -1591,8 +1591,8 @@ std::vector<topic> generate_unit_topics(const bool sort_generated, const std::st
std::string race_id = "..race_"+race;
std::string race_name;
std::string race_description;
const race_map::const_iterator race_it = unit_type_data::instance().unit_types.races().find(race);
if (race_it != unit_type_data::instance().unit_types.races().end()) {
const race_map::const_iterator race_it = unit_type_data::types().races().find(race);
if (race_it != unit_type_data::types().races().end()) {
race_name = race_it->second.plural_name();
race_description = race_it->second.description();
// if (description.empty()) description = _("No description Available");
@ -2709,7 +2709,7 @@ void help_browser::show_topic(const topic &t, bool save_in_history)
if (t.text.parsed_text().size() == 0){
if (t.id.find(unit_prefix) == 0){
std::string unit_id = t.id.substr(unit_prefix.length(), t.id.length() - unit_prefix.length());
unit_type& type = unit_type_data::instance().unit_types.build_unit_type(unit_id, unit_type::WITHOUT_ANIMATIONS);
const unit_type& type = unit_type_data::types().find(unit_id, unit_type::WITHOUT_ANIMATIONS)->second;
t.text = new unit_topic_generator(type);
}
}
@ -2991,7 +2991,7 @@ void show_help(display &disp, const section &toplevel_sec,
// Find all unit_types that have not been constructed yet and fill in the information
// needed to create the help topics
unit_type_data::instance().unit_types.generate_help_info();
unit_type_data::types().build_all(unit_type::HELP_TOPIC_BUILT);
if (preferences::encountered_units().size() != size_t(last_num_encountered_units) ||
preferences::encountered_terrains().size() != size_t(last_num_encountered_terrains) ||

View file

@ -125,7 +125,7 @@ void leader_list_manager::update_gender_list(const std::string& leader)
return;
}
unit_type_data::unit_type_factory& utypes = unit_type_data::instance().unit_types;
unit_type_data::unit_type_map_wrapper& utypes = unit_type_data::types();
if (utypes.find(leader) != utypes.end()) {
const unit_type* ut;
const unit_type* utg;
@ -182,7 +182,7 @@ void leader_list_manager::populate_leader_combo(int selected_index) {
std::vector<std::string> leader_strings;
for(itor = leaders_.begin(); itor != leaders_.end(); ++itor) {
unit_type_data::unit_type_factory& utypes = unit_type_data::instance().unit_types;
unit_type_data::unit_type_map_wrapper& utypes = unit_type_data::types();
//const std::string name = data_->unit_types->find(*itor).language_name();
if (utypes.find(*itor) != utypes.end()) {

View file

@ -72,8 +72,8 @@ std::vector<std::string> create_unit_table(const statistics::stats::str_int_map&
{
std::vector<std::string> table;
for(statistics::stats::str_int_map::const_iterator i = m.begin(); i != m.end(); ++i) {
const unit_type_data::unit_type_map::const_iterator type = unit_type_data::instance().unit_types.find(i->first);
if(type == unit_type_data::instance().unit_types.end()) {
const unit_type_data::unit_type_map::const_iterator type = unit_type_data::types().find(i->first);
if(type == unit_type_data::types().end()) {
continue;
}
@ -979,8 +979,8 @@ private:
const std::set<std::string>& recruits = current_team.recruits();
for(std::set<std::string>::const_iterator it = recruits.begin(); it != recruits.end(); ++it) {
const std::map<std::string,unit_type>::const_iterator
u_type = unit_type_data::instance().unit_types.find(*it);
if(u_type == unit_type_data::instance().unit_types.end()) {
u_type = unit_type_data::types().find(*it);
if(u_type == unit_type_data::types().end()) {
ERR_NG << "could not find unit '" << *it << "'\n";
return;
}
@ -1058,8 +1058,8 @@ private:
}
const std::map<std::string,unit_type>::const_iterator
u_type = unit_type_data::instance().unit_types.find(name);
assert(u_type != unit_type_data::instance().unit_types.end());
u_type = unit_type_data::types().find(name);
assert(u_type != unit_type_data::types().end());
if(u_type->second.cost() > current_team.gold()) {
gui::message_dialog(*gui_,"",
@ -1603,15 +1603,14 @@ private:
_("Type");
options.push_back(heading);
for(unit_type_data::unit_type_map::iterator i = unit_type_data::instance().unit_types.begin(); i != unit_type_data::instance().unit_types.end(); ++i) {
for(unit_type_data::unit_type_map::const_iterator i = unit_type_data::types().begin(); i != unit_type_data::types().end(); ++i) {
std::stringstream row;
const config& unit_cfg = unit_type_data::instance().unit_types.find_config(i->first);
i->second.build_help_index(unit_cfg, unit_type_data::instance().unit_types.races());
unit_type_data::types().find(i->first, unit_type::WITHOUT_ANIMATIONS);
std::string race;
const race_map::const_iterator race_it = unit_type_data::instance().unit_types.races().find(i->second.race());
if (race_it != unit_type_data::instance().unit_types.races().end()) {
const race_map::const_iterator race_it = unit_type_data::types().races().find(i->second.race());
if (race_it != unit_type_data::types().races().end()) {
race = race_it->second.plural_name();
}
row << race << COLUMN_SEPARATOR;
@ -2120,7 +2119,7 @@ private:
gui::dialog(*gui_,"",msg).show();
}
}
//A function object class with only the constructor public.
//Will execute one specified console command if possible.
//To add a new console command:
@ -2132,8 +2131,8 @@ private:
class console_handler
{
public:
console_handler(menu_handler& menu_handler,
mouse_handler& mouse_handler, const std::string& cmd,
console_handler(menu_handler& menu_handler,
mouse_handler& mouse_handler, const std::string& cmd,
const std::string data, const unsigned int team_num)
: menu_handler_(menu_handler), mouse_handler_(mouse_handler)
,cmd_(cmd), data_(data), team_num_(team_num)
@ -2143,10 +2142,10 @@ private:
}
dispatch();
}
private:
typedef void (console_handler::*command_handler)();
struct command
{
command_handler handler;
@ -2157,7 +2156,7 @@ private:
: handler(h), help(help), debug_only(false), network_only(false)
{
}
command& set_debug_only()
command& set_debug_only()
{
debug_only = true;
return *this;
@ -2175,36 +2174,36 @@ private:
return flags;
}
};
typedef std::map<std::string, command> command_map;
typedef std::map<std::string, std::string> command_alias_map;
static command_map command_map_;
static command_alias_map command_alias_map_;
menu_handler& menu_handler_;
mouse_handler& mouse_handler_;
const std::string & cmd_;
const std::string & data_;
const unsigned int team_num_;
const unsigned int team_num_;
static command& register_command(const std::string& cmd,
command_handler h, const std::string& help)
{
return command_map_.insert(
command_map::value_type(cmd,command(h, help))).first->second;
command_map::value_type(cmd,command(h, help))).first->second;
}
static void assert_existence(const std::string& cmd)
{
assert(command_map_.count(cmd));
}
static void register_alias(const std::string& to_cmd,
static void register_alias(const std::string& to_cmd,
const std::string& cmd)
{
assert_existence(to_cmd);
command_alias_map_.insert(
command_alias_map::value_type(cmd,to_cmd));
}
static void init_command_map();
static std::string get_actual_cmd(const std::string& cmd);
static const command* get_command(const std::string& cmd);
@ -2213,7 +2212,7 @@ private:
const std::vector<std::string> get_aliases(const std::string& cmd);
void help();
void help(const std::string& cmd);
void do_refresh();
void do_droid();
void do_log();
@ -2245,25 +2244,25 @@ private:
void do_event();
void do_version();
};
console_handler::command_map console_handler::command_map_;
console_handler::command_alias_map console_handler::command_alias_map_;
void console_handler::print(const std::string& title,
const std::string& message)
{
menu_handler_.add_chat_message(time(NULL), title, 0, message);
menu_handler_.add_chat_message(time(NULL), title, 0, message);
}
void console_handler::init_command_map()
{
register_command("help", &console_handler::help,
"[command] - Command help");
register_command("refresh", &console_handler::do_refresh,
"Refresh gui");
register_command("droid", &console_handler::do_droid,
register_command("droid", &console_handler::do_droid,
"[<side> [on/off]] - AI control").set_debug_only();
register_command("log", &console_handler::do_log,
register_command("log", &console_handler::do_log,
"<level> <domain> - Change the log level of a log domain.");
register_command("theme", &console_handler::do_theme, "");
register_command("muteall", &console_handler::do_network_send_cmd,
@ -2278,9 +2277,9 @@ private:
"").set_network_only();
register_command("query", &console_handler::do_network_send_cmd_data,
"").set_network_only();
register_command("control", &console_handler::do_control,
register_command("control", &console_handler::do_control,
"<side> <nick>").set_network_only();
register_command("control", &console_handler::do_clear,
register_command("control", &console_handler::do_clear,
"Clear chat history");
register_command("sunset", &console_handler::do_sunset,
"Change time of day").set_debug_only();
@ -2299,7 +2298,7 @@ private:
&console_handler::do_ignore_replay_errors, "Ignore replay errors");
register_command("nosaves", &console_handler::do_nosaves,
"Do not autosave");
register_command("next_level", &console_handler::do_next_level,
register_command("next_level", &console_handler::do_next_level,
"Advance to next level").set_debug_only();
register_alias("next_level", "n");
register_command("debug", &console_handler::do_debug,
@ -2322,15 +2321,15 @@ private:
"Toggle fog for current player").set_debug_only();
register_command("shroud", &console_handler::do_shroud,
"Toggle shroud for current player").set_debug_only();
register_command("gold", &console_handler::do_gold,
register_command("gold", &console_handler::do_gold,
"Give gold to current player").set_debug_only();
register_command("throw", &console_handler::do_event,
"Fire game event").set_debug_only();
register_alias("throw", "fire");
register_command("version", &console_handler::do_version,
register_command("version", &console_handler::do_version,
"Display version information");
}
std::string console_handler::get_actual_cmd(const std::string& cmd)
{
command_alias_map::const_iterator i = command_alias_map_.find(cmd);
@ -2342,7 +2341,7 @@ private:
}
return real_cmd;
}
const console_handler::command* console_handler::get_command(
const std::string& cmd)
{
@ -2353,7 +2352,7 @@ private:
return 0;
}
}
const std::vector<std::string> console_handler::get_aliases(
const std::string& cmd)
{
@ -2367,18 +2366,18 @@ private:
}
return aliases;
}
void console_handler::dispatch()
{
std::string actual_cmd = get_actual_cmd(cmd_);
if (const command* c = get_command(actual_cmd)) {
if (c->debug_only && !game_config::debug) return;
if (c->network_only || network::nconnections() != 0) return;
(this->*(c->handler))();
}
}
void console_handler::help()
{
std::string actual_cmd = get_actual_cmd(data_);
@ -2399,7 +2398,7 @@ private:
print("help", ss.str());
print("help", "Type :help <command> for more info");
}
void console_handler::help(const std::string& cmd)
{
const command* c = get_command(cmd);
@ -2424,7 +2423,7 @@ private:
print("help", ss.str());
}
}
void menu_handler::do_command(const std::string& str,
const unsigned int team_num, mouse_handler& mousehandler)
{
@ -2441,7 +2440,7 @@ private:
image::flush_cache();
menu_handler_.gui_->redraw_everything();
}
void console_handler::do_droid() {
// :droid [<side> [on/off]]
const std::string::const_iterator j = std::find(data_.begin(),data_.end(),' ');
@ -2634,8 +2633,8 @@ private:
}
void console_handler::do_create() {
if (menu_handler_.map_.on_board(mouse_handler_.get_last_hex())) {
const unit_type_data::unit_type_map::const_iterator i = unit_type_data::instance().unit_types.find(data_);
if(i == unit_type_data::instance().unit_types.end()) {
const unit_type_data::unit_type_map::const_iterator i = unit_type_data::types().find(data_);
if(i == unit_type_data::types().end()) {
return;
}

View file

@ -168,8 +168,8 @@ connect::side::side(connect& parent, const config& cfg, int index) :
leader_name_pseudolist.push_back("-");
} else {
unit_type_data::unit_type_map::const_iterator leader_name =
unit_type_data::instance().unit_types.find(leader_type);
if(leader_name == unit_type_data::instance().unit_types.end()) {
unit_type_data::types().find(leader_type);
if(leader_name == unit_type_data::types().end()) {
leader_name_pseudolist.push_back("-");
} else {
if (gender_ == "female")
@ -186,8 +186,8 @@ connect::side::side(connect& parent, const config& cfg, int index) :
if (!gender_.empty()) {
if (leader_type.empty()
|| unit_type_data::instance().unit_types.find(leader_type)
== unit_type_data::instance().unit_types.end())
|| unit_type_data::types().find(leader_type)
== unit_type_data::types().end())
{
gender_name_pseudolist.push_back("-");
} else {
@ -230,8 +230,8 @@ connect::side::side(connect& parent, const config& cfg, int index) :
llm_.set_leader_combo(NULL);
llm_.set_gender_combo(NULL);
std::vector<std::string> leader_name_pseudolist;
unit_type_data::unit_type_map::const_iterator leader_name = unit_type_data::instance().unit_types.find(leader_);
if(leader_name == unit_type_data::instance().unit_types.end()) {
unit_type_data::unit_type_map::const_iterator leader_name = unit_type_data::types().find(leader_);
if(leader_name == unit_type_data::types().end()) {
leader_name_pseudolist.push_back("?");
} else {
leader_name_pseudolist.push_back(leader_name->second.language_name());
@ -240,7 +240,7 @@ connect::side::side(connect& parent, const config& cfg, int index) :
combo_leader_.set_selected(0);
std::vector<std::string> gender_name_pseudolist;
if (!gender_.empty()) {
if(leader_name == unit_type_data::instance().unit_types.end()) {
if(leader_name == unit_type_data::types().end()) {
gender_name_pseudolist.push_back("?");
} else {
if (gender_ == "female")
@ -872,9 +872,9 @@ void connect::side::resolve_random()
}
// Resolve random genders "very much" like standard unit code
if (llm_.get_gender() == "random" || solved_random_leader) {
unit_type_data::unit_type_map::const_iterator ut = unit_type_data::instance().unit_types.find(leader_.empty() ? llm_.get_leader() : leader_);
unit_type_data::unit_type_map::const_iterator ut = unit_type_data::types().find(leader_.empty() ? llm_.get_leader() : leader_);
if (ut != unit_type_data::instance().unit_types.end()) {
if (ut != unit_type_data::types().end()) {
const std::vector<unit_race::GENDER> glist = ut->second.genders();
if (!glist.empty()) {
const int gchoice = rand() % glist.size();

View file

@ -95,7 +95,7 @@ void wait::leader_preview_pane::draw_contents()
std::string leader = leaders_.get_leader();
std::string gender = leaders_.get_gender();
unit_type_data::unit_type_factory& utypes = unit_type_data::instance().unit_types;
unit_type_data::unit_type_map_wrapper& utypes = unit_type_data::types();
std::string leader_name;
std::string image;
@ -465,7 +465,7 @@ void wait::generate_menu()
std::string leader_name;
std::string leader_image;
unit_type_data::unit_type_factory& utypes = unit_type_data::instance().unit_types;
unit_type_data::unit_type_map_wrapper& utypes = unit_type_data::types();
const unit_type* ut;
const unit_type* utg;

View file

@ -934,8 +934,8 @@ bool do_replay_handle(game_display& disp, const gamemap& map,
std::set<std::string>::const_iterator itor = recruits.begin();
std::advance(itor,val);
const std::map<std::string,unit_type>::const_iterator u_type = unit_type_data::instance().unit_types.find(*itor);
if(u_type == unit_type_data::instance().unit_types.end()) {
const std::map<std::string,unit_type>::const_iterator u_type = unit_type_data::types().find(*itor);
if(u_type == unit_type_data::types().end()) {
std::stringstream errbuf;
errbuf << "recruiting illegal unit: '" << *itor << "'\n";
replay::throw_error(errbuf.str());

View file

@ -393,9 +393,9 @@ void unit::add_trait(std::string /*trait*/)
void unit::generate_traits(bool musthaveonly, game_state* state)
{
LOG_UT << "Generating a trait for unit type " << type_id() << " with musthaveonly " << musthaveonly << "\n";
const unit_type_data::unit_type_map::const_iterator type = unit_type_data::instance().unit_types.find(type_id());
const unit_type_data::unit_type_map::const_iterator type = unit_type_data::types().find(type_id());
// Calculate the unit's traits
if (type == unit_type_data::instance().unit_types.end()) {
if (type == unit_type_data::types().end()) {
std::string error_message = _("Unknown unit type '$type|'");
utils::string_map symbols;
symbols["type"] = type_id();
@ -584,8 +584,8 @@ void unit::advance_to(const unit_type* t, bool use_traits, game_state* state)
const unit_type* unit::type() const
{
std::map<std::string,unit_type>::const_iterator i = unit_type_data::instance().unit_types.find(type_id());
if(i != unit_type_data::instance().unit_types.end()) {
std::map<std::string,unit_type>::const_iterator i = unit_type_data::types().find(type_id());
if(i != unit_type_data::types().end()) {
return &i->second;
}
if (!type_id().empty()) {
@ -1177,7 +1177,7 @@ void unit::read(const config& cfg, bool use_traits, game_state* state)
/* */
if(cfg["gender"].empty()) {
const unit_type_data::unit_type_map::const_iterator ut = unit_type_data::instance().unit_types.find(cfg["type"]);
const unit_type_data::unit_type_map::const_iterator ut = unit_type_data::types().find(cfg["type"]);
//! @todo FIXME shadowmaster: in my opinion, the following condition check
//! should be done earlier in this function as it is repated later for other
//! operations; i.e. it must be a sanity check to be performed as soon as possible
@ -1185,7 +1185,7 @@ void unit::read(const config& cfg, bool use_traits, game_state* state)
//! throw an error at the start of this function, right after getting id/type from
//! the config obj. Not sure if that would be wanted; can the engine handle units
//! that don't have an equivalent unit_type obj associated?
if (ut != unit_type_data::instance().unit_types.end())
if (ut != unit_type_data::types().end())
gender_ = generate_gender(ut->second, utils::string_bool(cfg_["random_gender"], false), state);
else
ERR_UT << "no valid unit_type found for unit WML id \"" << cfg["type"] << "\"!\n";
@ -1265,8 +1265,8 @@ void unit::read(const config& cfg, bool use_traits, game_state* state)
bool type_set = false;
type_ = "";
if(!cfg["type"].empty()) {
std::map<std::string,unit_type>::const_iterator i = unit_type_data::instance().unit_types.find(cfg["type"]);
if(i != unit_type_data::instance().unit_types.end()) {
std::map<std::string,unit_type>::const_iterator i = unit_type_data::types().find(cfg["type"]);
if(i != unit_type_data::types().end()) {
advance_to(&i->second.get_gender_unit_type(gender_), use_traits, state);
type_set = true;
} else {
@ -1288,8 +1288,8 @@ void unit::read(const config& cfg, bool use_traits, game_state* state)
}
type_ = cfg_["type"];
if(!type_set || cfg["race"] != "") {
const race_map::const_iterator race_it = unit_type_data::instance().unit_types.races().find(cfg["race"]);
if(race_it != unit_type_data::instance().unit_types.races().end()) {
const race_map::const_iterator race_it = unit_type_data::types().races().find(cfg["race"]);
if(race_it != unit_type_data::types().races().end()) {
race_ = &race_it->second;
} else {
static const unit_race dummy_race;
@ -1334,10 +1334,10 @@ void unit::read(const config& cfg, bool use_traits, game_state* state)
//remove ai_vars from private cfg
cfg_.clear_children("ai_vars");
std::map<std::string,unit_type>::const_iterator uti = unit_type_data::instance().unit_types.find(cfg["type"]);
std::map<std::string,unit_type>::const_iterator uti = unit_type_data::types().find(cfg["type"]);
const unit_type* ut = NULL;
if(uti != unit_type_data::instance().unit_types.end()) {
if(uti != unit_type_data::types().end()) {
ut = &uti->second.get_gender_unit_type(gender_).get_variation(variation_);
}
if(!type_set) {
@ -1473,9 +1473,9 @@ void unit::write(config& cfg) const
cfg.add_child("abilities",abilities_b_);
cfg["x"] = x;
cfg["y"] = y;
std::map<std::string,unit_type>::const_iterator uti = unit_type_data::instance().unit_types.find(type_id());
std::map<std::string,unit_type>::const_iterator uti = unit_type_data::types().find(type_id());
const unit_type* ut = NULL;
if(uti != unit_type_data::instance().unit_types.end()) {
if(uti != unit_type_data::types().end()) {
ut = &uti->second.get_gender_unit_type(gender_).get_variation(variation_);
}
if(ut && cfg["description"] == ut->unit_description()) {
@ -2439,8 +2439,8 @@ void unit::add_modification(const std::string& type, const config& mod, bool no_
// for the first time.
if(apply_to == "variation" && no_add == false) {
variation_ = (**i.first)["name"];
const unit_type_data::unit_type_map::const_iterator var = unit_type_data::instance().unit_types.find(type_id());
if(var == unit_type_data::instance().unit_types.end()) {
const unit_type_data::unit_type_map::const_iterator var = unit_type_data::types().find(type_id());
if(var == unit_type_data::types().end()) {
std::string error_message = _("Unknown unit type '$type|'");
utils::string_map symbols;
symbols["type"] = type_id();

View file

@ -893,19 +893,19 @@ unit_type_data* unit_type_data::instance_ = NULL;
unit_type_data::unit_type_data()
{}
void unit_type_data::set_config(const config& cfg)
void unit_type_data::unit_type_map_wrapper::set_config(const config& cfg)
{
DBG_UT << "unit_type_data::set_config, cfg:\n" << cfg;
clear();
unit_types.set_unit_config(cfg);
unit_types.set_unit_traits(cfg.get_children("trait"));
set_unit_config(cfg);
set_unit_traits(cfg.get_children("trait"));
config::const_child_itors i;
for(i = cfg.child_range("movetype"); i.first != i.second; ++i.first)
{
const unit_movement_type move_type(**i.first);
unit_types.movement_types().insert(
movement_types_.insert(
std::pair<std::string,unit_movement_type>(move_type.name(), move_type));
increment_set_config_progress();
}
@ -913,7 +913,7 @@ void unit_type_data::set_config(const config& cfg)
for(i = cfg.child_range("race"); i.first != i.second; ++i.first)
{
const unit_race race(**i.first);
unit_types.races().insert(std::pair<std::string,unit_race>(race.id(),race));
races_.insert(std::pair<std::string,unit_race>(race.id(),race));
increment_set_config_progress();
}
@ -924,7 +924,7 @@ void unit_type_data::set_config(const config& cfg)
{
// Derive a new unit type from an existing base unit id
const std::string based_from = (*(**i.first).child("base_unit"))["id"];
config from_cfg = unit_types.find_config(based_from);
config from_cfg = find_config(based_from);
//merge the base_unit config into this one
//ugly hack, but couldn't think of anything better for the moment
@ -936,7 +936,7 @@ void unit_type_data::set_config(const config& cfg)
}
// we insert an empty unit_type and build it after the copy (for performance)
std::pair<unit_type_map::iterator,bool> insertion =
unit_types.insert(std::pair<const std::string,unit_type>(id,unit_type()));
insert(std::pair<const std::string,unit_type>(id,unit_type()));
// if (!insertion.second)
// TODO: else { warning for multiple units with same id}
lg::info(lg::config) << "added " << id << " to unit_type list (unit_type_data.unit_types)\n";
@ -950,7 +950,7 @@ void unit_type_data::set_config(const config& cfg)
{
// Derive a new unit type from an existing base unit id
const std::string based_from = (*(**i.first).child("base_unit"))["id"];
config from_cfg = unit_types.find_config(based_from);
config from_cfg = find_config(based_from);
//merge the base_unit config into this one
//ugly hack, but couldn't think of anything better for the moment
@ -962,7 +962,7 @@ void unit_type_data::set_config(const config& cfg)
}
// we insert an empty unit_type and build it after the copy (for performance)
std::pair<unit_type_map::iterator,bool> insertion =
unit_types.insert(std::pair<const std::string,unit_type>(id,unit_type()));
insert(std::pair<const std::string,unit_type>(id,unit_type()));
// if (!insertion.second)
// TODO: else { warning for multiple units with same id}
lg::info(lg::config) << "added " << id << " to unit_type list (unit_type_data.unit_types)\n";
@ -970,12 +970,7 @@ void unit_type_data::set_config(const config& cfg)
}
}
void unit_type_data::clear()
{
unit_types.clear();
}
unit_type_data::unit_type_map::const_iterator unit_type_data::unit_type_factory::find(const std::string& key)
unit_type_data::unit_type_map::const_iterator unit_type_data::unit_type_map_wrapper::find(const std::string& key, unit_type::BUILD_STATUS status) const
{
if (key.empty() || (key == "random"))
return types_.end();
@ -996,119 +991,56 @@ unit_type_data::unit_type_map::const_iterator unit_type_data::unit_type_factory:
}
//check if the unit_type is constructed and build it if necessary
if (itor->second.id().empty()){
lg::info(lg::config) << "construct " << key << " in unit_type list (unit_type_data.unit_types)\n";
for(config::const_child_itors i = unit_cfg_->child_range("unit_type"); i.first != i.second; ++i.first)
{
std::string id = (**i.first)["id"];
if (id == key){
build_unit_type(key, unit_type::FULL);
}
}
// FIXME OBSOLETE compatibility hack to be removed in 1.5.3
for(config::const_child_itors i = unit_cfg_->child_range("unit"); i.first != i.second; ++i.first)
{
std::string id = (**i.first)["id"];
if (id == key){
build_unit_type(key, unit_type::FULL);
}
}
}
build_unit_type(key, status);
return types_.find(key);
}
const config& unit_type_data::unit_type_factory::find_config(const std::string& key){
for(config::const_child_itors i = unit_cfg_->child_range("unit_type"); i.first != i.second; ++i.first)
{
std::string id = (**i.first)["id"];
if (id == key){
return **i.first;
}
}
const config& unit_type_data::unit_type_map_wrapper::find_config(const std::string& key) const
{
const config* cfg = unit_cfg_->find_child("unit_type", "id", key);
if (cfg != NULL)
return *cfg;
// FIXME OBSOLETE compatibility hack to be removed in 1.5.3
for(config::const_child_itors i = unit_cfg_->child_range("unit"); i.first != i.second; ++i.first)
{
std::string id = (**i.first)["id"];
if (id == key){
return **i.first;
}
}
cfg = unit_cfg_->find_child("unit", "id", key);
ERR_UT << "unit_type_data::unit_type_factory::find_config: unit config for id " << key << " not found!\n";
assert(false);
assert(cfg != NULL);
return *cfg;
}
void unit_type_data::unit_type_factory::generate_help_info()
void unit_type_data::unit_type_map_wrapper::build_all(unit_type::BUILD_STATUS status) const
{
assert(unit_cfg_ != NULL);
for(config::const_child_itors i = unit_cfg_->child_range("unit_type"); i.first != i.second; ++i.first)
{
unit_type_map::iterator itor = types_.find((**i.first)["id"]);
assert(itor != types_.end());
//build the stuff that is needed to feed the help index
if (itor->second.build_status() == unit_type::NOT_BUILT)
itor->second.build_help_index(**i.first, races_);
//find the units this one can advance into and add advancefrom information for them
std::vector<std::string> advance_to = utils::split((**i.first)["advanceto"]);
if ( (advance_to.size() > 0) && (advance_to[0] != "null") ){
int count = 0;
for (std::vector<std::string>::const_iterator i_adv = advance_to.begin(); i_adv != advance_to.end(); i_adv++){
count++;
DBG_UT << "Unit: " << (**i.first)["id"] << ", AdvanceTo " << count << ": " << *i_adv << "\n";
unit_type_map::iterator itor_advanceto = types_.find(*i_adv);
itor_advanceto->second.add_advancesfrom((**i.first)["id"]);
}
}
}
// FIXME OBSOLETE compatibility hack to be removed in 1.5.3
for(config::const_child_itors i = unit_cfg_->child_range("unit"); i.first != i.second; ++i.first)
{
unit_type_map::iterator itor = types_.find((**i.first)["id"]);
assert(itor != types_.end());
//build the stuff that is needed to feed the help index
if (itor->second.build_status() == unit_type::NOT_BUILT)
itor->second.build_help_index(**i.first, races_);
//find the units this one can advance into and add advancefrom information for them
std::vector<std::string> advance_to = utils::split((**i.first)["advanceto"]);
if ( (advance_to.size() > 0) && (advance_to[0] != "null") ){
int count = 0;
for (std::vector<std::string>::const_iterator i_adv = advance_to.begin(); i_adv != advance_to.end(); i_adv++){
count++;
DBG_UT << "Unit: " << (**i.first)["id"] << ", AdvanceTo " << count << ": " << *i_adv << "\n";
unit_type_map::iterator itor_advanceto = types_.find(*i_adv);
itor_advanceto->second.add_advancesfrom((**i.first)["id"]);
}
}
for (unit_type_map::const_iterator u = types_.begin(); u != types_.end(); u++){
build_unit_type(u->first, status);
}
}
unit_type& unit_type_data::unit_type_factory::build_unit_type(const std::string& key, unit_type::BUILD_STATUS status){
unit_type& unit_type_data::unit_type_map_wrapper::build_unit_type(const std::string& key, unit_type::BUILD_STATUS status) const
{
unit_type_map::iterator ut = types_.find(key);
const config& unit_cfg = find_config(key);
switch (status){
case unit_type::HELP_TOPIC_BUILT:
//build the stuff that is needed to feed the help index
if (ut->second.build_status() == unit_type::NOT_BUILT)
{
const config& unit_cfg = find_config(key);
ut->second.build_help_index(unit_cfg, races_);
}
add_advancefrom(unit_cfg);
break;
case unit_type::WITHOUT_ANIMATIONS:
case unit_type::FULL:
if ( (ut->second.build_status() == unit_type::NOT_BUILT) ||
(ut->second.build_status() == unit_type::HELP_TOPIC_BUILT) )
{
const config& unit_cfg = find_config(key);
ut->second.build_full(unit_cfg, movement_types_, races_, unit_traits_);
if (ut->second.build_status() == unit_type::NOT_BUILT)
add_advancefrom(unit_cfg);
add_advancement(unit_cfg, ut->second);
}
break;
@ -1119,7 +1051,23 @@ unit_type& unit_type_data::unit_type_factory::build_unit_type(const std::string&
return ut->second;
}
void unit_type_data::unit_type_factory::add_advancement(const config& cfg, unit_type& to_unit){
void unit_type_data::unit_type_map_wrapper::add_advancefrom(const config& unit_cfg) const
{
//find the units this one can advance into and add advancefrom information for them
std::vector<std::string> advance_to = utils::split(unit_cfg["advanceto"]);
if ( (advance_to.size() > 0) && (advance_to[0] != "null") ){
int count = 0;
for (std::vector<std::string>::const_iterator i_adv = advance_to.begin(); i_adv != advance_to.end(); i_adv++){
count++;
DBG_UT << "Unit: " << unit_cfg["id"] << ", AdvanceTo " << count << ": " << *i_adv << "\n";
unit_type_map::iterator itor_advanceto = types_.find(*i_adv);
itor_advanceto->second.add_advancesfrom(unit_cfg["id"]);
}
}
}
void unit_type_data::unit_type_map_wrapper::add_advancement(const config& cfg, unit_type& to_unit) const
{
config::const_child_itors af;
for(af = cfg.child_range("advancefrom"); af.first != af.second; ++af.first)
{

View file

@ -294,45 +294,38 @@ public:
typedef std::map<std::string,unit_type> unit_type_map;
class unit_type_factory
class unit_type_map_wrapper
{
public:
unit_type_factory()
{
unit_cfg_ = NULL;
}
friend class unit_type_data;
unit_type_factory(const config& unit_cfg) :
unit_cfg_(&unit_cfg)
{}
public:
const race_map& races() const { return races_; }
void set_config(const config& cfg);
unit_type_map::const_iterator begin() const { return types_.begin(); }
unit_type_map::const_iterator end() const { return types_.end(); }
unit_type_map::const_iterator find(const std::string& key, unit_type::BUILD_STATUS status = unit_type::FULL) const;
void build_all(unit_type::BUILD_STATUS status) const;
private:
unit_type_map_wrapper() { unit_cfg_ = NULL; }
unit_type_map_wrapper(unit_type_map_wrapper& utf) {}
void set_unit_config(const config& unit_cfg) { unit_cfg_ = &unit_cfg; }
void set_unit_traits(const config::child_list unit_traits) { unit_traits_ = unit_traits; }
movement_type_map& movement_types() { return movement_types_; }
race_map& races() { return races_; }
const config* unit_config() { return unit_cfg_; }
unit_type_map::const_iterator find(const std::string& key);
const config& find_config(const std::string& key);
unit_type_map::iterator end() { return types_.end(); }
unit_type_map::iterator begin() { return types_.begin(); }
const config& find_config(const std::string& key) const;
std::pair<unit_type_map::iterator, bool> insert(const std::pair<std::string,unit_type>& utype) { return types_.insert(utype); }
void clear() {
types_.clear();
movement_types_.clear();
races_.clear();
}
std::pair<unit_type_map::iterator, bool> insert(const std::pair<std::string,unit_type>& utype) { return types_.insert(utype); }
void generate_help_info();
unit_type& build_unit_type(const std::string& key, unit_type::BUILD_STATUS status);
private:
unit_type_factory(unit_type_factory& utf) {}
void add_advancement(const config& cfg, unit_type& to_unit);
unit_type& build_unit_type(const std::string& key, unit_type::BUILD_STATUS status) const;
void add_advancefrom(const config& unit_cfg) const;
void add_advancement(const config& cfg, unit_type& to_unit) const;
mutable unit_type_map types_;
movement_type_map movement_types_;
@ -341,16 +334,13 @@ public:
const config* unit_cfg_;
};
void set_config(const config& cfg);
void clear();
static unit_type_map_wrapper& types() { return instance().unit_types_; }
mutable unit_type_factory unit_types;
private:
static unit_type_data* instance_;
mutable unit_type_map_wrapper unit_types_;
protected:
unit_type_data();
private:
static unit_type_data* instance_;
unit_type_data();
};
#endif