Codechange: Place gamelog into its own class, along with internal data.

Data is now stored in vectors to avoid manual memory management and
passing lengths around.
This commit is contained in:
Peter Nelson
2023-05-01 18:14:31 +01:00
committed by PeterN
parent 47a8d12f0e
commit 00bf42353a
18 changed files with 308 additions and 345 deletions

View File

@@ -340,24 +340,6 @@ static void ResetSignalHandlers()
signal(SIGFPE, _prev_fpe);
}
/**
* Try to find the overridden GRF identifier of the given GRF.
* @param c the GRF to get the 'previous' version of.
* @return the GRF identifier or \a c if none could be found.
*/
static const GRFIdentifier *GetOverriddenIdentifier(const GRFConfig *c)
{
const LoggedAction *la = &_gamelog_action[_gamelog_actions - 1];
if (la->at != GLAT_LOAD) return &c->ident;
const LoggedChange *lcend = &la->change[la->changes];
for (const LoggedChange *lc = la->change; lc != lcend; lc++) {
if (lc->ct == GLCT_GRFCOMPAT && lc->grfcompat.grfid == c->ident.grfid) return &lc->grfcompat;
}
return &c->ident;
}
/** Was the saveload crash because of missing NewGRFs? */
static bool _saveload_crash_with_missing_newgrfs = false;
@@ -405,7 +387,7 @@ static void CDECL HandleSavegameLoadCrash(int signum)
for (const GRFConfig *c = _grfconfig; c != nullptr; c = c->next) {
if (HasBit(c->flags, GCF_COMPATIBLE)) {
const GRFIdentifier *replaced = GetOverriddenIdentifier(c);
const GRFIdentifier *replaced = _gamelog.GetOverriddenIdentifier(c);
char original_md5[40];
char replaced_md5[40];
md5sumToString(original_md5, lastof(original_md5), c->original_md5sum);
@@ -591,10 +573,10 @@ bool AfterLoadGame()
/* The LFSR used in RunTileLoop iteration cannot have a zeroed state, make it non-zeroed. */
if (_cur_tileloop_tile == 0) _cur_tileloop_tile = 1;
if (IsSavegameVersionBefore(SLV_98)) GamelogOldver();
if (IsSavegameVersionBefore(SLV_98)) _gamelog.Oldver();
GamelogTestRevision();
GamelogTestMode();
_gamelog.TestRevision();
_gamelog.TestMode();
RebuildTownKdtree();
RebuildStationKdtree();
@@ -602,7 +584,7 @@ bool AfterLoadGame()
* that otherwise won't exist in the tree. */
RebuildViewportKdtree();
if (IsSavegameVersionBefore(SLV_98)) GamelogGRFAddList(_grfconfig);
if (IsSavegameVersionBefore(SLV_98)) _gamelog.GRFAddList(_grfconfig);
if (IsSavegameVersionBefore(SLV_119)) {
_pause_mode = (_pause_mode == 2) ? PM_PAUSED_NORMAL : PM_UNPAUSED;
@@ -729,9 +711,9 @@ bool AfterLoadGame()
GRFListCompatibility gcf_res = IsGoodGRFConfigList(_grfconfig);
for (GRFConfig *c = _grfconfig; c != nullptr; c = c->next) {
if (c->status == GCS_NOT_FOUND) {
GamelogGRFRemove(c->ident.grfid);
_gamelog.GRFRemove(c->ident.grfid);
} else if (HasBit(c->flags, GCF_COMPATIBLE)) {
GamelogGRFCompatible(&c->ident);
_gamelog.GRFCompatible(&c->ident);
}
}
@@ -3260,7 +3242,7 @@ bool AfterLoadGame()
AfterLoadCompanyStats();
AfterLoadStoryBook();
GamelogPrintDebug(1);
_gamelog.PrintDebug(1);
InitializeWindowsAndCaches();
/* Restore the signals */

View File

@@ -298,12 +298,11 @@ public:
void Save(LoggedAction *la) const override
{
SlSetStructListLength(la->changes);
SlSetStructListLength(la->change.size());
const LoggedChange *lcend = &la->change[la->changes];
for (LoggedChange *lc = la->change; lc != lcend; lc++) {
assert((uint)lc->ct < GLCT_END);
SlObject(lc, this->GetDescription());
for (auto &lc : la->change) {
assert((uint)lc.ct < GLCT_END);
SlObject(&lc, this->GetDescription());
}
}
@@ -315,27 +314,20 @@ public:
if (type >= GLCT_END) SlErrorCorrupt("Invalid gamelog change type");
GamelogChangeType ct = (GamelogChangeType)type;
la->change = ReallocT(la->change, la->changes + 1);
LoggedChange *lc = &la->change[la->changes++];
memset(lc, 0, sizeof(*lc));
lc->ct = ct;
SlObject(lc, this->GetLoadDescription());
LoggedChange &lc = la->change.emplace_back();
lc.ct = ct;
SlObject(&lc, this->GetLoadDescription());
}
return;
}
size_t length = SlGetStructListLength(UINT32_MAX);
la->change = ReallocT(la->change, length);
la->changes = (uint32)length;
la->change.reserve(length);
for (size_t i = 0; i < length; i++) {
LoggedChange *lc = &la->change[i];
memset(lc, 0, sizeof(*lc));
lc->ct = (GamelogChangeType)SlReadByte();
SlObject(lc, this->GetLoadDescription());
LoggedChange &lc = la->change.emplace_back();
lc.ct = (GamelogChangeType)SlReadByte();
SlObject(&lc, this->GetLoadDescription());
}
}
@@ -352,10 +344,9 @@ static const SaveLoad _gamelog_desc[] = {
struct GLOGChunkHandler : ChunkHandler {
GLOGChunkHandler() : ChunkHandler('GLOG', CH_TABLE) {}
void LoadCommon(LoggedAction *&gamelog_action, uint &gamelog_actions) const
void LoadCommon(Gamelog &gamelog) const
{
assert(gamelog_action == nullptr);
assert(gamelog_actions == 0);
assert(gamelog.data->action.empty());
const std::vector<SaveLoad> slt = SlCompatTableHeader(_gamelog_desc, _gamelog_sl_compat);
@@ -364,22 +355,16 @@ struct GLOGChunkHandler : ChunkHandler {
while ((type = SlReadByte()) != GLAT_NONE) {
if (type >= GLAT_END) SlErrorCorrupt("Invalid gamelog action type");
gamelog_action = ReallocT(gamelog_action, gamelog_actions + 1);
LoggedAction *la = &gamelog_action[gamelog_actions++];
memset(la, 0, sizeof(*la));
la->at = (GamelogActionType)type;
SlObject(la, slt);
LoggedAction &la = gamelog.data->action.emplace_back();
la.at = (GamelogActionType)type;
SlObject(&la, slt);
}
return;
}
while (SlIterateArray() != -1) {
gamelog_action = ReallocT(gamelog_action, gamelog_actions + 1);
LoggedAction *la = &gamelog_action[gamelog_actions++];
memset(la, 0, sizeof(*la));
SlObject(la, slt);
LoggedAction &la = gamelog.data->action.emplace_back();
SlObject(&la, slt);
}
}
@@ -387,23 +372,21 @@ struct GLOGChunkHandler : ChunkHandler {
{
SlTableHeader(_gamelog_desc);
const LoggedAction *laend = &_gamelog_action[_gamelog_actions];
uint i = 0;
for (LoggedAction *la = _gamelog_action; la != laend; la++, i++) {
SlSetArrayIndex(i);
SlObject(la, _gamelog_desc);
for (LoggedAction &la : _gamelog.data->action) {
SlSetArrayIndex(i++);
SlObject(&la, _gamelog_desc);
}
}
void Load() const override
{
this->LoadCommon(_gamelog_action, _gamelog_actions);
this->LoadCommon(_gamelog);
}
void LoadCheck(size_t) const override
{
this->LoadCommon(_load_check_data.gamelog_action, _load_check_data.gamelog_actions);
this->LoadCommon(_load_check_data.gamelog);
}
};

View File

@@ -348,7 +348,7 @@ void NORETURN SlError(StringID string, const std::string &extra_msg)
if (_sl.action == SLA_LOAD || _sl.action == SLA_PTRS) SlNullPointers();
/* Logging could be active. */
GamelogStopAnyAction();
_gamelog.StopAnyAction();
throw std::exception();
}
@@ -3129,7 +3129,7 @@ static SaveOrLoadResult DoLoad(LoadFilter *reader, bool load_check)
* confuse old games */
InitializeGame(256, 256, true, true);
GamelogReset();
_gamelog.Reset();
if (IsSavegameVersionBefore(SLV_4)) {
/*
@@ -3175,16 +3175,16 @@ static SaveOrLoadResult DoLoad(LoadFilter *reader, bool load_check)
/* The only part from AfterLoadGame() we need */
_load_check_data.grf_compatibility = IsGoodGRFConfigList(_load_check_data.grfconfig);
} else {
GamelogStartAction(GLAT_LOAD);
_gamelog.StartAction(GLAT_LOAD);
/* After loading fix up savegame for any internal changes that
* might have occurred since then. If it fails, load back the old game. */
if (!AfterLoadGame()) {
GamelogStopAction();
_gamelog.StopAction();
return SL_REINIT;
}
GamelogStopAction();
_gamelog.StopAction();
}
return SL_OK;
@@ -3237,16 +3237,16 @@ SaveOrLoadResult SaveOrLoad(const std::string &filename, SaveLoadOperation fop,
* Note: this is done here because AfterLoadGame is also called
* for OTTD savegames which have their own NewGRF logic. */
ClearGRFConfigList(&_grfconfig);
GamelogReset();
_gamelog.Reset();
if (!LoadOldSaveGame(filename)) return SL_REINIT;
_sl_version = SL_MIN_VERSION;
_sl_minor_version = 0;
GamelogStartAction(GLAT_LOAD);
_gamelog.StartAction(GLAT_LOAD);
if (!AfterLoadGame()) {
GamelogStopAction();
_gamelog.StopAction();
return SL_REINIT;
}
GamelogStopAction();
_gamelog.StopAction();
return SL_OK;
}