Changed game.cpp to use config_cache object for caching

This commit is contained in:
Pauli Nieminen 2008-08-27 21:58:51 +00:00
parent 98d065c731
commit fb70f62c97
8 changed files with 186 additions and 370 deletions

View file

@ -32,6 +32,8 @@ Version 1.5.3+svn:
* prevent some negative/nonsense values in direct WML unit modifications
* Renamed the advanceto key in [unit_type] to advances_to in order to be
consistent with its own and [unit]'s internals.
* Networking
* removed null termination character from end of packet send by wesnoth
* Miscellaneous and bug fixes:
* Changed side_drop handling not to automaticaly assign AI for side if
leader is dead (bug #12186)
@ -40,6 +42,7 @@ Version 1.5.3+svn:
of a number.
* Fixed [modify_turns] causing weird behavior when used in prestart
or start events to change current turn.
* Made config cache code available to eveverywhere in wesnoth
* Fixed [modify_turns] giving the unwanted side-effect of changing
turn limit when only current= modifier was used.
* Fixed [modify_turns] not updating $turn_number when current= was

View file

@ -146,7 +146,6 @@ wesnoth_sources = Split("""
attack_prediction_display.cpp
callable_objects.cpp
config_adapter.cpp
config_cache.cpp
controller_base.cpp
dialogs.cpp
floating_textbox.cpp
@ -244,6 +243,7 @@ if env['python']:
wesnoth_sources.extend(python_env.Object(Split("""
ai_python.cpp
ai.cpp
config_cache.cpp
multiplayer_connect.cpp
""")))
@ -354,13 +354,14 @@ libtest_utils = env.Library("test_utils", test_utils_sources)
test_sources = Split("""
tests/main.cpp
tests/test_config_cache.cpp
tests/test_network_worker.cpp
tests/test_team.cpp
tests/test_util.cpp
tests/gui/test_drop_target.cpp
tests/gui/test_save_dialog.cpp
""")
test_sources.extend(env.Object("tests/test_config_cache.cpp", EXTRA_DEFINE = env['python'] and "HAVE_PYTHON" or None))
test = test_env.WesnothProgram("test", test_sources + [libwesnoth_extras, libwesnoth_core, libwesnoth_sdl, libwesnoth,libtest_utils], have_test_prereqs)
#Export("test")

View file

@ -37,6 +37,8 @@
#include <ostream>
#include <string>
#include <vector>
#include "game_errors.hpp"
#include "tstring.hpp"
#include "serialization/string_utils.hpp"
@ -113,9 +115,8 @@ public:
std::string debug() const;
std::string hash() const;
struct error {
error(const std::string& msg) : message(msg) {}
std::string message;
struct error : public game::error {
error(const std::string& message) : game::error(message) {}
};
struct child_pos {

View file

@ -18,7 +18,6 @@
#include "gettext.hpp"
#include "game_config.hpp"
#include "game_display.hpp"
#include "loadscreen.hpp"
#include "log.hpp"
#include "marked-up_text.hpp"
#include "show_dialog.hpp"
@ -131,11 +130,6 @@ namespace game_config {
//read the file and then write to the cache
scoped_istream stream = preprocess_file(path, &defines_map, &error_log);
//reset the parse counter before reading the game files
if (loadscreen::global_loadscreen) {
loadscreen::global_loadscreen->parser_counter = 0;
}
read(cfg, *stream, &error_log);
if (!error_log.empty())
{
@ -151,7 +145,7 @@ namespace game_config {
for(preproc_map::const_iterator i = defines_map_.begin(); i != defines_map_.end(); ++i) {
if(i->second.value != "" || i->second.arguments.empty() == false) {
is_valid = false;
ERR_CONFIG << "Preproc define not valid\n";
ERR_CONFIG << "Preprocessor define not valid\n";
break;
}
@ -188,7 +182,7 @@ namespace game_config {
}
if(file_exists(fname) && (force_valid_cache_ || (dir_checksum == data_tree_checksum()))) {
LOG_CONFIG << "found valid cache at '" << fname << "' using it\n";
LOG_CONFIG << "found valid cache at '" << fname << "' with defines_map " << defines_string.str() << "\n";
log_scope("read cache");
try {
read_file(fname,cfg);
@ -229,17 +223,6 @@ namespace game_config {
}
return;
ERR_CONFIG << "caching cannot be done. Reading file\n";
std::string error_log;
read_configs(cfg, error_log);
if(!error_log.empty()) {
gui::show_error_message(*game_display::get_singleton(),
_("Warning: Errors occurred while loading game configuration files: '") +
font::nullify_markup(error_log));
}
}
void config_cache::set_use_cache(bool use)
@ -259,11 +242,13 @@ namespace game_config {
void config_cache::add_define(const std::string& define)
{
DBG_CONFIG << "adding define: " << define << "\n";
defines_map_[define] = preproc_define();
}
void config_cache::remove_define(const std::string& define)
{
DBG_CONFIG << "removing define: " << define << "\n";
defines_map_.erase(define);
}
}

View file

@ -16,6 +16,8 @@
#define CONFIG_CACHE_HPP_INCLUDED
#include <boost/utility.hpp>
#include <boost/scoped_ptr.hpp>
#include "config.hpp"
#include "serialization/preprocessor.hpp"
@ -119,6 +121,7 @@ namespace game_config {
}
};
typedef scoped_preproc_define_internal<config_cache> scoped_preproc_define;
typedef boost::scoped_ptr<scoped_preproc_define> scoped_preproc_define_sptr;
}
#endif

View file

@ -19,6 +19,7 @@
#include "about.hpp"
#include "config.hpp"
#include "config_cache.hpp"
#include "construct_dialog.hpp"
#include "cursor.hpp"
#include "dialogs.hpp"
@ -124,10 +125,7 @@ public:
bool play_test();
bool play_multiplayer_mode();
void reset_game_cfg();
void reset_defines_map();
void reload_changed_game_config();
void read_configs(std::string&);
bool is_loading() const;
bool load_game();
@ -159,8 +157,8 @@ private:
game_controller(const game_controller&);
void operator=(const game_controller&);
void read_game_cfg(bool use_cache);
void refresh_game_cfg(bool reset_translations=false);
void load_game_cfg();
void reset_translations();
void set_unit_data();
bool detect_video_settings(); // FIXME
@ -188,8 +186,6 @@ private:
std::string test_scenario_;
bool test_mode_, multiplayer_mode_, no_gui_;
bool use_caching_;
bool force_valid_cache_;
int force_bpp_;
config game_config_;
@ -206,13 +202,12 @@ private:
bool loaded_game_show_replay_;
bool loaded_game_cancel_orders_;
preproc_map defines_map_, old_defines_map_;
std::string multiplayer_server_;
bool jump_to_campaign_, jump_to_multiplayer_;
#ifdef USE_EDITOR2
bool jump_to_editor_;
#endif
game_config::config_cache& cache_;
};
game_controller::game_controller(int argc, char** argv) :
@ -234,8 +229,6 @@ game_controller::game_controller(int argc, char** argv) :
test_mode_(false),
multiplayer_mode_(false),
no_gui_(false),
use_caching_(true),
force_valid_cache_(false),
force_bpp_(-1),
game_config_(),
disp_(NULL),
@ -246,14 +239,13 @@ game_controller::game_controller(int argc, char** argv) :
loaded_game_(),
loaded_game_show_replay_(false),
loaded_game_cancel_orders_(false),
defines_map_(),
old_defines_map_(),
multiplayer_server_(),
jump_to_campaign_(false),
jump_to_multiplayer_(false)
#ifdef USE_EDITOR2
,jump_to_editor_(false)
#endif
,cache_(game_config::config_cache::instance())
{
bool no_sound = false;
for(arg_ = 1; arg_ != argc_; ++arg_) {
@ -265,7 +257,7 @@ game_controller::game_controller(int argc, char** argv) :
if(val == "--fps") {
preferences::set_show_fps(true);
} else if(val == "--nocache") {
use_caching_ = false;
cache_.set_use_cache(false);
} else if(val == "--max-fps") {
if(arg_+1 != argc_) {
++arg_;
@ -280,7 +272,7 @@ game_controller::game_controller(int argc, char** argv) :
preferences::set_draw_delay(fps);
}
} else if(val == "--validcache") {
force_valid_cache_ = true;
cache_.set_force_valid_cache(true);
} else if(val == "--resolution" || val == "-r") {
if(arg_+1 != argc_) {
++arg_;
@ -549,11 +541,12 @@ bool game_controller::init_video()
bool game_controller::init_config()
{
//Resets old_defines_map_, to force refresh_game_cfg to reload
//everything.
old_defines_map_.clear();
reset_game_cfg();
refresh_game_cfg();
cache_.clear_defines();
// make sure that multiplayer mode is set if command line parameter is selected
if (multiplayer_mode_)
cache_.add_define("MULTIPLAYER");
load_game_cfg();
game_config::load_config(game_config_.child("game_config"));
hotkey::deactivate_all_scopes();
@ -603,10 +596,10 @@ bool game_controller::play_test()
state_.scenario = test_scenario_;
try {
refresh_game_cfg();
load_game_cfg();
} catch(config::error&) {
reset_game_cfg();
refresh_game_cfg();
cache_.clear_defines();
load_game_cfg();
return false;
}
@ -861,32 +854,34 @@ bool game_controller::load_game()
error_log);
}
reset_defines_map();
defines_map_[cfg["difficulty"]] = preproc_define();
if(defines_map_.count("NORMAL")) {
defines_map_["MEDIUM"] = preproc_define();
}
cache_.clear_defines();
game_config::scoped_preproc_define dificulty_def(cfg["difficulty"]);
const std::string& campaign_define = cfg["campaign_define"];
game_config::scoped_preproc_define_sptr campaign_define_def;
if(campaign_define.empty() == false) {
defines_map_[campaign_define] = preproc_define();
campaign_define_def.reset(new game_config::scoped_preproc_define(campaign_define));
}
game_config::scoped_preproc_define_sptr campaign_type_def;
if (campaign_define.empty() && (cfg["campaign_type"] == "multiplayer")){
defines_map_["MULTIPLAYER"] = preproc_define();
campaign_type_def.reset(new game_config::scoped_preproc_define("MULTIPLAYER"));
}
const std::vector<std::string> campaign_xtra_defines = utils::split(cfg["campaign_extra_defines"]);
typedef boost::shared_ptr<game_config::scoped_preproc_define> define_ptr;
std::deque<define_ptr> extra_defines;
for(std::vector<std::string>::const_iterator i = campaign_xtra_defines.begin(); i != campaign_xtra_defines.end(); ++i) {
defines_map_[*i] = preproc_define();
define_ptr newdefine(new game_config::scoped_preproc_define(*i));
extra_defines.push_back(newdefine);
}
try {
refresh_game_cfg();
load_game_cfg();
} catch(config::error&) {
reset_game_cfg();
refresh_game_cfg();
cache_.clear_defines();
load_game_cfg();
return false;
}
@ -924,10 +919,10 @@ bool game_controller::load_game()
lexical_cast_default<unsigned> (state_.snapshot["random_calls"]);
state_.rng().seed_random(seed, calls);
} catch(game::error& e) {
} catch(config::error& e) {
gui::show_error_message(disp(), _("The file you have tried to load is corrupt: '") + e.message + '\'');
return false;
} catch(config::error& e) {
} catch(game::error& e) {
gui::show_error_message(disp(), _("The file you have tried to load is corrupt: '") + e.message + '\'');
return false;
} catch(io_exception&) {
@ -967,13 +962,13 @@ bool game_controller::load_game()
}
}
if(state_.campaign_type == "tutorial") {
defines_map_["TUTORIAL"] = preproc_define();
} else if(state_.campaign_type == "multiplayer") {
if(state_.campaign_type == "multiplayer") {
for(config::child_itors sides = state_.snapshot.child_range("side");
sides.first != sides.second; ++sides.first) {
if((**sides.first)["controller"] == "network")
(**sides.first)["controller"] = "human";
if((**sides.first)["controller"] == "network_ai")
(**sides.first)["controller"] = "human_ai";
}
}
@ -999,8 +994,8 @@ void game_controller::set_tutorial()
state_.campaign_type = "tutorial";
state_.scenario = "tutorial";
state_.campaign_define = "TUTORIAL";
reset_defines_map();
defines_map_["TUTORIAL"] = preproc_define();
cache_.clear_defines();
cache_.add_define("TUTORIAL");
}
@ -1088,8 +1083,8 @@ bool game_controller::new_campaign()
}
state_.difficulty = difficulties[dlg.result()];
reset_defines_map();
defines_map_[difficulties[dlg.result()]] = preproc_define();
cache_.clear_defines();
cache_.add_define(difficulties[dlg.result()]);
}
state_.campaign_define = campaign["define"];
@ -1149,13 +1144,9 @@ namespace
refresh_addon_version_info_cache();
//force a reload of configuration information
old_defines_map_.clear();
reset_game_cfg();
data_tree_checksum(true); // Reload checksums
refresh_game_cfg();
::init_textdomains(game_config_);
paths_manager_.set_paths(game_config_);
cache_.recheck_filetree_checksum();
clear_binary_paths_cache();
init_config();
}
void game_controller::start_wesnothd()
@ -1287,9 +1278,9 @@ bool game_controller::play_multiplayer()
}
/* do */ {
reset_defines_map();
defines_map_[state_.campaign_define] = preproc_define();
refresh_game_cfg();
cache_.clear_defines();
cache_.add_define(state_.campaign_define);
load_game_cfg();
events::discard(INPUT_MASK); // prevent the "keylogger" effect
cursor::set(cursor::NORMAL);
// update binary paths
@ -1370,7 +1361,7 @@ bool game_controller::change_language()
SDL_WM_SetCaption(wm_title_string.c_str(), NULL);
}
refresh_game_cfg(true);
reset_translations();
}
return true;
@ -1392,214 +1383,6 @@ void game_controller::show_upload_begging()
}
void game_controller::read_configs(std::string& error_log)
{
// We need this as soon as possible for loading MP binary_paths
// only when they are needed.
if(multiplayer_mode_) {
defines_map_["MULTIPLAYER"] = preproc_define();
}
preproc_map defines_map(defines_map_);
std::string user_error_log;
//read the file and then write to the cache
scoped_istream stream = preprocess_file("data/", &defines_map, &error_log);
//reset the parse counter before reading the game files
if (loadscreen::global_loadscreen) {
loadscreen::global_loadscreen->parser_counter = 0;
}
read(game_config_, *stream, &error_log);
// clone and put the gfx rules aside so that we can prepend the add-on
// rules to them.
config core_terrain_rules;
// FIXME: there should be a canned algorithm for cloning child_list objects,
// along with the memory their elements point to... little implementation detail.
foreach(config const* p_cfg, game_config_.get_children("terrain_graphics")) {
core_terrain_rules.add_child("terrain_graphics", *p_cfg);
}
game_config_.clear_children("terrain_graphics");
// load usermade add-ons
const std::string user_campaign_dir = get_addon_campaigns_dir();
std::vector< std::string > error_addons;
// Scan addon directories
std::vector<std::string> user_addons;
get_files_in_dir(user_campaign_dir,NULL,&user_addons,ENTIRE_FILE_PATH);
// Load the addons
for(std::vector<std::string>::const_iterator uc = user_addons.begin(); uc != user_addons.end(); ++uc) {
std::string oldstyle_cfg = *uc + ".cfg";
std::string main_cfg = *uc + "/_main.cfg";
std::string toplevel;
if (file_exists(oldstyle_cfg))
toplevel = oldstyle_cfg;
else if (file_exists(main_cfg))
toplevel = main_cfg;
else
continue;
try {
preproc_map addon_defines_map(defines_map);
scoped_istream stream = preprocess_file(toplevel, &addon_defines_map);
std::string addon_error_log;
config umc_cfg;
read(umc_cfg, *stream, &addon_error_log);
if (addon_error_log.empty()) {
game_config_.append(umc_cfg);
} else {
user_error_log += addon_error_log;
error_addons.push_back(*uc);
}
} catch(config::error& err) {
ERR_CONFIG << "error reading usermade add-on '" << *uc << "'\n";
error_addons.push_back(*uc);
user_error_log += err.message + "\n";
} catch(preproc_config::error&) {
ERR_CONFIG << "error reading usermade add-on '" << *uc << "'\n";
error_addons.push_back(*uc);
//no need to modify the error log here, already done by the preprocessor
} catch(io_exception&) {
ERR_CONFIG << "error reading usermade add-on '" << *uc << "'\n";
error_addons.push_back(*uc);
}
if(error_addons.empty() == false) {
std::stringstream msg;
msg << _n("The following add-on had errors and could not be loaded:",
"The following add-ons had errors and could not be loaded:",
error_addons.size());
for(std::vector<std::string>::const_iterator i = error_addons.begin(); i != error_addons.end(); ++i) {
msg << "\n" << *i;
}
msg << "\n" << _("ERROR DETAILS:") << "\n" << font::nullify_markup(user_error_log);
gui::show_error_message(disp(),msg.str());
}
}
game_config_.merge_children("units");
game_config_.append(core_terrain_rules);
config& hashes = game_config_.add_child("multiplayer_hashes");
for(config::child_list::const_iterator ch = game_config_.get_children("multiplayer").begin(); ch != game_config_.get_children("multiplayer").end(); ++ch) {
hashes[(**ch)["id"]] = (*ch)->hash();
}
}
//this function reads the game configuration, searching for valid cached copies first
void game_controller::read_game_cfg(bool use_cache)
{
log_scope("read_game_cfg");
loadscreen::global_loadscreen_manager loadscreen_manager(disp().video());
bool is_valid = true;
std::stringstream str;
for(preproc_map::const_iterator i = defines_map_.begin(); i != defines_map_.end(); ++i) {
if(i->second.value != "" || i->second.arguments.empty() == false) {
is_valid = false;
break;
}
str << " " << i->first;
}
//std::string localename = get_locale().localename;
//str << "-lang_" << (localename.empty() ? "default" : localename);
if(is_valid) {
const std::string& cache = get_cache_dir();
if(cache != "") {
sha1_hash sha(str.str()); // use a hash for a shorter display of the defines
const std::string fname = cache + "/cache-v" + game_config::version + "-" + sha.display();
const std::string fname_checksum = fname + ".checksum";
file_tree_checksum dir_checksum;
if(use_cache && !force_valid_cache_) {
try {
if(file_exists(fname_checksum)) {
config checksum_cfg;
scoped_istream stream = istream_file(fname_checksum);
read(checksum_cfg, *stream);
dir_checksum = file_tree_checksum(checksum_cfg);
}
} catch(config::error&) {
ERR_CONFIG << "cache checksum is corrupt\n";
} catch(io_exception&) {
ERR_CONFIG << "error reading cache checksum\n";
}
}
if(force_valid_cache_) {
LOG_CONFIG << "skipping cache validation (forced)\n";
}
if(use_cache && file_exists(fname) && (force_valid_cache_ || (dir_checksum == data_tree_checksum()))) {
LOG_CONFIG << "found valid cache at '" << fname << "' using it\n";
log_scope("read cache");
try {
scoped_istream stream = istream_file(fname);
read_compressed(game_config_, *stream);
set_unit_data();
return;
} catch(config::error&) {
ERR_CONFIG << "cache is corrupt. Loading from files\n";
} catch(io_exception&) {
ERR_CONFIG << "error reading cache. Loading from files\n";
}
}
LOG_CONFIG << "no valid cache found. Writing cache to '" << fname << " with defines_map "<< str.str() << "'\n";
DBG_CONFIG << ((use_cache && file_exists(fname)) ? "yes":"no ") << " " << dir_checksum.modified << "==" << data_tree_checksum().modified << " " << dir_checksum.nfiles << "==" << data_tree_checksum().nfiles << " " << dir_checksum.sum_size << "==" << data_tree_checksum().sum_size << "\n";
std::string error_log;
read_configs(error_log);
if(!error_log.empty()) {
gui::show_error_message(disp(),
_("Warning: Errors occurred while loading game configuration files: '") +
font::nullify_markup(error_log));
} else {
try {
scoped_ostream cache = ostream_file(fname);
write_compressed(*cache, game_config_);
config checksum_cfg;
data_tree_checksum().write(checksum_cfg);
scoped_ostream checksum = ostream_file(fname_checksum);
write(*checksum, checksum_cfg);
} catch(io_exception&) {
ERR_FS << "could not write to cache '" << fname << "'\n";
}
}
set_unit_data();
return;
}
}
ERR_CONFIG << "caching cannot be done. Reading file\n";
std::string error_log;
read_configs(error_log);
if(!error_log.empty()) {
gui::show_error_message(disp(),
_("Warning: Errors occurred while loading game configuration files: '") +
font::nullify_markup(error_log));
}
set_unit_data();
}
void game_controller::set_unit_data(){
const config* const units = game_config_.child("units");
if(units != NULL) {
@ -1607,101 +1390,146 @@ void game_controller::set_unit_data(){
}
}
void game_controller::refresh_game_cfg(bool reset_translations)
void game_controller::reset_translations()
{
cursor::setter cur(cursor::WAIT);
try {
game_config_.reset_translation();
// we may have translatable strings in [game_config]
// e.g. team color names are defined there
game_config::load_config(game_config_.child("game_config"));
} catch(game::error& e) {
ERR_CONFIG << "Error loading game configuration files\n";
gui::show_error_message(disp(), _("Error loading game configuration files: '") +
font::nullify_markup(e.message) + _("' (The game will now exit)"));
throw;
}
}
void game_controller::load_game_cfg()
{
loadscreen::global_loadscreen_manager loadscreen_manager(disp().video());
cursor::setter cur(cursor::WAIT);
// The loadscreen will erase the titlescreen
// NOTE: even without loadscreen, needed after MP lobby
gui::set_background_dirty();
try {
if(old_defines_map_.empty() || defines_map_ != old_defines_map_ || reset_translations) {
cursor::setter cur(cursor::WAIT);
/**
* Read all game configs
* First we should load data/
* Then handle terrains so that they are last loaded from data/
* 2nd everything in userdata
**/
//reset the parse counter before reading the game files
loadscreen::global_loadscreen->parser_counter = 0;
if(!reset_translations) {
game_config_.clear();
read_game_cfg(use_caching_);
} else {
game_config_.reset_translation();
// we may have translatable strings in [game_config]
// e.g. team color names are defined there
game_config::load_config(game_config_.child("game_config"));
}
cache_.get_config(game_config::path +"/data", game_config_);
old_defines_map_ = defines_map_;
// clone and put the gfx rules aside so that we can prepend the add-on
// rules to them.
config core_terrain_rules;
// FIXME: there should be a canned algorithm for cloning child_list objects,
// along with the memory their elements point to... little implementation detail.
foreach(config const* p_cfg, game_config_.get_children("terrain_graphics")) {
core_terrain_rules.add_child("terrain_graphics", *p_cfg);
}
} catch(config::error& e) {
game_config_.clear_children("terrain_graphics");
// load usermade add-ons
const std::string user_campaign_dir = get_addon_campaigns_dir();
std::vector< std::string > error_addons;
// Scan addon directories
std::vector<std::string> user_addons;
get_files_in_dir(user_campaign_dir,NULL,&user_addons,ENTIRE_FILE_PATH);
std::string user_error_log;
// Load the addons
for(std::vector<std::string>::const_iterator uc = user_addons.begin(); uc != user_addons.end(); ++uc) {
std::string oldstyle_cfg = *uc + ".cfg";
std::string main_cfg = *uc + "/_main.cfg";
std::string toplevel;
if (file_exists(oldstyle_cfg))
toplevel = oldstyle_cfg;
else if (file_exists(main_cfg))
toplevel = main_cfg;
else
continue;
try {
config umc_cfg;
cache_.get_config(toplevel, umc_cfg);
game_config_.append(umc_cfg);
} catch(config::error& err) {
ERR_CONFIG << "error reading usermade add-on '" << *uc << "'\n";
error_addons.push_back(*uc);
user_error_log += err.message + "\n";
} catch(preproc_config::error& err) {
ERR_CONFIG << "error reading usermade add-on '" << *uc << "'\n";
error_addons.push_back(*uc);
user_error_log += err.message + "\n";
} catch(io_exception&) {
ERR_CONFIG << "error reading usermade add-on '" << *uc << "'\n";
error_addons.push_back(*uc);
}
if(error_addons.empty() == false) {
std::stringstream msg;
msg << _n("The following add-on had errors and could not be loaded:",
"The following add-ons had errors and could not be loaded:",
error_addons.size());
for(std::vector<std::string>::const_iterator i = error_addons.begin(); i != error_addons.end(); ++i) {
msg << "\n" << *i;
}
msg << "\n" << _("ERROR DETAILS:") << "\n" << font::nullify_markup(user_error_log);
gui::show_error_message(disp(),msg.str());
}
}
game_config_.merge_children("units");
game_config_.append(core_terrain_rules);
config& hashes = game_config_.add_child("multiplayer_hashes");
for(config::child_list::const_iterator ch = game_config_.get_children("multiplayer").begin(); ch != game_config_.get_children("multiplayer").end(); ++ch) {
hashes[(**ch)["id"]] = (*ch)->hash();
}
set_unit_data();
} catch(game::error& e) {
ERR_CONFIG << "Error loading game configuration files\n";
gui::show_error_message(disp(), _("Error loading game configuration files: '") +
font::nullify_markup(e.message) + _("' (The game will now exit)"));
throw e;
} catch(preproc_config::error& e) {
ERR_CONFIG << "Error loading game configuration files\n";
gui::show_error_message(disp(), _("Error loading game configuration files: '") +
font::nullify_markup(e.message) + _("' (The game will now exit)"));
throw e;
throw;
}
}
void game_controller::reset_game_cfg()
{
reset_defines_map();
//load in the game's configuration files
#if defined(__APPLE__)
defines_map_["APPLE"] = preproc_define();
#endif
if(multiplayer_mode_) {
defines_map_["MULTIPLAYER"] = preproc_define();
} else {
defines_map_["NORMAL"] = preproc_define();
defines_map_["MEDIUM"] = preproc_define();
}
//refresh_game_cfg();
}
void game_controller::reset_defines_map()
{
defines_map_.clear();
/* APPLE is only meant for configuration so it's not there */
#ifdef USE_TINY_GUI
defines_map_["TINY"] = preproc_define();
#endif
if (game_config::small_gui)
defines_map_["SMALL_GUI"] = preproc_define();
#ifdef HAVE_PYTHON
defines_map_["PYTHON"] = preproc_define();
#endif
}
void game_controller::play_game(RELOAD_GAME_DATA reload)
{
loadscreen::global_loadscreen_manager loadscreen_manager(disp().video());
loadscreen::global_loadscreen->set_progress(0, _("Loading data files"));
if(reload == RELOAD_DATA) {
game_config::scoped_preproc_define_sptr campaign_define;
if(state_.campaign_define.empty() == false) {
defines_map_[state_.campaign_define] = preproc_define();
campaign_define.reset(new game_config::scoped_preproc_define(state_.campaign_define));
}
for( std::vector<std::string>::const_iterator i = state_.campaign_xtra_defines.begin();
i != state_.campaign_xtra_defines.end(); ++i) {
defines_map_[*i] = preproc_define();
typedef boost::shared_ptr<game_config::scoped_preproc_define> define_ptr;
std::deque<define_ptr> extra_defines;
for(std::vector<std::string>::const_iterator i = state_.campaign_xtra_defines.begin(); i != state_.campaign_xtra_defines.end(); ++i) {
define_ptr newdefine(new game_config::scoped_preproc_define(*i));
extra_defines.push_back(newdefine);
}
if(defines_map_.count("NORMAL")) {
defines_map_["MEDIUM"] = preproc_define();
}
try {
refresh_game_cfg();
load_game_cfg();
} catch(config::error&) {
reset_game_cfg();
refresh_game_cfg();
cache_.clear_defines();
load_game_cfg();
return;
}
}
@ -1759,10 +1587,10 @@ void game_controller::play_replay()
#ifdef USE_EDITOR2
editor2::EXIT_STATUS game_controller::start_editor()
{
reset_game_cfg();
defines_map_["EDITOR"] = preproc_define();
defines_map_["EDITOR2"] = preproc_define();
refresh_game_cfg();
cache_.clear_defines();
cache_.add_define("EDITOR");
cache_.add_define("EDITOR2");
load_game_cfg();
const binary_paths_manager bin_paths_manager(game_config_);
return editor2::start(game_config_, video_);
}
@ -2114,13 +1942,7 @@ static int play_game(int argc, char** argv)
LOG_CONFIG << "time elapsed: "<< (SDL_GetTicks() - start_ticks) << " ms\n";
for(int first_time = true;;first_time = false){
//init_config already processed the configs, so we don't need to do it for the
//first loop pass.
if (!first_time){
//make sure the game config is always set to how it should be at the title screen
//game.reset_game_cfg();
}
for(;;){
// reset the TC, since a game can modify it, and it may be used
// by images in add-ons or campaigns dialogs

View file

@ -866,7 +866,7 @@ connection receive_data(std::vector<char>& buf
{
bandwidth_in = &temp;
}
const int headers = 5;
const int headers = 4;
bandwidth_in->reset(new network::bandwidth_in(buf.size() + headers));
}
#endif

View file

@ -23,6 +23,8 @@
#include <string>
#include <vector>
#include "game_errors.hpp"
struct preproc_define
{
preproc_define() : value(""), arguments(), textdomain(""), linenum(0), location("") {}
@ -42,9 +44,8 @@ struct preproc_define
std::ostream& operator<<(std::ostream& stream, const preproc_define& def);
struct preproc_config {
struct error {
error(const std::string& msg) : message(msg) {}
std::string message;
struct error : public game::error {
error(const std::string& message) : game::error(message) {}
};
};