Navigation Menu

Skip to content

Commit

Permalink
libcommon|GameStateWriter|GameStateReader: Continued cleaning up save…
Browse files Browse the repository at this point in the history
…game file management
  • Loading branch information
danij-deng committed Feb 17, 2014
1 parent d454792 commit 66e23fc
Show file tree
Hide file tree
Showing 9 changed files with 92 additions and 56 deletions.
1 change: 1 addition & 0 deletions doomsday/libdeng1/src/writer.c
Expand Up @@ -142,6 +142,7 @@ Writer *Writer_NewWithCallbacks(Writer_Callback_WriteInt8 writeInt8,

void Writer_Delete(Writer *writer)
{
if(!writer) return;
if(writer->isDynamic)
{
// The buffer was allocated by us.
Expand Down
9 changes: 5 additions & 4 deletions doomsday/plugins/common/include/saveslots.h
Expand Up @@ -148,14 +148,16 @@ class SaveSlots
void copySlot(int sourceSlot, int destSlot);

/**
* Compose the (possibly relative) file path to the game state associated with save @a slot.
* Compose the (possibly relative) file path to the map state associated with save @a slot.
*
* @param slot Slot to compose the identifier of.
* @param map If @c >= 0 include this logical map index in the composed path.
* @param map Logical map index.
*
* @return The composed path if reachable (else a zero-length string).
*/
AutoStr *composeSavePathForSlot(int slot, int map = -1) const;
AutoStr *composeMapSavePathForSlot(int slot, uint map) const;

AutoStr *composeSavePathForSlot(int slot) const;

/**
* Register the console commands and variables of this module.
Expand Down Expand Up @@ -194,7 +196,6 @@ SaveInfo *SaveSlots_SaveInfo(SaveSlots *sslots, int slot);
void SaveSlots_ReplaceSaveInfo(SaveSlots *sslots, int slot, SaveInfo *newInfo);
void SaveSlots_ClearSlot(SaveSlots *sslots, int slot);
void SaveSlots_CopySlot(SaveSlots *sslots, int sourceSlot, int destSlot);
AutoStr *SaveSlots_ComposeSavePathForSlot(SaveSlots const *sslots, int slot, int map);

void SaveSlots_ConsoleRegister();

Expand Down
38 changes: 16 additions & 22 deletions doomsday/plugins/common/src/gamestatereader.cpp
Expand Up @@ -33,7 +33,7 @@

DENG2_PIMPL(GameStateReader)
{
SaveInfo *saveInfo; ///< Info for the save state to be read.
SaveInfo *saveInfo; ///< Info for the save state to be read. Not owned.
Reader *reader;
dd_bool loaded[MAXPLAYERS];
dd_bool infile[MAXPLAYERS];
Expand All @@ -47,6 +47,11 @@ DENG2_PIMPL(GameStateReader)
de::zap(infile);
}

~Instance()
{
Reader_Delete(reader);
}

/// Assumes the reader is currently positioned at the start of the stream.
void seekToGameState()
{
Expand Down Expand Up @@ -105,10 +110,9 @@ DENG2_PIMPL(GameStateReader)
#if __JHEXEN__ // The map state is actually read from a separate file.
// Close the game state file.
Z_Free(saveBuffer);
SV_CloseFile();

// Open the map state file.
AutoStr *path = saveSlots->composeSavePathForSlot(BASE_SLOT, gameMap + 1);
AutoStr *path = saveSlots->composeMapSavePathForSlot(BASE_SLOT, gameMap);
if(!SV_OpenMapSaveFile(path))
{
throw FileAccessError("GameStateReader", "Failed opening \"" + de::String(Str_Text(path)) + "\"");
Expand All @@ -120,9 +124,11 @@ DENG2_PIMPL(GameStateReader)
readConsistencyBytes();
#if __JHEXEN__
Z_Free(saveBuffer);
SV_ClearTargetPlayers();
#else
SV_CloseFile();
#endif
#if __JHEXEN__
SV_ClearTargetPlayers();
#endif
}

Expand Down Expand Up @@ -208,17 +214,19 @@ DENG2_PIMPL(GameStateReader)
{
for(int i = 0; i < MAXPLAYERS; ++i)
{
dd_bool notLoaded = false;
bool notLoaded = false;

#if __JHEXEN__
if(players[i].plr->inGame)
{
// Try to find a saved player that corresponds this one.
uint k;
int k;
for(k = 0; k < MAXPLAYERS; ++k)
{
if(saveToRealPlayerNum[k] == i)
{
break;
}
}
if(k < MAXPLAYERS)
continue; // Found; don't bother this player.
Expand Down Expand Up @@ -269,29 +277,15 @@ GameStateReader::~GameStateReader()

bool GameStateReader::recognize(SaveInfo &info, Str const *path) // static
{
DENG_ASSERT(path != 0);

if(!SV_ExistingFile(path)) return false;

#if __JHEXEN__
/// @todo Do not buffer the whole file.
byte *readBuffer;
size_t fileSize = M_ReadFile(Str_Text(path), (char **) &readBuffer);
if(!fileSize) return false;

// Set the save pointer.
SV_HxSavePtr()->b = readBuffer;
SV_HxSetSaveEndPtr(readBuffer + fileSize);
#else
if(!SV_OpenFile(path, "rp")) return false;
#endif
if(!SV_OpenGameSaveFile(path, false/*for reading*/)) return false;

Reader *reader = SV_NewReader();
info.read(reader);
Reader_Delete(reader);

#if __JHEXEN__
Z_Free(readBuffer);
Z_Free(saveBuffer);
#else
SV_CloseFile();
#endif
Expand Down
10 changes: 8 additions & 2 deletions doomsday/plugins/common/src/gamestatewriter.cpp
Expand Up @@ -30,7 +30,7 @@

DENG2_PIMPL(GameStateWriter)
{
SaveInfo *saveInfo; ///< Info for the save state to be written.
SaveInfo *saveInfo; ///< Info for the save state to be written. Not owned.
ThingArchive *thingArchive;
Writer *writer;

Expand All @@ -41,6 +41,12 @@ DENG2_PIMPL(GameStateWriter)
, writer(0)
{}

~Instance()
{
Writer_Delete(writer);
delete thingArchive;
}

void beginSegment(int segId)
{
#if __JHEXEN__
Expand Down Expand Up @@ -82,7 +88,7 @@ DENG2_PIMPL(GameStateWriter)
SV_CloseFile();

// Open the map state file.
SV_OpenFile(saveSlots->composeSavePathForSlot(BASE_SLOT, gameMap + 1), "wp");
SV_OpenFile(saveSlots->composeMapSavePathForSlot(BASE_SLOT, gameMap), "wp");
#endif

MapStateWriter(*thingArchive).write(writer);
Expand Down
20 changes: 19 additions & 1 deletion doomsday/plugins/common/src/mapstatereader.cpp
Expand Up @@ -54,7 +54,7 @@ using namespace internal;

DENG2_PIMPL(MapStateReader)
{
Reader *reader;
Reader *reader; // Not owned.
int saveVersion;
int mapVersion;
bool formatHasMapVersionNumber;
Expand All @@ -77,6 +77,13 @@ DENG2_PIMPL(MapStateReader)
, sideArchive(0)
{}

~Instance()
{
delete thingArchive;
delete sideArchive;
MaterialArchive_Delete(materialArchive);
}

void beginSegment(int segId)
{
#if __JHEXEN__
Expand Down Expand Up @@ -364,7 +371,9 @@ DENG2_PIMPL(MapStateReader)
#if __JHEXEN__
if(reachedSpecialsBlock)
#endif
{
tClass = Reader_ReadByte(reader);
}

#if __JHEXEN__
if(mapVersion < 4)
Expand All @@ -376,7 +385,9 @@ DENG2_PIMPL(MapStateReader)
// are differrent, so we need to manipulate the thinker
// class identifier value.
if(tClass != TC_END)
{
tClass += 2;
}
}
else
{
Expand All @@ -400,9 +411,13 @@ DENG2_PIMPL(MapStateReader)
// the end of the specials data so we need to manipulate
// the thinker class identifier value.
if(tClass == PRE_VER5_END_SPECIALS)
{
tClass = TC_END;
}
else
{
tClass += 3;
}
}
else if(tClass == TC_END)
{
Expand All @@ -412,6 +427,7 @@ DENG2_PIMPL(MapStateReader)
}
}
#endif

if(tClass == TC_END)
break; // End of the list.

Expand Down Expand Up @@ -445,7 +461,9 @@ DENG2_PIMPL(MapStateReader)

#if __JHEXEN__
if(tClass == TC_MOBJ)
{
i++;
}
#endif
}

Expand Down
13 changes: 11 additions & 2 deletions doomsday/plugins/common/src/mapstatewriter.cpp
Expand Up @@ -43,9 +43,9 @@ using namespace internal;

DENG2_PIMPL(MapStateWriter)
{
ThingArchive *thingArchive;
ThingArchive *thingArchive; // Not owned.
MaterialArchive *materialArchive;
Writer *writer;
Writer *writer; // Not owned.

Instance(Public *i)
: Base(i)
Expand All @@ -54,6 +54,11 @@ DENG2_PIMPL(MapStateWriter)
, writer(0)
{}

~Instance()
{
MaterialArchive_Delete(materialArchive);
}

void beginSegment(int segId)
{
#if __JHEXEN__
Expand Down Expand Up @@ -139,12 +144,16 @@ DENG2_PIMPL(MapStateWriter)
if(p.excludePlayers)
{
if(th->function == (thinkfunc_t) P_MobjThinker && ((mobj_t *) th)->player)
{
return false;
}
}

// Only the server saves this class of thinker?
if((thInfo->flags & TSF_SERVERONLY) && IS_CLIENT)
{
return false;
}

// Write the header block for this thinker.
Writer_WriteByte(p.msw->writer(), thInfo->thinkclass); // Thinker type byte.
Expand Down
15 changes: 9 additions & 6 deletions doomsday/plugins/common/src/p_saveg.cpp
Expand Up @@ -88,10 +88,13 @@ dd_bool SV_OpenGameSaveFile(Str const *path, dd_bool write)
#if __JHEXEN__
if(!write)
{
bool result = M_ReadFile(Str_Text(path), (char **)&saveBuffer) > 0;
// Set the save pointer.
size_t bufferSize = M_ReadFile(Str_Text(path), (char **)&saveBuffer);
if(!bufferSize) return false;

SV_HxSavePtr()->b = saveBuffer;
return result;
SV_HxSetSaveEndPtr(saveBuffer + bufferSize);

return true;
}
else
#endif
Expand Down Expand Up @@ -122,7 +125,7 @@ dd_bool SV_OpenMapSaveFile(Str const *path)
dd_bool SV_HxHaveMapStateForSlot(int slot, uint map)
{
DENG_ASSERT(inited);
AutoStr *path = saveSlots->composeSavePathForSlot(slot, (int)map + 1);
AutoStr *path = saveSlots->composeMapSavePathForSlot(slot, map);
if(path && !Str_IsEmpty(path))
{
return SV_ExistingFile(path);
Expand Down Expand Up @@ -1144,7 +1147,7 @@ void SV_LoadGameClient(uint sessionId)
#if __JHEXEN__
void SV_HxSaveHubMap()
{
SV_OpenFile(saveSlots->composeSavePathForSlot(BASE_SLOT, gameMap + 1), "wp");
SV_OpenFile(saveSlots->composeMapSavePathForSlot(BASE_SLOT, gameMap), "wp");

// Set the mobj archive numbers
ThingArchive thingArchive;
Expand Down Expand Up @@ -1175,7 +1178,7 @@ void SV_HxLoadHubMap()
// Been here before, load the previous map state.
try
{
AutoStr *path = saveSlots->composeSavePathForSlot(BASE_SLOT, gameMap + 1);
AutoStr *path = saveSlots->composeMapSavePathForSlot(BASE_SLOT, gameMap);
if(!SV_OpenMapSaveFile(path))
{
throw de::Error("SV_HxLoadHubMap", "Failed opening \"" + de::String(Str_Text(path)) + "\" for read");
Expand Down
2 changes: 1 addition & 1 deletion doomsday/plugins/common/src/saveinfo.cpp
Expand Up @@ -291,7 +291,7 @@ void SaveInfo::updateFromFile(Str const *path)
// Is this a recognized game state?
if(!SV_RecognizeGameState(*this, path))
{
// Clear the info for this slot.
// Clear the info.
setDescription(0);
setSessionId(0);
return;
Expand Down

0 comments on commit 66e23fc

Please sign in to comment.