Skip to content

Commit

Permalink
Refactor|libcommon|SaveInfo: Extracted SessionMetadata from SaveInfo
Browse files Browse the repository at this point in the history
  • Loading branch information
danij-deng committed Feb 28, 2014
1 parent 2e5a0d9 commit a011e4e
Show file tree
Hide file tree
Showing 9 changed files with 348 additions and 421 deletions.
100 changes: 42 additions & 58 deletions doomsday/plugins/common/include/saveinfo.h
Expand Up @@ -25,6 +25,37 @@
#include <de/Observers>
#include <de/String>

/**
* Game session metadata (serialized to savegames).
* @ingroup libcommon
*/
struct SessionMetadata
{
#if !__JHEXEN__
// Info data about players present (or not) in the game session.
typedef byte Players[MAXPLAYERS];
#endif

de::String userDescription;
uint sessionId;
int magic;
int version;
de::String gameIdentityKey;
Uri *mapUri;
GameRuleset gameRules;
#if !__JHEXEN__
int mapTime;
Players players;
#endif

SessionMetadata();
SessionMetadata(SessionMetadata const &other);
~SessionMetadata();

void write(Writer *writer) const;
void read(Reader *reader);
};

/**
* Represents a saved game session state.
*
Expand All @@ -46,17 +77,12 @@ class SaveInfo
Unused
};

#if !__JHEXEN__
// Info data about players present (or not) in the game session.
typedef byte Players[MAXPLAYERS];
#endif

public:
SaveInfo(de::String const &fileName = "");
SaveInfo(SaveInfo const &other);

static SaveInfo *newWithCurrentSessionMetadata(de::String const &fileName = "",
de::String const &userDescription = "");
static SaveInfo *newWithCurrentSessionMeta(de::String const &fileName = "",
de::String const &userDescription = "");

SaveInfo &operator = (SaveInfo const &other);

Expand Down Expand Up @@ -129,73 +155,31 @@ class SaveInfo
* Update the metadata associated with the save using values derived from the current game
* session. Note that this does @em not affect the copy of this save on disk.
*/
void applyCurrentSessionMetadata();
void applyCurrentSessionMeta();

/**
* Returns the unique "identity key" of the game session.
* Provides read-only access to a copy of the deserialized game session metadata.
*/
de::String const &gameIdentityKey() const;
void setGameIdentityKey(de::String newGameIdentityKey);
SessionMetadata const &meta() const;

/**
* Returns the logical version of the serialized game session state.
* Deserializes the game session metadata using @a reader.
*/
int version() const;
void setVersion(int newVersion);
void readMeta(Reader *reader);

/**
* Returns the textual description of the saved game session provided by the user. The
* UserDescriptionChange audience is notified whenever the description changes.
*/
de::String const &userDescription() const;
// Metadata manipulation:
void setGameIdentityKey(de::String newGameIdentityKey);
void setVersion(int newVersion);
void setUserDescription(de::String newUserDescription);

/**
* @see G_GenerateSessionId()
*/
uint sessionId() const;
void setSessionId(uint newSessionId);

/**
* Returns the URI of the @em current map of the game session.
*/
Uri const *mapUri() const;
void setMapUri(Uri const *newMapUri);

#if !__JHEXEN__

/**
* Returns the expired time in tics since the @em current map of the game session began.
*/
int mapTime() const;
void setMapTime(int newMapTime);

/**
* Returns the player info data for the game session.
*/
Players const &players() const;
void setPlayers(Players const &newPlayers);

void setPlayers(SessionMetadata::Players const &newPlayers);
#endif // !__JHEXEN__

/**
* Returns the game ruleset for the game session.
*/
GameRuleset const &gameRules() const;
void setGameRules(GameRuleset const &newRules);

/**
* Serializes the game session header using @a writer.
*/
void write(Writer *writer) const;

/**
* Deserializes the game session header using @a reader.
*/
void read(Reader *reader);

public: /// @todo refactor away:
int magic() const;
void setMagic(int newMagic);
static SaveInfo *fromReader(Reader *reader);

Expand Down
16 changes: 8 additions & 8 deletions doomsday/plugins/common/src/g_game.cpp
Expand Up @@ -1408,7 +1408,7 @@ int G_DoLoadMap(loadmap_params_t *p)
throw de::Error("G_DoLoadMap", "Failed opening \"" + de::NativePath(path).pretty() + "\" for read");
}

MapStateReader(saveInfo.version()).read(reader);
MapStateReader(saveInfo.meta().version).read(reader);

