From 10c136f039ea3e7bd0b977c20932532ec41243e4 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Sat, 13 Jul 2024 00:49:37 +0100 Subject: [PATCH] Saveload: Add mechanism for custom handling of missing table fields --- src/sl/saveload.cpp | 4 +++- src/sl/saveload.h | 8 +++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/sl/saveload.cpp b/src/sl/saveload.cpp index 43a1fdc1cf..7f85345a47 100644 --- a/src/sl/saveload.cpp +++ b/src/sl/saveload.cpp @@ -2208,7 +2208,7 @@ static uint8_t GetSavegameTableFileType(const SaveLoad &sld) * @param slt The NamedSaveLoad table with objects to save/load. * @return The ordered SaveLoad array to use. */ -std::vector SlTableHeader(const NamedSaveLoadTable &slt) +std::vector SlTableHeader(const NamedSaveLoadTable &slt, TableHeaderSpecialHandler *special_handler) { /* You can only use SlTableHeader if you are a CH_TABLE. */ assert(_sl.block_mode == CH_TABLE || _sl.block_mode == CH_SPARSE_TABLE); @@ -2255,6 +2255,8 @@ std::vector SlTableHeader(const NamedSaveLoadTable &slt) auto sld_it = std::lower_bound(key_lookup.begin(), key_lookup.end(), key); if (sld_it == key_lookup.end() || sld_it->name != key) { + if (special_handler != nullptr && special_handler->MissingField(key, type, saveloads)) continue; // Special handler took responsibility for missing field + /* SLA_LOADCHECK triggers this debug statement a lot and is perfectly normal. */ DEBUG(sl, _sl.action == SLA_LOAD ? 2 : 6, "Field '%s' of type 0x%02X not found, skipping", key.c_str(), type); diff --git a/src/sl/saveload.h b/src/sl/saveload.h index 291630e9fb..cb344d7df8 100644 --- a/src/sl/saveload.h +++ b/src/sl/saveload.h @@ -1071,9 +1071,15 @@ void SlObjectSaveFiltered(void *object, const SaveLoadTable &slt); void SlObjectLoadFiltered(void *object, const SaveLoadTable &slt); void SlObjectPtrOrNullFiltered(void *object, const SaveLoadTable &slt); +struct TableHeaderSpecialHandler { + virtual ~TableHeaderSpecialHandler() {} + + virtual bool MissingField(const std::string &key, uint8_t type, std::vector &saveloads) { return false; } // By default, do not handle +}; + bool SlIsTableChunk(); void SlSkipTableHeader(); -std::vector SlTableHeader(const NamedSaveLoadTable &slt); +std::vector SlTableHeader(const NamedSaveLoadTable &slt, TableHeaderSpecialHandler *special_handler = nullptr); std::vector SlTableHeaderOrRiff(const NamedSaveLoadTable &slt); void SlSaveTableObjectChunk(const SaveLoadTable &slt); void SlLoadTableOrRiffFiltered(const SaveLoadTable &slt);