config/cache: Ensure built-in symbols like WESNOTH_VERSION are always defined

Half-fix for issue #1634 and issue #1924.

The issue that remains to be solved is that on subsequent sessions after
a campaign has failed to load, it is possible for the game to generate a
cache entry for it that only contains the main menu WML for it.
Apparently the config cache transactions mechanism causes the game to
try to generate a cache entry with the wrong defines (a define set that
doesn't include the campaign's symbol, for instance) instead of the ones
that are actually needed and used to match the cache entry's filename
via checksumming. As a result, on subsequent sessions the failed
campaign is aborted with "failed to load the scenario" instead of
displaying the real WML error again (since the error is not hit again if
it depends on the campaign's symbol being defined).

In the meantime, this at least removes the red herring error and makes
the underlying issue a bit more visible. It's a very crude hack but it
does the job.
This commit is contained in:
Iris Morelle 2018-06-18 18:28:12 -04:00
parent 9d95aa776c
commit 0c2298d8c2
2 changed files with 24 additions and 7 deletions

View file

@ -50,6 +50,9 @@
### User interface
* Improved the layout of the Statistics dialog.
* Allow changing dropdown menu selections with the scrollwheel (FR #3251).
### WML engine
* Fixed errors about WESNOTH_VERSION not being defined when trying to load
add-ons that have preprocessor errors (issues #1924, #1634).
### Miscellaneous and bug fixes
* Added an advanced preference to enable experimental PRNG combat.
* Fixed MP admins being unable to observe private games.

View file

@ -36,6 +36,20 @@ static lg::log_domain log_cache("cache");
namespace game_config
{
namespace
{
void add_builtin_defines(preproc_map& target)
{
#ifdef __APPLE__
target["APPLE"] = preproc_define();
#endif
target["WESNOTH_VERSION"] = preproc_define(game_config::wesnoth_version.str());
}
}
config_cache& config_cache::instance()
{
static config_cache cache;
@ -68,11 +82,7 @@ void config_cache::clear_defines()
// Set-up default defines map.
//
#ifdef __APPLE__
defines_map_["APPLE"] = preproc_define();
#endif
defines_map_["WESNOTH_VERSION"] = preproc_define(game_config::wesnoth_version.str());
add_builtin_defines(defines_map_);
}
void config_cache::get_config(const std::string& file_path, config& cfg)
@ -113,7 +123,11 @@ void config_cache::read_file(const std::string& file_path, config& cfg)
preproc_map& config_cache::make_copy_map()
{
return config_cache_transaction::instance().get_active_map(defines_map_);
preproc_map& res = config_cache_transaction::instance().get_active_map(defines_map_);
// HACK: copy_map doesn't have built-in defines in some cases (issue #1924)
// or they may be out of date, so brute-force them in.
add_builtin_defines(res);
return res;
}
void config_cache::add_defines_map_diff(preproc_map& defines_map)
@ -428,7 +442,7 @@ preproc_map& config_cache_transaction::get_active_map(const preproc_map& defines
if(get_state() == NEW) {
state_ = ACTIVE;
}
}
}
return active_map_;
}