SV_HxReleaseSaveBuffer();
}
Expand Down Expand Up @@ -2243,7 +2243,7 @@ void G_DoReborn(int plrNum)
{
// Compose the confirmation message.
SaveInfo &saveInfo = G_SaveSlots()[chosenSlot].saveInfo();
AutoStr *msg = Str_Appendf(AutoStr_NewStd(), REBORNLOAD_CONFIRM, saveInfo.userDescription().toUtf8().constData());
AutoStr *msg = Str_Appendf(AutoStr_NewStd(), REBORNLOAD_CONFIRM, saveInfo.meta().userDescription.toUtf8().constData());
S_LocalSound(SFX_REBORNLOAD_CONFIRM, NULL);
Hu_MsgStart(MSG_YESNO, Str_Text(msg), rebornLoadConfirmResponse, 0, new de::String(chosenSlot));
}
Expand Down Expand Up @@ -2906,18 +2906,18 @@ static int saveGameStateWorker(void *context)
if(userDescription.isEmpty())
{
SaveInfo &saveInfo = G_SaveSlots()[p.slotId].saveInfo();
if(!saveInfo.userDescription().isEmpty())
if(!saveInfo.meta().userDescription.isEmpty())
{
// Slot already in use; reuse the existing description.
userDescription = saveInfo.userDescription();
userDescription = saveInfo.meta().userDescription;
}
else if(gaSaveSessionGenerateDescription)
{
userDescription = Str_Text(G_GenerateUserSaveDescription());
}
}

SaveInfo *saveInfo = SaveInfo::newWithCurrentSessionMetadata(
SaveInfo *saveInfo = SaveInfo::newWithCurrentSessionMeta(
G_SaveSlots()[logicalSlot].fileName(),
userDescription);
try
Expand Down Expand Up @@ -4179,7 +4179,7 @@ D_CMD(LoadSession)

S_LocalSound(SFX_QUICKLOAD_PROMPT, NULL);
// Compose the confirmation message.
AutoStr *msg = Str_Appendf(AutoStr_NewStd(), QLPROMPT, sslot.saveInfo().userDescription().toUtf8().constData());
AutoStr *msg = Str_Appendf(AutoStr_NewStd(), QLPROMPT, sslot.saveInfo().meta().userDescription.toUtf8().constData());
Hu_MsgStart(MSG_YESNO, Str_Text(msg), loadSessionConfirmed, 0, new de::String(slotId));
return true;
}
Expand Down Expand Up @@ -4295,7 +4295,7 @@ D_CMD(SaveSession)
}

// Compose the confirmation message.
AutoStr *msg = Str_Appendf(AutoStr_NewStd(), QSPROMPT, sslot.saveInfo().userDescription().toUtf8().constData());
AutoStr *msg = Str_Appendf(AutoStr_NewStd(), QSPROMPT, sslot.saveInfo().meta().userDescription.toUtf8().constData());

savesessionconfirmed_params_t *parm = new savesessionconfirmed_params_t;
parm->slotId = slotId;
Expand Down Expand Up @@ -4391,7 +4391,7 @@ D_CMD(DeleteSavedSession)
else
{
// Compose the confirmation message.
AutoStr *msg = Str_Appendf(AutoStr_NewStd(), DELETESAVEGAME_CONFIRM, sslot.saveInfo().userDescription().toUtf8().constData());
AutoStr *msg = Str_Appendf(AutoStr_NewStd(), DELETESAVEGAME_CONFIRM, sslot.saveInfo().meta().userDescription.toUtf8().constData());
S_LocalSound(SFX_DELETESAVEGAME_CONFIRM, NULL);
Hu_MsgStart(MSG_YESNO, Str_Text(msg), deleteSavedSessionConfirmed, 0, new de::String(slotId));
}
Expand Down
32 changes: 16 additions & 16 deletions doomsday/plugins/common/src/gamestatereader.cpp
Expand Up @@ -99,11 +99,11 @@ DENG2_PIMPL(GameStateReader)
void readWorldACScriptData()
{
#if __JHEXEN__
if(saveInfo->version() >= 7)
if(saveInfo->meta().version >= 7)
{
beginSegment(ASEG_WORLDSCRIPTDATA);
}
Game_ACScriptInterpreter().readWorldScriptData(reader, saveInfo->version());
Game_ACScriptInterpreter().readWorldScriptData(reader, saveInfo->meta().version);
#endif
}

Expand All @@ -121,7 +121,7 @@ DENG2_PIMPL(GameStateReader)
}
#endif

