Move game config loading to new manager class.

This commit is contained in:
Andrius Silinskas 2013-06-05 16:38:49 +01:00
parent 75f9b81435
commit cb6119abb0
8 changed files with 394 additions and 272 deletions

View file

@ -256,6 +256,7 @@ wesnoth_sources = Split("""
formula_function.cpp
formula_string_utils.cpp
formula_tokenizer.cpp
game_config_manager.cpp
game_controller.cpp
game_controller_abstract.cpp
game_controller_new.cpp

View file

@ -18,6 +18,7 @@
#include "addon/manager.hpp"
#include "addon/manager_ui.hpp"
#include "commandline_options.hpp"
#include "game_config_manager.hpp"
#include "game_controller.hpp"
#include "game_controller_new.hpp"
#include "gui/dialogs/title_screen.hpp"
@ -473,6 +474,8 @@ static int do_gameloop(int argc, char** argv)
gui2::init();
const gui2::event::tmanager gui_event_manager;
game_config_manager config_manager(cmdline_opts, game->disp());
loadscreen::start_stage("load config");
res = game->init_config();
if(res == false) {

279
src/game_config_manager.cpp Normal file
View file

@ -0,0 +1,279 @@
/*
Copyright (C) 2013 by Andrius Silinskas <silinskas.andrius@gmail.com>
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
#include "game_config_manager.hpp"
#include "about.hpp"
#include "addon/manager.hpp"
#include "ai/configuration.hpp"
#include "builder.hpp"
#include "cursor.hpp"
#include "game_config.hpp"
#include "gettext.hpp"
#include "gui/dialogs/message.hpp"
#include "language.hpp"
#include "loadscreen.hpp"
#include "log.hpp"
#include "resources.hpp"
#include "scripting/lua.hpp"
static lg::log_domain log_config("config");
#define ERR_CONFIG LOG_STREAM(err, log_config)
#define WRN_CONFIG LOG_STREAM(warn, log_config)
#define LOG_CONFIG LOG_STREAM(info, log_config)
game_config_manager::game_config_manager(const commandline_options& cmdline_opts, game_display& display) :
cmdline_opts_(cmdline_opts),
disp_(display),
game_config_(),
defines_(),
old_defines_map_(),
paths_manager_(),
cache_(game_config::config_cache::instance())
{
resources::config_manager = this;
if (cmdline_opts_.nocache)
cache_.set_use_cache(false);
if (cmdline_opts_.validcache)
cache_.set_force_valid_cache(true);
}
game_config_manager::~game_config_manager()
{
resources::config_manager = NULL;
}
bool game_config_manager::init_config(const bool force, const bool jump_to_editor)
{
load_game_cfg(force);
// make sure that multiplayer mode is set if command line parameter is selected
if (cmdline_opts_.multiplayer)
cache_.add_define("MULTIPLAYER");
if (cmdline_opts_.test)
cache_.add_define("TEST");
if (jump_to_editor)
cache_.add_define("EDITOR");
if (!cmdline_opts_.multiplayer && !cmdline_opts_.test && !jump_to_editor)
cache_.add_define("TITLE_SCREEN");
game_config::load_config(game_config_.child("game_config"));
hotkey::deactivate_all_scopes();
hotkey::set_scope_active(hotkey::SCOPE_GENERAL);
hotkey::set_scope_active(hotkey::SCOPE_GAME);
hotkey::load_hotkeys(game_config(), true);
paths_manager_.set_paths(game_config());
::init_textdomains(game_config());
about::set_about(game_config());
ai::configuration::init(game_config());
return true;
}
void game_config_manager::load_game_cfg(const bool force)
{
// scoped defines
typedef boost::shared_ptr<game_config::scoped_preproc_define> define_ptr;
std::deque<define_ptr> defines;
for(std::vector<std::pair<std::string, bool> >::iterator it = defines_.begin(); it != defines_.end(); ++it) {
define_ptr newdefine(new game_config::scoped_preproc_define((*it).first, (*it).second));
defines.push_back(newdefine);
}
defines_.clear();
// make sure that 'debug mode' symbol is set if command line parameter is selected
// also if we're in multiplayer and actual debug mode is disabled
if (game_config::debug || game_config::mp_debug) {
cache_.add_define("DEBUG_MODE");
}
if (!game_config_.empty() && !force && old_defines_map_ == cache_.get_preproc_map())
return; // game_config already holds requested config in memory
old_defines_map_ = cache_.get_preproc_map();
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
try {
/**
* Read all game configs
* First we should load data/
* Then handle terrains so that they are last loaded from data/
* 2nd everything in userdata
**/
loadscreen::start_stage("verify cache");
data_tree_checksum();
loadscreen::start_stage("create cache");
// start transaction so macros are shared
game_config::config_cache_transaction main_transaction;
cache_.get_config(game_config::path +"/data", game_config_);
main_transaction.lock();
/* Put the gfx rules aside so that we can prepend the add-on
rules to them. */
config core_terrain_rules;
core_terrain_rules.splice_children(game_config_, "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_dirs;
// Scan for standalone files
std::vector<std::string> user_files;
// The addons that we'll actually load
std::vector<std::string> addons_to_load;
get_files_in_dir(user_campaign_dir,&user_files,&user_dirs,ENTIRE_FILE_PATH);
std::stringstream user_error_log;
// Append the $user_campaign_dir/*.cfg files to addons_to_load.
for(std::vector<std::string>::const_iterator uc = user_files.begin(); uc != user_files.end(); ++uc) {
const std::string file = *uc;
const int size_minus_extension = file.size() - 4;
if(file.substr(size_minus_extension, file.size()) == ".cfg") {
bool ok = true;
// Allowing it if the dir doesn't exist, for the single-file add-on.
if(file_exists(file.substr(0, size_minus_extension))) {
// Unfortunately, we create the dir plus _info.cfg ourselves on download
std::vector<std::string> dirs, files;
get_files_in_dir(file.substr(0, size_minus_extension), &files, &dirs);
if(dirs.size() > 0)
ok = false;
if(files.size() > 1)
ok = false;
if(files.size() == 1 && files[0] != "_info.cfg")
ok = false;
}
if(!ok) {
const int userdata_loc = file.find("data/add-ons") + 5;
ERR_CONFIG << "error reading usermade add-on '" << file << "'\n";
error_addons.push_back(file);
user_error_log << "The format '~" << file.substr(userdata_loc) << "' is only for single-file add-ons, use '~" << file.substr(userdata_loc, size_minus_extension - userdata_loc) << "/_main.cfg' instead.\n";
} else
addons_to_load.push_back(file);
}
}
// Append the $user_campaign_dir/*/_main.cfg files to addons_to_load.
for(std::vector<std::string>::const_iterator uc = user_dirs.begin(); uc != user_dirs.end(); ++uc){
const std::string main_cfg = *uc + "/_main.cfg";
if (file_exists(main_cfg))
addons_to_load.push_back(main_cfg);
}
// Load the addons
for(std::vector<std::string>::const_iterator uc = addons_to_load.begin(); uc != addons_to_load.end(); ++uc) {
const std::string toplevel = *uc;
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' << user_error_log.str();
gui2::show_error_message(disp_.video(),msg.str());
}
// Extract the Lua scripts at toplevel.
extract_preload_scripts(game_config_);
game_config_.clear_children("lua");
config colorsys_info;
colorsys_info.splice_children(game_config_, "color_range");
colorsys_info.splice_children(game_config_, "color_palette");
game_config_.merge_children("units");
game_config_.splice_children(core_terrain_rules, "terrain_graphics");
config& hashes = game_config_.add_child("multiplayer_hashes");
BOOST_FOREACH(const config &ch, game_config_.child_range("multiplayer")) {
hashes[ch["id"]] = ch.hash();
}
game_config::add_color_info(colorsys_info);
//set_unit_data();
loadscreen::start_stage("load unit types");
if (config &units = game_config_.child("units")) {
unit_types.set_config(units);
}
terrain_builder::set_terrain_rules_cfg(game_config());
::init_strings(game_config());
theme::set_known_themes(&game_config());
} catch(game::error& e) {
ERR_CONFIG << "Error loading game configuration files\n";
gui2::show_error_message(disp_.video(), _("Error loading game configuration files: '") +
e.message + _("' (The game will now exit)"));
throw;
}
}
void game_config_manager::reload_changed_game_config(const bool jump_to_editor)
{
// rebuild addon version info cache
refresh_addon_version_info_cache();
//force a reload of configuration information
cache_.recheck_filetree_checksum();
old_defines_map_.clear();
clear_binary_paths_cache();
init_config(true, jump_to_editor);
}
void game_config_manager::add_define(const std::string name, const bool add)
{
defines_.push_back(std::make_pair(name, add));
}
void game_config_manager::add_cache_define(const std::string name)
{
cache_.add_define(name);
}

View file

@ -0,0 +1,61 @@
/*
Copyright (C) 2013 by Andrius Silinskas <silinskas.andrius@gmail.com>
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
#ifndef GAME_CONFIG_MANAGER_HPP_INCLUDED
#define GAME_CONFIG_MANAGER_HPP_INCLUDED
#include "commandline_options.hpp"
#include "config_cache.hpp"
#include "game_display.hpp"
#include "filesystem.hpp"
class config;
class game_config_manager
{
friend class game_controller;
public:
game_config_manager(const commandline_options& cmdline_opts, game_display& disp);
~game_config_manager();
const config& game_config() const { return game_config_; }
void add_define(const std::string name, const bool add = true);
void add_cache_define(const std::string name);
bool init_config(const bool force = false, const bool jump_to_editor = false);
void load_game_cfg(const bool force = false);
void reload_changed_game_config(const bool jump_to_editor = false);
protected:
game_config::config_cache& cache() { return cache_; }
binary_paths_manager& bin_paths_manager() { return paths_manager_; }
private:
game_config_manager(const game_config_manager&);
const commandline_options& cmdline_opts_;
game_display& disp_;
config game_config_;
std::vector<std::pair<std::string, bool> > defines_;
preproc_map old_defines_map_;
binary_paths_manager paths_manager_;
game_config::config_cache& cache_;
};
#endif

View file

@ -15,9 +15,6 @@
#include "game_controller.hpp"
#include "about.hpp"
#include "addon/manager.hpp"
#include "ai/configuration.hpp"
#include "builder.hpp"
#include "construct_dialog.hpp"
#include "gettext.hpp"
#include "gui/dialogs/addon_connect.hpp"
@ -84,18 +81,14 @@ game_controller::game_controller(const commandline_options& cmdline_opts, const
hotkey_manager_(),
music_thinker_(),
resize_monitor_(),
paths_manager_(),
test_scenario_("test"),
screenshot_map_(),
screenshot_filename_(),
game_config_(),
old_defines_map_(),
state_(),
multiplayer_server_(),
jump_to_multiplayer_(false),
jump_to_campaign_(false, -1, "", ""),
jump_to_editor_(false),
cache_(game_config::config_cache::instance())
jump_to_editor_(false)
{
bool no_music = false;
bool no_sound = false;
@ -183,8 +176,6 @@ game_controller::game_controller(const commandline_options& cmdline_opts, const
set_new_storyscreen(true);
if (cmdline_opts_.new_widgets)
gui2::new_widgets = true;
if (cmdline_opts_.nocache)
cache_.set_use_cache(false);
if (cmdline_opts_.nodelay)
game_config::no_delay = true;
if (cmdline_opts_.nomusic)
@ -257,8 +248,6 @@ game_controller::game_controller(const commandline_options& cmdline_opts, const
if (!cmdline_opts_.test->empty())
test_scenario_ = *cmdline_opts_.test;
}
if (cmdline_opts_.validcache)
cache_.set_force_valid_cache(true);
if (cmdline_opts_.windowed)
preferences::set_fullscreen(false);
if (cmdline_opts_.with_replay)
@ -287,36 +276,9 @@ game_controller::game_controller(const commandline_options& cmdline_opts, const
bool game_controller::init_config(const bool force)
{
cache_.clear_defines();
resources::config_manager->cache().clear_defines();
// make sure that multiplayer mode is set if command line parameter is selected
if (cmdline_opts_.multiplayer)
cache_.add_define("MULTIPLAYER");
if (cmdline_opts_.test)
cache_.add_define("TEST");
if (jump_to_editor_)
cache_.add_define("EDITOR");
if (!cmdline_opts_.multiplayer && !cmdline_opts_.test && !jump_to_editor_)
cache_.add_define("TITLE_SCREEN");
load_game_cfg(force);
game_config::load_config(game_config_.child("game_config"));
hotkey::deactivate_all_scopes();
hotkey::set_scope_active(hotkey::SCOPE_GENERAL);
hotkey::set_scope_active(hotkey::SCOPE_GAME);
hotkey::load_hotkeys(game_config(), true);
paths_manager_.set_paths(game_config());
::init_textdomains(game_config());
about::set_about(game_config());
ai::configuration::init(game_config());
return true;
return resources::config_manager->init_config(force, jump_to_editor_);
}
bool game_controller::play_test()
@ -334,11 +296,11 @@ bool game_controller::play_test()
state_.classification().campaign_type = "test";
state_.carryover_sides_start["next_scenario"] = test_scenario_;
state_.classification().campaign_define = "TEST";
cache_.add_define("TEST");
resources::config_manager->add_cache_define("TEST");
load_game_cfg();
resources::config_manager->load_game_cfg();
paths_manager_.set_paths(game_config());
resources::config_manager->bin_paths_manager().set_paths(game_config());
try {
play_game(disp(),state_,game_config());
@ -355,9 +317,9 @@ bool game_controller::play_screenshot_mode()
return true;
}
cache_.clear_defines();
cache_.add_define("EDITOR");
load_game_cfg();
resources::config_manager->cache().clear_defines();
resources::config_manager->add_define("EDITOR");
resources::config_manager->load_game_cfg();
const binary_paths_manager bin_paths_manager(game_config());
::init_textdomains(game_config());
@ -377,29 +339,26 @@ bool game_controller::load_game()
try {
load.load_game(game::load_game_exception::game, game::load_game_exception::show_replay, game::load_game_exception::cancel_orders, game::load_game_exception::select_difficulty, game::load_game_exception::difficulty);
cache_.clear_defines();
game_config::scoped_preproc_define difficulty_def(load.get_difficulty());
resources::config_manager->cache().clear_defines();
game_config::scoped_preproc_define campaign_define_def(state_.classification().campaign_define, !state_.classification().campaign_define.empty());
resources::config_manager->add_define(load.get_difficulty());
resources::config_manager->add_define(state_.classification().campaign_define, !state_.classification().campaign_define.empty());
resources::config_manager->add_define("MULTIPLAYER", state_.classification().campaign_define.empty() && (state_.classification().campaign_type == "multiplayer"));
game_config::scoped_preproc_define campaign_type_def("MULTIPLAYER", state_.classification().campaign_define.empty() && (state_.classification().campaign_type == "multiplayer"));
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_.classification().campaign_xtra_defines.begin(); i != state_.classification().campaign_xtra_defines.end(); ++i) {
define_ptr newdefine(new game_config::scoped_preproc_define(*i));
extra_defines.push_back(newdefine);
for(std::vector<std::string>::const_iterator i = state_.classification().campaign_xtra_defines.begin();
i != state_.classification().campaign_xtra_defines.end(); ++i) {
resources::config_manager->add_define(*i);
}
try {
load_game_cfg();
resources::config_manager->load_game_cfg();
} catch(config::error&) {
cache_.clear_defines();
load_game_cfg();
resources::config_manager->cache().clear_defines();
resources::config_manager->load_game_cfg();
return false;
}
paths_manager_.set_paths(game_config());
resources::config_manager->bin_paths_manager().set_paths(game_config());
load.set_gamestate();
} catch(load_game_cancelled_exception&) {
@ -493,9 +452,8 @@ void game_controller::set_tutorial()
state_.classification().campaign_type = "tutorial";
state_.carryover_sides_start["next_scenario"] = "tutorial";
state_.classification().campaign_define = "TUTORIAL";
cache_.clear_defines();
cache_.add_define("TUTORIAL");
resources::config_manager->cache().clear_defines();
resources::config_manager->add_define("TUTORIAL");
}
void game_controller::mark_completed_campaigns(std::vector<config> &campaigns)
@ -619,11 +577,11 @@ bool game_controller::new_campaign()
}
state_.carryover_sides_start["difficulty"] = difficulties[difficulty];
cache_.clear_defines();
cache_.add_define(difficulties[difficulty]);
resources::config_manager->cache().clear_defines();
resources::config_manager->add_define(difficulties[difficulty]);
} else {
//clear even when there is no difficulty
cache_.clear_defines();
resources::config_manager->cache().clear_defines();
}
state_.classification().campaign_define = campaign["define"].str();
@ -680,14 +638,7 @@ bool game_controller::goto_editor()
void game_controller::reload_changed_game_config()
{
// rebuild addon version info cache
refresh_addon_version_info_cache();
//force a reload of configuration information
cache_.recheck_filetree_checksum();
old_defines_map_.clear();
clear_binary_paths_cache();
init_config(true);
resources::config_manager->reload_changed_game_config(jump_to_editor_);
}
void game_controller::start_wesnothd()
@ -783,13 +734,13 @@ bool game_controller::play_multiplayer()
}
/* do */ {
cache_.clear_defines();
game_config::scoped_preproc_define multiplayer(state_.classification().campaign_define);
load_game_cfg();
resources::config_manager->cache().clear_defines();
resources::config_manager->add_define(state_.classification().campaign_define);
resources::config_manager->load_game_cfg();
events::discard_input(); // prevent the "keylogger" effect
cursor::set(cursor::NORMAL);
// update binary paths
paths_manager_.set_paths(game_config());
resources::config_manager->bin_paths_manager().set_paths(game_config());
clear_binary_paths_cache();
}
@ -859,13 +810,13 @@ bool game_controller::play_multiplayer_commandline()
state_.classification().campaign_type = "multiplayer";
state_.classification().campaign_define = "MULTIPLAYER";
cache_.clear_defines();
game_config::scoped_preproc_define multiplayer(state_.classification().campaign_define);
load_game_cfg();
resources::config_manager->cache().clear_defines();
resources::config_manager->add_define(state_.classification().campaign_define);
resources::config_manager->load_game_cfg();
events::discard_input(); // prevent the "keylogger" effect
cursor::set(cursor::NORMAL);
// update binary paths
paths_manager_.set_paths(game_config());
resources::config_manager->bin_paths_manager().set_paths(game_config());
clear_binary_paths_cache();
config game_data;
@ -899,189 +850,22 @@ void game_controller::show_preferences()
disp().redraw_everything();
}
void game_controller::set_unit_data()
{
loadscreen::start_stage("load unit types");
if (config &units = game_config_.child("units")) {
unit_types.set_config(units);
}
}
void game_controller::load_game_cfg(const bool force)
{
// make sure that 'debug mode' symbol is set if command line parameter is selected
// also if we're in multiplayer and actual debug mode is disabled
if (game_config::debug || game_config::mp_debug) {
cache_.add_define("DEBUG_MODE");
}
if (!game_config_.empty() && !force
&& old_defines_map_ == cache_.get_preproc_map())
return; // game_config already holds requested config in memory
old_defines_map_ = cache_.get_preproc_map();
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
try {
/**
* Read all game configs
* First we should load data/
* Then handle terrains so that they are last loaded from data/
* 2nd everything in userdata
**/
loadscreen::start_stage("verify cache");
data_tree_checksum();
loadscreen::start_stage("create cache");
// start transaction so macros are shared
game_config::config_cache_transaction main_transaction;
cache_.get_config(game_config::path +"/data", game_config_);
main_transaction.lock();
/* Put the gfx rules aside so that we can prepend the add-on
rules to them. */
config core_terrain_rules;
core_terrain_rules.splice_children(game_config_, "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_dirs;
// Scan for standalone files
std::vector<std::string> user_files;
// The addons that we'll actually load
std::vector<std::string> addons_to_load;
get_files_in_dir(user_campaign_dir,&user_files,&user_dirs,ENTIRE_FILE_PATH);
std::stringstream user_error_log;
// Append the $user_campaign_dir/*.cfg files to addons_to_load.
for(std::vector<std::string>::const_iterator uc = user_files.begin(); uc != user_files.end(); ++uc) {
const std::string file = *uc;
const int size_minus_extension = file.size() - 4;
if(file.substr(size_minus_extension, file.size()) == ".cfg") {
bool ok = true;
// Allowing it if the dir doesn't exist, for the single-file add-on.
if(file_exists(file.substr(0, size_minus_extension))) {
// Unfortunately, we create the dir plus _info.cfg ourselves on download
std::vector<std::string> dirs, files;
get_files_in_dir(file.substr(0, size_minus_extension), &files, &dirs);
if(dirs.size() > 0)
ok = false;
if(files.size() > 1)
ok = false;
if(files.size() == 1 && files[0] != "_info.cfg")
ok = false;
}
if(!ok) {
const int userdata_loc = file.find("data/add-ons") + 5;
ERR_CONFIG << "error reading usermade add-on '" << file << "'\n";
error_addons.push_back(file);
user_error_log << "The format '~" << file.substr(userdata_loc) << "' is only for single-file add-ons, use '~" << file.substr(userdata_loc, size_minus_extension - userdata_loc) << "/_main.cfg' instead.\n";
} else
addons_to_load.push_back(file);
}
}
// Append the $user_campaign_dir/*/_main.cfg files to addons_to_load.
for(std::vector<std::string>::const_iterator uc = user_dirs.begin(); uc != user_dirs.end(); ++uc){
const std::string main_cfg = *uc + "/_main.cfg";
if (file_exists(main_cfg))
addons_to_load.push_back(main_cfg);
}
// Load the addons
for(std::vector<std::string>::const_iterator uc = addons_to_load.begin(); uc != addons_to_load.end(); ++uc) {
const std::string toplevel = *uc;
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' << user_error_log.str();
gui2::show_error_message(disp().video(),msg.str());
}
// Extract the Lua scripts at toplevel.
extract_preload_scripts(game_config_);
game_config_.clear_children("lua");
config colorsys_info;
colorsys_info.splice_children(game_config_, "color_range");
colorsys_info.splice_children(game_config_, "color_palette");
game_config_.merge_children("units");
game_config_.splice_children(core_terrain_rules, "terrain_graphics");
config& hashes = game_config_.add_child("multiplayer_hashes");
BOOST_FOREACH(const config &ch, game_config_.child_range("multiplayer")) {
hashes[ch["id"]] = ch.hash();
}
game_config::add_color_info(colorsys_info);
set_unit_data();
terrain_builder::set_terrain_rules_cfg(game_config());
::init_strings(game_config());
theme::set_known_themes(&game_config());
} catch(game::error& e) {
ERR_CONFIG << "Error loading game configuration files\n";
gui2::show_error_message(disp().video(), _("Error loading game configuration files: '") +
e.message + _("' (The game will now exit)"));
throw;
}
}
void game_controller::launch_game(RELOAD_GAME_DATA reload)
{
loadscreen::global_loadscreen_manager loadscreen_manager(disp().video());
loadscreen::start_stage("load data");
if(reload == RELOAD_DATA) {
game_config::scoped_preproc_define campaign_define(state_.classification().campaign_define, state_.classification().campaign_define.empty() == false);
resources::config_manager->add_define(state_.classification().campaign_define, state_.classification().campaign_define.empty() == false);
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_.classification().campaign_xtra_defines.begin(); i != state_.classification().campaign_xtra_defines.end(); ++i) {
define_ptr newdefine(new game_config::scoped_preproc_define(*i));
extra_defines.push_back(newdefine);
for(std::vector<std::string>::const_iterator i = state_.classification().campaign_xtra_defines.begin();
i != state_.classification().campaign_xtra_defines.end(); ++i) {
resources::config_manager->add_define(*i);
}
try {
load_game_cfg();
resources::config_manager->load_game_cfg();
} catch(config::error&) {
cache_.clear_defines();
load_game_cfg();
resources::config_manager->cache().clear_defines();
resources::config_manager->load_game_cfg();
return;
}
}
@ -1126,9 +910,9 @@ void game_controller::play_replay()
editor::EXIT_STATUS game_controller::start_editor(const std::string& filename)
{
while(true){
cache_.clear_defines();
cache_.add_define("EDITOR");
load_game_cfg();
resources::config_manager->cache().clear_defines();
resources::config_manager->add_define("EDITOR");
resources::config_manager->load_game_cfg();
const binary_paths_manager bin_paths_manager(game_config());
::init_textdomains(game_config());

View file

@ -17,13 +17,12 @@
#include "game_controller_abstract.hpp"
#include "commandline_options.hpp"
#include "config_cache.hpp"
#include "filesystem.hpp"
#include "gamestatus.hpp"
#include "game_config.hpp"
#include "game_config_manager.hpp"
#include "game_display.hpp"
#include "game_preferences.hpp"
#include "hotkeys.hpp"
#include "resources.hpp"
#include "sound.hpp"
#include "thread.hpp"
@ -77,15 +76,13 @@ public:
editor::EXIT_STATUS start_editor() { return start_editor(""); }
void start_wesnothd();
const config& game_config() const { return game_config_; }
const config& game_config() const { return resources::config_manager->game_config(); }
private:
game_controller(const game_controller&);
void operator=(const game_controller&);
bool init_config(const bool force);
void load_game_cfg(const bool force=false);
void set_unit_data();
void mark_completed_campaigns(std::vector<config>& campaigns);
@ -102,15 +99,11 @@ private:
const hotkey::manager hotkey_manager_;
sound::music_thinker music_thinker_;
resize_monitor resize_monitor_;
binary_paths_manager paths_manager_;
std::string test_scenario_;
std::string screenshot_map_, screenshot_filename_;
config game_config_;
preproc_map old_defines_map_;
/// Stateful class taking over scenario-switching capabilities from the current game_controller and playsingle_controller. Currently only available when --new-syntax command line option is enabled.
game_state state_;
@ -119,8 +112,6 @@ private:
jump_to_campaign_info jump_to_campaign_;
bool jump_to_editor_;
game_config::config_cache& cache_;
};
#endif

View file

@ -17,6 +17,7 @@
namespace resources
{
game_config_manager *config_manager = NULL;
play_controller *controller = NULL;
game_data *gamedata = NULL;
gamemap *game_map = NULL;

View file

@ -17,6 +17,7 @@
#include <vector>
class game_config_manager;
class game_display;
class gamemap;
class game_state;
@ -38,6 +39,7 @@ namespace wb { class manager; } //whiteboard manager
namespace resources
{
extern game_config_manager *config_manager;
extern play_controller *controller;
extern game_data *gamedata;
extern gamemap *game_map;