Skip to content

Commit

Permalink
Fixed|libcommon: Error at shutdown attempting to query cvars that no …
Browse files Browse the repository at this point in the history
…longer exist

The games' SaveSlots are presently allocated as a global variable,
meaning that destruction will occur long after the engine's cvar
database is cleared when the game is unloaded. Therefore attempting
to modify the last-used and quick-slot tracking cvars from SaveSlots
destructor is both wrong and unnecessary.
  • Loading branch information
danij-deng committed Feb 12, 2014
1 parent d8dfdcd commit a1db720
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 27 deletions.
2 changes: 1 addition & 1 deletion doomsday/plugins/common/include/p_saveg.h
Expand Up @@ -29,7 +29,7 @@
DENG_EXTERN_C int thingArchiveVersion;
DENG_EXTERN_C uint thingArchiveSize;
DENG_EXTERN_C int saveToRealPlayerNum[MAXPLAYERS];
DENG_EXTERN_C SaveSlots saveSlots;
DENG_EXTERN_C SaveSlots *saveSlots;

#ifdef __cplusplus
extern "C" {
Expand Down
31 changes: 16 additions & 15 deletions doomsday/plugins/common/src/p_saveg.cpp
Expand Up @@ -64,7 +64,8 @@ struct playerheader_t

static bool inited = false;

SaveSlots saveSlots(NUMSAVESLOTS);
SaveSlots ss(NUMSAVESLOTS);
SaveSlots *saveSlots = &ss;

static SaveInfo const *curInfo;

Expand Down Expand Up @@ -216,7 +217,7 @@ dd_bool SV_RecognizeGameState(Str const *path, SaveInfo *info)
dd_bool SV_HxHaveMapStateForSlot(int slot, uint map)
{
DENG_ASSERT(inited);
AutoStr *path = saveSlots.composeSavePathForSlot(slot, (int)map + 1);
AutoStr *path = saveSlots->composeSavePathForSlot(slot, (int)map + 1);
if(path && !Str_IsEmpty(path))
{
return SV_ExistingFile(path);
Expand Down Expand Up @@ -1735,7 +1736,7 @@ void SV_Shutdown()
if(!inited) return;

SV_ShutdownIO();
saveSlots.clearAllSaveInfo();
saveSlots->clearAllSaveInfo();

inited = false;
}
Expand Down Expand Up @@ -1842,7 +1843,7 @@ static void loadNativeState(Str const *path, SaveInfo *info)

// Load the current map state.
#if __JHEXEN__
openMapSaveFile(saveSlots.composeSavePathForSlot(BASE_SLOT, gameMap + 1));
openMapSaveFile(saveSlots->composeSavePathForSlot(BASE_SLOT, gameMap + 1));
#endif

MapStateReader(info->version()).read(reader);
Expand Down Expand Up @@ -1972,14 +1973,14 @@ dd_bool SV_LoadGame(int slot)
int const logicalSlot = slot;
#endif

if(!saveSlots.isValidSlot(slot))
if(!saveSlots->isValidSlot(slot))
{
return false;
}

App_Log(DE2_RES_VERBOSE, "Attempting load of save slot #%i...", slot);

AutoStr *path = saveSlots.composeSavePathForSlot(slot);
AutoStr *path = saveSlots->composeSavePathForSlot(slot);
if(Str_IsEmpty(path))
{
App_Log(DE2_RES_ERROR, "Game not loaded: path \"%s\" is unreachable", SV_SavePath());
Expand All @@ -1992,13 +1993,13 @@ dd_bool SV_LoadGame(int slot)
/// @todo Does any caller ever attempt to load the base slot?? (Doesn't seem logical)
if(slot != BASE_SLOT)
{
saveSlots.copySlot(slot, BASE_SLOT);
saveSlots->copySlot(slot, BASE_SLOT);
}
#endif

try
{
SaveInfo &info = saveSlots.saveInfo(logicalSlot);
SaveInfo &info = saveSlots->saveInfo(logicalSlot);

loadGameState(path, info);

Expand Down Expand Up @@ -2211,7 +2212,7 @@ static void saveGameState(Str const *path, SaveInfo *saveInfo)
*/
#if __JHEXEN__
// ...map state is actually written to a separate file.
SV_OpenFile(saveSlots.composeSavePathForSlot(BASE_SLOT, gameMap + 1), "wp");
SV_OpenFile(saveSlots->composeSavePathForSlot(BASE_SLOT, gameMap + 1), "wp");
#endif

MapStateWriter(thingArchiveExcludePlayers).write(writer);
Expand All @@ -2236,7 +2237,7 @@ dd_bool SV_SaveGame(int slot, char const *description)
int const logicalSlot = slot;
#endif

if(!saveSlots.isValidSlot(slot))
if(!saveSlots->isValidSlot(slot))
{
DENG_ASSERT(!"Invalid slot specified");
return false;
Expand All @@ -2247,7 +2248,7 @@ dd_bool SV_SaveGame(int slot, char const *description)
return false;
}

AutoStr *path = saveSlots.composeSavePathForSlot(logicalSlot);
AutoStr *path = saveSlots->composeSavePathForSlot(logicalSlot);
if(Str_IsEmpty(path))
{
App_Log(DE2_RES_WARNING, "Cannot save game: path \"%s\" is unreachable", SV_SavePath());
Expand All @@ -2261,11 +2262,11 @@ dd_bool SV_SaveGame(int slot, char const *description)
saveGameState(path, info);

// Swap the save info.
saveSlots.replaceSaveInfo(logicalSlot, info);
saveSlots->replaceSaveInfo(logicalSlot, info);

#if __JHEXEN__
// Copy base slot to destination slot.
saveSlots.copySlot(logicalSlot, slot);
saveSlots->copySlot(logicalSlot, slot);
#endif

// Make note of the last used save slot.
Expand All @@ -2289,7 +2290,7 @@ void SV_HxSaveHubMap()
{
playerHeaderOK = false; // Uninitialized.

SV_OpenFile(saveSlots.composeSavePathForSlot(BASE_SLOT, gameMap + 1), "wp");
SV_OpenFile(saveSlots->composeSavePathForSlot(BASE_SLOT, gameMap + 1), "wp");

// Set the mobj archive numbers
initThingArchiveForSave(true /*exclude players*/);
Expand Down Expand Up @@ -2321,7 +2322,7 @@ void SV_HxLoadHubMap()
// Been here before, load the previous map state.
try
{
openMapSaveFile(saveSlots.composeSavePathForSlot(BASE_SLOT, gameMap + 1));
openMapSaveFile(saveSlots->composeSavePathForSlot(BASE_SLOT, gameMap + 1));

MapStateReader(info->version()).read(reader);

Expand Down
24 changes: 13 additions & 11 deletions doomsday/plugins/common/src/saveslots.cpp
Expand Up @@ -52,7 +52,7 @@ DENG2_PIMPL(SaveSlots)

~Instance()
{
self.clearAllSaveInfo();
clearInfos();
}

/// Determines whether to announce when the specified @a slot is cleared.
Expand All @@ -68,6 +68,17 @@ DENG2_PIMPL(SaveSlots)
#endif
}

void clearInfos()
{
DENG2_FOR_EACH(Infos, i, infos) { delete *i; }
infos.clear();

delete autoInfo; autoInfo = 0;
#if __JHEXEN__
delete baseInfo; baseInfo = 0;
#endif
}

SaveInfo **infoAdrForSlot(int slot)
{
buildInfosIfNeeded();
Expand Down Expand Up @@ -149,16 +160,7 @@ SaveSlots::SaveSlots(int slotCount) : d(new Instance(this, slotCount))

void SaveSlots::clearAllSaveInfo()
{
DENG2_FOR_EACH(Instance::Infos, i, d->infos)
{
delete *i;
}
d->infos.clear();

delete d->autoInfo; d->autoInfo = 0;
#if __JHEXEN__
delete d->baseInfo; d->baseInfo = 0;
#endif
d->clearInfos();

// Reset last-used and quick-save slot tracking.
Con_SetInteger2("game-save-last-slot", -1, SVF_WRITE_OVERRIDE);
Expand Down

0 comments on commit a1db720

Please sign in to comment.