diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp index e32c64a4ac..ded1a83467 100644 --- a/src/saveload/saveload.cpp +++ b/src/saveload/saveload.cpp @@ -1259,13 +1259,17 @@ public: */ static size_t SlCalcLen(const void *storage, VarType conv, SaveLoadType cmd = SL_VAR) { - assert(cmd == SL_VAR || cmd == SL_REF); + assert(cmd == SL_VAR || cmd == SL_REF || cmd == SL_STDSTR); const SlStorageT *list = static_cast(storage); - int type_size = SlGetArrayLength(list->size()); - int item_size = SlCalcConvFileLen(cmd == SL_VAR ? conv : (VarType)SLE_FILE_U32); - return list->size() * item_size + type_size; + size_t type_size = SlGetArrayLength(list->size()); + if constexpr (std::is_same_v, SlStorageT> || std::is_same_v, SlStorageT>) { + return std::accumulate(list->begin(), list->end(), type_size, [](size_t sum, const std::string &str) { return sum + SlCalcStdStringLen(&str); }); + } else { + size_t item_size = SlCalcConvFileLen(cmd == SL_VAR ? conv : (VarType)SLE_FILE_U32); + return list->size() * item_size + type_size; + } } static void SlSaveLoadMember(SaveLoadType cmd, Tvar *item, VarType conv) @@ -1273,6 +1277,7 @@ public: switch (cmd) { case SL_VAR: SlSaveLoadConv(item, conv); break; case SL_REF: SlSaveLoadRef(item, conv); break; + case SL_STDSTR: SlStdString(item, conv); break; default: NOT_REACHED(); } @@ -1286,7 +1291,7 @@ public: */ static void SlSaveLoad(void *storage, VarType conv, SaveLoadType cmd = SL_VAR) { - assert(cmd == SL_VAR || cmd == SL_REF); + assert(cmd == SL_VAR || cmd == SL_REF || cmd == SL_STDSTR); SlStorageT *list = static_cast(storage); @@ -1305,6 +1310,7 @@ public: switch (cmd) { case SL_VAR: length = IsSavegameVersionBefore(SLV_SAVELOAD_LIST_LENGTH) ? SlReadUint32() : SlReadArrayLength(); break; case SL_REF: length = IsSavegameVersionBefore(SLV_69) ? SlReadUint16() : IsSavegameVersionBefore(SLV_SAVELOAD_LIST_LENGTH) ? SlReadUint32() : SlReadArrayLength(); break; + case SL_STDSTR: length = SlReadArrayLength(); break; default: NOT_REACHED(); } @@ -1375,6 +1381,7 @@ static inline size_t SlCalcDequeLen(const void *deque, VarType conv) case SLE_VAR_U32: return SlStorageHelper::SlCalcLen(deque, conv); case SLE_VAR_I64: return SlStorageHelper::SlCalcLen(deque, conv); case SLE_VAR_U64: return SlStorageHelper::SlCalcLen(deque, conv); + case SLE_VAR_STR: return SlStorageHelper::SlCalcLen(deque, conv, SL_STDSTR); default: NOT_REACHED(); } } @@ -1396,6 +1403,7 @@ static void SlDeque(void *deque, VarType conv) case SLE_VAR_U32: SlStorageHelper::SlSaveLoad(deque, conv); break; case SLE_VAR_I64: SlStorageHelper::SlSaveLoad(deque, conv); break; case SLE_VAR_U64: SlStorageHelper::SlSaveLoad(deque, conv); break; + case SLE_VAR_STR: SlStorageHelper::SlSaveLoad(deque, conv, SL_STDSTR); break; default: NOT_REACHED(); } } @@ -1417,6 +1425,7 @@ static inline size_t SlCalcVectorLen(const void *vector, VarType conv) case SLE_VAR_U32: return SlStorageHelper::SlCalcLen(vector, conv); case SLE_VAR_I64: return SlStorageHelper::SlCalcLen(vector, conv); case SLE_VAR_U64: return SlStorageHelper::SlCalcLen(vector, conv); + case SLE_VAR_STR: return SlStorageHelper::SlCalcLen(vector, conv, SL_STDSTR); default: NOT_REACHED(); } } @@ -1438,6 +1447,7 @@ static void SlVector(void *vector, VarType conv) case SLE_VAR_U32: SlStorageHelper::SlSaveLoad(vector, conv); break; case SLE_VAR_I64: SlStorageHelper::SlSaveLoad(vector, conv); break; case SLE_VAR_U64: SlStorageHelper::SlSaveLoad(vector, conv); break; + case SLE_VAR_STR: SlStorageHelper::SlSaveLoad(vector, conv, SL_STDSTR); break; default: NOT_REACHED(); } } diff --git a/src/saveload/saveload.h b/src/saveload/saveload.h index 05ffac1c04..db9de245c9 100644 --- a/src/saveload/saveload.h +++ b/src/saveload/saveload.h @@ -944,6 +944,16 @@ inline constexpr bool SlCheckVarSize(SaveLoadType cmd, VarType type, size_t leng */ #define SLE_CONDDEQUE(base, variable, type, from, to) SLE_GENERAL(SL_DEQUE, base, variable, type, 0, from, to, 0) +/** + * Storage of a vector of #SL_VAR elements in some savegame versions. + * @param base Name of the class or struct containing the list. + * @param variable Name of the variable in the class or struct referenced by \a base. + * @param type Storage of the data in memory and in the savegame. + * @param from First savegame version that has the list. + * @param to Last savegame version that has the list. + */ +#define SLE_CONDVECTOR(base, variable, type, from, to) SLE_GENERAL(SL_VECTOR, base, variable, type, 0, from, to, 0) + /** * Storage of a variable in every version of a savegame. * @param base Name of the class or struct containing the variable.