1
0
Fork 0

Codechange: Support saveload of reference vectors.

This uses the same data format as reference lists, but for vectors, so allows data structures to be changed without affecting savegame format.
pull/13127/head
Peter Nelson 2024-11-14 18:16:43 +00:00 committed by Peter Nelson
parent e7c63de55d
commit 177e2ebf80
2 changed files with 52 additions and 0 deletions

View File

@ -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<std::list, void *>::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<std::vector, void *>::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<std::vector, void *>::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;

View File

@ -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<void *>) == size;
case SL_VECTOR: return sizeof(std::vector<void *>) == size;
case SL_REFLIST: return sizeof(std::list<void *>) == size;
case SL_REFVECTOR: return sizeof(std::vector<void *>) == 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