diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp index 9ae95b51a9..f15e4ee7b7 100644 --- a/src/saveload/saveload.cpp +++ b/src/saveload/saveload.cpp @@ -565,6 +565,7 @@ static uint8_t GetSavegameFileType(const SaveLoad &sld) return IsSavegameVersionBefore(SLV_69) ? SLE_FILE_U16 : SLE_FILE_U32; case SL_REFLIST: + case SL_REFVECTOR: return (IsSavegameVersionBefore(SLV_69) ? SLE_FILE_U16 : SLE_FILE_U32) | SLE_FILE_HAS_LENGTH_FIELD; case SL_SAVEBYTE: @@ -1352,6 +1353,33 @@ static void SlRefList(void *list, VarType conv) SlStorageHelper::SlSaveLoad(list, conv, SL_REF); } +/** + * Return the size in bytes of a vector. + * @param vector The std::vector to find the size of. + * @param conv VarType type of variable that is used for calculating the size. + */ +static size_t SlCalcRefVectorLen(const void *vector, VarType conv) +{ + return SlStorageHelper::SlCalcLen(vector, conv, SL_REF); +} + +/** + * Save/Load a vector. + * @param vector The vector being manipulated. + * @param conv VarType type of variable that is used for calculating the size. + */ +static void SlRefVector(void *vector, VarType conv) +{ + /* Automatically calculate the length? */ + if (_sl.need_length != NL_NONE) { + SlSetLength(SlCalcRefVectorLen(vector, conv)); + /* Determine length only? */ + if (_sl.need_length == NL_CALCLENGTH) return; + } + + SlStorageHelper::SlSaveLoad(vector, conv, SL_REF); +} + /** * Return the size in bytes of a std::deque. * @param deque The std::deque to find the size of @@ -1530,6 +1558,7 @@ size_t SlCalcObjMemberLength(const void *object, const SaveLoad &sld) case SL_REF: return SlCalcRefLen(); case SL_ARR: return SlCalcArrayLen(sld.length, sld.conv); case SL_REFLIST: return SlCalcRefListLen(GetVariableAddress(object, sld), sld.conv); + case SL_REFVECTOR: return SlCalcRefVectorLen(GetVariableAddress(object, sld), sld.conv); case SL_DEQUE: return SlCalcDequeLen(GetVariableAddress(object, sld), sld.conv); case SL_VECTOR: return SlCalcVectorLen(GetVariableAddress(object, sld), sld.conv); case SL_STDSTR: return SlCalcStdStringLen(GetVariableAddress(object, sld)); @@ -1575,6 +1604,7 @@ static bool SlObjectMember(void *object, const SaveLoad &sld) case SL_REF: case SL_ARR: case SL_REFLIST: + case SL_REFVECTOR: case SL_DEQUE: case SL_VECTOR: case SL_STDSTR: { @@ -1585,6 +1615,7 @@ static bool SlObjectMember(void *object, const SaveLoad &sld) case SL_REF: SlSaveLoadRef(ptr, conv); break; case SL_ARR: SlArray(ptr, sld.length, conv); break; case SL_REFLIST: SlRefList(ptr, conv); break; + case SL_REFVECTOR: SlRefVector(ptr, conv); break; case SL_DEQUE: SlDeque(ptr, conv); break; case SL_VECTOR: SlVector(ptr, conv); break; case SL_STDSTR: SlStdString(ptr, sld.conv); break; diff --git a/src/saveload/saveload.h b/src/saveload/saveload.h index f1150ddcf3..e90d040187 100644 --- a/src/saveload/saveload.h +++ b/src/saveload/saveload.h @@ -705,6 +705,8 @@ enum SaveLoadType : uint8_t { SL_SAVEBYTE = 10, ///< Save (but not load) a byte. SL_NULL = 11, ///< Save null-bytes and load to nowhere. + + SL_REFVECTOR = 12, ///< Save/load a vector of #SL_REF elements. }; typedef void *SaveLoadAddrProc(void *base, size_t extra); @@ -813,6 +815,7 @@ inline constexpr bool SlCheckVarSize(SaveLoadType cmd, VarType type, size_t leng case SL_DEQUE: return sizeof(std::deque) == size; case SL_VECTOR: return sizeof(std::vector) == size; case SL_REFLIST: return sizeof(std::list) == size; + case SL_REFVECTOR: return sizeof(std::vector) == size; case SL_SAVEBYTE: return true; default: NOT_REACHED(); } @@ -948,6 +951,16 @@ inline constexpr bool SlCheckVarSize(SaveLoadType cmd, VarType type, size_t leng */ #define SLE_CONDREFLIST(base, variable, type, from, to) SLE_GENERAL(SL_REFLIST, base, variable, type, 0, from, to, 0) +/** + * Storage of a vector of #SL_REF elements in some savegame versions. + * @param base Name of the class or struct containing the vector. + * @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 vector. + * @param to Last savegame version that has the vector. + */ +#define SLE_CONDREFVECTOR(base, variable, type, from, to) SLE_GENERAL(SL_REFVECTOR, 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. @@ -1047,6 +1060,14 @@ inline constexpr bool SlCheckVarSize(SaveLoadType cmd, VarType type, size_t leng */ #define SLE_REFLIST(base, variable, type) SLE_CONDREFLIST(base, variable, type, SL_MIN_VERSION, SL_MAX_VERSION) +/** + * Storage of a vector of #SL_REF elements in every savegame version. + * @param base Name of the class or struct containing the vector. + * @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. + */ +#define SLE_REFVECTOR(base, variable, type) SLE_CONDREFVECTOR(base, variable, type, SL_MIN_VERSION, SL_MAX_VERSION) + /** * Only write byte during saving; never read it during loading. * When using SLE_SAVEBYTE you will have to read this byte before the table