From 42daab712970937cb0b6b86d36f2c9779d91a73d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Kera=CC=88nen?= Date: Sun, 21 Jan 2018 22:52:22 +0200 Subject: [PATCH] libcommon|Fixed: Initialization of global GameRules instances Moved GameRules instances from the global scope to getter functions, to avoid initialization order problems where static Strings needed by GameRules aren't available early enough. --- .../apps/plugins/common/include/g_common.h | 8 ++-- doomsday/apps/plugins/common/src/common.cpp | 13 +++++++ .../apps/plugins/common/src/game/g_game.cpp | 39 +++++++++---------- .../plugins/common/src/game/gamerules.cpp | 16 ++++---- doomsday/apps/plugins/common/src/hu_menu.cpp | 2 +- 5 files changed, 43 insertions(+), 35 deletions(-) diff --git a/doomsday/apps/plugins/common/include/g_common.h b/doomsday/apps/plugins/common/include/g_common.h index 34c46e5ca0..63cbbd7e1d 100644 --- a/doomsday/apps/plugins/common/include/g_common.h +++ b/doomsday/apps/plugins/common/include/g_common.h @@ -31,13 +31,13 @@ #if __cplusplus class SaveSlots; -extern GameRules defaultGameRules; +GameRules &gfw_DefaultGameRules(); -#define gfw_DefaultRule(name) (defaultGameRules.values.name) -#define gfw_SetDefaultRule(name, value) GameRules_Set(defaultGameRules, name, value) +#define gfw_DefaultRule(name) (gfw_DefaultGameRules().values.name) +#define gfw_SetDefaultRule(name, value) GameRules_Set(gfw_DefaultGameRules(), name, value) extern de::Uri nextMapUri; -extern uint nextMapEntryPoint; +extern uint nextMapEntryPoint; /** * Schedule a new game session (deferred). diff --git a/doomsday/apps/plugins/common/src/common.cpp b/doomsday/apps/plugins/common/src/common.cpp index daea37b0da..576d2ad383 100644 --- a/doomsday/apps/plugins/common/src/common.cpp +++ b/doomsday/apps/plugins/common/src/common.cpp @@ -82,6 +82,19 @@ void *Common_GetGameAPI(char const *name) return nullptr; } +GameRules &gfw_DefaultGameRules() +{ + static GameRules defaultGameRules; + return defaultGameRules; +} + +void GameRules_UpdateDefaultsFromCVars() +{ +#if !__JHEXEN__ + gfw_SetDefaultRule(fast, cfg.common.defaultRuleFastMonsters); +#endif +} + #ifdef __JDOOM__ void fastMonstersChanged() { diff --git a/doomsday/apps/plugins/common/src/game/g_game.cpp b/doomsday/apps/plugins/common/src/game/g_game.cpp index c802ec8186..443c20ee63 100644 --- a/doomsday/apps/plugins/common/src/game/g_game.cpp +++ b/doomsday/apps/plugins/common/src/game/g_game.cpp @@ -82,8 +82,6 @@ using namespace common; void R_LoadVectorGraphics(); int Hook_DemoStop(int hookType, int val, void *parm); -GameRules defaultGameRules; - game_config_t cfg; // The global cfg. #if __JDOOM__ || __JDOOM64__ @@ -122,13 +120,17 @@ static SaveSlots *sslots; static gameaction_t gameAction; // Game action parameters: -static GameRules gaNewSessionRules; -static String gaNewSessionEpisodeId; +static GameRules &G_NewSessionRules() +{ + static GameRules gaNewSessionRules; + return gaNewSessionRules; +} +static String gaNewSessionEpisodeId; static de::Uri gaNewSessionMapUri; -static uint gaNewSessionMapEntrance; +static uint gaNewSessionMapEntrance; static String gaSaveSessionSlot; -static bool gaSaveSessionGenerateDescription = true; +static bool gaSaveSessionGenerateDescription = true; static String gaSaveSessionUserDescription; static String gaLoadSessionSlot; @@ -147,10 +149,10 @@ void G_SetGameAction(gameaction_t newAction) } } -void G_SetGameActionNewSession(GameRules const &rules, String episodeId, - de::Uri const &mapUri, uint mapEntrance) +void G_SetGameActionNewSession(GameRules const &rules, String episodeId, de::Uri const &mapUri, + uint mapEntrance) { - ::gaNewSessionRules = rules; // make a copy. + G_NewSessionRules() = rules; ::gaNewSessionEpisodeId = episodeId; ::gaNewSessionMapUri = mapUri; ::gaNewSessionMapEntrance = mapEntrance; @@ -311,7 +313,7 @@ void G_CommonPreInit() ::quitInProgress = false; // Apply the default game rules. - gfw_Session()->applyNewRules(defaultGameRules = GameRules()); + gfw_Session()->applyNewRules(gfw_DefaultGameRules() = GameRules()); // Register hooks. Plug_AddHook(HOOK_DEMO_STOP, Hook_DemoStop); @@ -905,7 +907,7 @@ void G_AutoStartOrBeginTitleLoop() // Don't brief when autostarting. ::briefDisabled = true; - G_SetGameActionNewSession(defaultGameRules, startEpisodeId, startMapUri); + G_SetGameActionNewSession(gfw_DefaultGameRules(), startEpisodeId, startMapUri); } else { @@ -1355,8 +1357,10 @@ static void runGameAction() { case GA_NEWSESSION: gfw_Session()->end(); - gfw_Session()->begin(::gaNewSessionRules, ::gaNewSessionEpisodeId, - ::gaNewSessionMapUri, ::gaNewSessionMapEntrance); + gfw_Session()->begin(G_NewSessionRules(), + ::gaNewSessionEpisodeId, + ::gaNewSessionMapUri, + ::gaNewSessionMapEntrance); break; case GA_LOADSESSION: @@ -1891,13 +1895,6 @@ void G_QueueBody(mobj_t *mo) } #endif -void GameRules_UpdateDefaultsFromCVars() -{ -#if !__JHEXEN__ - gfw_SetDefaultRule(fast, cfg.common.defaultRuleFastMonsters); -#endif -} - /** * Lookup the debriefing Finale for the current episode and map (if any). */ @@ -2820,7 +2817,7 @@ D_CMD(WarpMap) else { // If a session is already in progress then copy the rules from it. - GameRules rules = (gfw_Session()->hasBegun() ? gfw_Session()->rules() : defaultGameRules); + GameRules rules = (gfw_Session()->hasBegun() ? gfw_Session()->rules() : gfw_DefaultGameRules()); if (IS_DEDICATED) { // Why is this necessary to set here? Changing the rules in P_SetupMap() diff --git a/doomsday/apps/plugins/common/src/game/gamerules.cpp b/doomsday/apps/plugins/common/src/game/gamerules.cpp index cfc767fbcc..33c4514f75 100644 --- a/doomsday/apps/plugins/common/src/game/gamerules.cpp +++ b/doomsday/apps/plugins/common/src/game/gamerules.cpp @@ -35,17 +35,15 @@ String const GameRules::KEY_noMonsters = "noMonsters"; String const GameRules::KEY_respawnMonsters = "respawnMonsters"; String const GameRules::KEY_randomClasses = "randomClasses"; -static Record const builtInDefaults = - Record::withMembers(GameRules::KEY_skill, 2, // medium - GameRules::KEY_fast, false, - GameRules::KEY_deathmatch, 0, - GameRules::KEY_noMonsters, false, - GameRules::KEY_randomClasses, false, - GameRules::KEY_respawnMonsters, false); - DENG2_PIMPL_NOREF(GameRules) { - Record rules { builtInDefaults }; + Record rules { + Record::withMembers(GameRules::KEY_skill, 2, // medium + GameRules::KEY_fast, false, + GameRules::KEY_deathmatch, 0, + GameRules::KEY_noMonsters, false, + GameRules::KEY_randomClasses, false, + GameRules::KEY_respawnMonsters, false) }; Impl() {} diff --git a/doomsday/apps/plugins/common/src/hu_menu.cpp b/doomsday/apps/plugins/common/src/hu_menu.cpp index c20db58931..4dd14af8f1 100644 --- a/doomsday/apps/plugins/common/src/hu_menu.cpp +++ b/doomsday/apps/plugins/common/src/hu_menu.cpp @@ -3384,7 +3384,7 @@ static void Hu_MenuInitNewGame(bool confirmed) cfg.playerClass[CONSOLEPLAYER] = playerclass_t(mnPlrClass); #endif - GameRules newRules(defaultGameRules); + GameRules newRules{gfw_DefaultGameRules()}; GameRules_Set(newRules, skill, mnSkillmode); Record const &episodeDef = Defs().episodes.find("id", mnEpisode);