MapStateReader(saveInfo->version(), thingArchiveSize).read(reader);
MapStateReader(saveInfo->meta().version, thingArchiveSize).read(reader);

readConsistencyBytes();
#if __JHEXEN__
Expand All @@ -141,15 +141,15 @@ DENG2_PIMPL(GameStateReader)
void readPlayers()
{
#if __JHEXEN__
if(saveInfo->version() >= 4)
if(saveInfo->meta().version >= 4)
#else
if(saveInfo->version() >= 5)
if(saveInfo->meta().version >= 5)
#endif
{
beginSegment(ASEG_PLAYER_HEADER);
}
playerheader_t plrHdr;
plrHdr.read(reader, saveInfo->version());
plrHdr.read(reader, saveInfo->meta().version);

// Setup the dummy.
ddplayer_t dummyDDPlayer;
Expand All @@ -160,7 +160,7 @@ DENG2_PIMPL(GameStateReader)
{
loaded[i] = 0;
#if !__JHEXEN__
infile[i] = saveInfo->players()[i];
infile[i] = saveInfo->meta().players[i];
#endif
}

Expand Down Expand Up @@ -285,7 +285,7 @@ bool GameStateReader::recognize(SaveInfo &info) // static
if(!SV_OpenFile(path, false/*for reading*/)) return false;

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

#if __JHEXEN__
Expand All @@ -295,23 +295,23 @@ bool GameStateReader::recognize(SaveInfo &info) // static
#endif

// Magic must match.
if(info.magic() != MY_SAVE_MAGIC && info.magic() != MY_CLIENT_SAVE_MAGIC)
if(info.meta().magic != MY_SAVE_MAGIC && info.meta().magic != MY_CLIENT_SAVE_MAGIC)
{
return false;
}

/*
* Check for unsupported versions.
*/
if(info.version() > MY_SAVE_VERSION) // Future version?
if(info.meta().version > MY_SAVE_VERSION) // Future version?
{
return false;
}

#if __JHEXEN__
// We are incompatible with v3 saves due to an invalid test used to determine
// present sides (ver3 format's sides contain chunks of junk data).
if(info.version() == 3)
if(info.meta().version == 3)
{
return false;
}
Expand Down Expand Up @@ -346,16 +346,16 @@ void GameStateReader::read(SaveInfo &info)
* Load the map and configure some game settings.
*/
briefDisabled = true;
G_NewSession(d->saveInfo->mapUri(), 0/*not saved??*/, &d->saveInfo->gameRules());
G_NewSession(d->saveInfo->meta().mapUri, 0/*not saved??*/, &d->saveInfo->meta().gameRules);
G_SetGameAction(GA_NONE); /// @todo Necessary?

#if !__JHEXEN__
mapTime = d->saveInfo->mapTime();
mapTime = d->saveInfo->meta().mapTime;
#endif

int thingArchiveSize = 0;
#if !__JHEXEN__
thingArchiveSize = (d->saveInfo->version() >= 5? Reader_ReadInt32(d->reader) : 1024);
thingArchiveSize = (d->saveInfo->meta().version >= 5? Reader_ReadInt32(d->reader) : 1024);
#endif

d->readPlayers();
Expand All @@ -366,13 +366,13 @@ void GameStateReader::read(SaveInfo &info)

#if !__JHEXEN__
// In netgames, the server tells the clients about this.
NetSv_LoadGame(d->saveInfo->sessionId());
NetSv_LoadGame(d->saveInfo->meta().sessionId);
#endif

Reader_Delete(d->reader); d->reader = 0;

// Material scrollers must be spawned for older savegame versions.
if(d->saveInfo->version() <= 10)
if(d->saveInfo->meta().version <= 10)
{
P_SpawnAllMaterialOriginScrollers();
}
Expand Down
4 changes: 2 additions & 2 deletions doomsday/plugins/common/src/gamestatewriter.cpp
Expand Up @@ -71,7 +71,7 @@ DENG2_PIMPL(GameStateWriter)

void writeSessionHeader()
{
saveInfo->write(writer);
saveInfo->meta().write(writer);
}

void writeWorldACScriptData()
Expand Down Expand Up @@ -138,7 +138,7 @@ void GameStateWriter::write(SaveInfo &info)

// In networked games the server tells the clients to save their games.
#if !__JHEXEN__
NetSv_SaveGame(d->saveInfo->sessionId());
NetSv_SaveGame(d->saveInfo->meta().sessionId);
#endif

if(!SV_OpenFile(path, true/*for writing*/))
Expand Down

0 comments on commit a011e4e

Please sign in to comment.