From a8350e5fdf4e11599bfadfed80775aa6639b1322 Mon Sep 17 00:00:00 2001 From: peter1138 Date: Fri, 20 Apr 2007 07:51:20 +0000 Subject: [PATCH] (svn r9682) -Codechange: Add support for saving/loading std::lists containing object references (REF_*) --- src/saveload.cpp | 64 +++++++++++++++++++++++++++++++++++++++++++++--- src/saveload.h | 5 ++++ 2 files changed, 65 insertions(+), 4 deletions(-) diff --git a/src/saveload.cpp b/src/saveload.cpp index 511eb7418e..82c4152d65 100644 --- a/src/saveload.cpp +++ b/src/saveload.cpp @@ -27,6 +27,7 @@ #include "network/network.h" #include "variables.h" #include +#include extern const uint16 SAVEGAME_VERSION = 56; uint16 _sl_version; ///< the major savegame version identifier @@ -627,6 +628,61 @@ void SlArray(void *array, uint length, VarType conv) } } + +static uint ReferenceToInt(const void* obj, SLRefType rt); +static void* IntToReference(uint index, SLRefType rt); + + +/** + * Return the size in bytes of a list + * @param list The std::list to find the size of + */ +static inline size_t SlCalcListLen(const void *list) +{ + std::list *l = (std::list *) list; + + /* Each entry is saved as 2 bytes, plus 2 bytes are used for the length + * of the list */ + return l->size() * 2 + 2; +} + + +/** + * Save/Load a list. + * @param list The list being manipulated + * @param conv SLRefType type of the list (Vehicle *, Station *, etc) + */ +void SlList(void *list, SLRefType conv) +{ + /* Automatically calculate the length? */ + if (_sl.need_length != NL_NONE) { + SlSetLength(SlCalcListLen(list)); + /* Determine length only? */ + if (_sl.need_length == NL_CALCLENGTH) return; + } + + std::list *l = (std::list *) list; + + if (_sl.save) { + SlWriteUint16(l->size()); + + std::list::iterator iter; + for (iter = l->begin(); iter != l->end(); ++iter) { + void *ptr = *iter; + SlWriteUint16(ReferenceToInt(ptr, conv)); + } + } else { + uint length = SlReadUint16(); + + /* Load each reference and push to the end of the list */ + for (uint i = 0; i < length; i++) { + void *ptr = IntToReference(SlReadUint16(), conv); + l->push_back(ptr); + } + } +} + + /** Are we going to save this object or not? */ static inline bool SlIsObjectValidInSavegame(const SaveLoad *sld) { @@ -675,6 +731,7 @@ size_t SlCalcObjMemberLength(const void *object, const SaveLoad *sld) case SL_REF: case SL_ARR: case SL_STR: + case SL_LST: /* CONDITIONAL saveload types depend on the savegame version */ if (!SlIsObjectValidInSavegame(sld)) break; @@ -683,6 +740,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_STR: return SlCalcStringLen(GetVariableAddress(object, sld), sld->length, sld->conv); + case SL_LST: return SlCalcListLen(GetVariableAddress(object, sld)); default: NOT_REACHED(); } break; @@ -694,10 +752,6 @@ size_t SlCalcObjMemberLength(const void *object, const SaveLoad *sld) } -static uint ReferenceToInt(const void* obj, SLRefType rt); -static void* IntToReference(uint index, SLRefType rt); - - bool SlObjectMember(void *ptr, const SaveLoad *sld) { VarType conv = GB(sld->conv, 0, 8); @@ -706,6 +760,7 @@ bool SlObjectMember(void *ptr, const SaveLoad *sld) case SL_REF: case SL_ARR: case SL_STR: + case SL_LST: /* CONDITIONAL saveload types depend on the savegame version */ if (!SlIsObjectValidInSavegame(sld)) return false; if (SlSkipVariableOnLoad(sld)) return false; @@ -722,6 +777,7 @@ bool SlObjectMember(void *ptr, const SaveLoad *sld) break; case SL_ARR: SlArray(ptr, sld->length, conv); break; case SL_STR: SlString(ptr, sld->length, conv); break; + case SL_LST: SlList(ptr, (SLRefType)conv); break; default: NOT_REACHED(); } break; diff --git a/src/saveload.h b/src/saveload.h index 9148ab5a5b..7589db5f2b 100644 --- a/src/saveload.h +++ b/src/saveload.h @@ -159,6 +159,7 @@ enum SaveLoadTypes { SL_REF = 1, SL_ARR = 2, SL_STR = 3, + SL_LST = 4, // non-normal save-load types SL_WRITEBYTE = 8, SL_INCLUDE = 9, @@ -190,11 +191,13 @@ typedef SaveLoad SaveLoadGlobVarList; #define SLE_CONDREF(base, variable, type, from, to) SLE_GENERAL(SL_REF, base, variable, type, 0, from, to) #define SLE_CONDARR(base, variable, type, length, from, to) SLE_GENERAL(SL_ARR, base, variable, type, length, from, to) #define SLE_CONDSTR(base, variable, type, length, from, to) SLE_GENERAL(SL_STR, base, variable, type, length, from, to) +#define SLE_CONDLST(base, variable, type, from, to) SLE_GENERAL(SL_LST, base, variable, type, 0, from, to) #define SLE_VAR(base, variable, type) SLE_CONDVAR(base, variable, type, 0, SL_MAX_VERSION) #define SLE_REF(base, variable, type) SLE_CONDREF(base, variable, type, 0, SL_MAX_VERSION) #define SLE_ARR(base, variable, type, length) SLE_CONDARR(base, variable, type, length, 0, SL_MAX_VERSION) #define SLE_STR(base, variable, type, length) SLE_CONDSTR(base, variable, type, length, 0, SL_MAX_VERSION) +#define SLE_LST(base, variable, type) SLE_CONDLST(base, variable, type, 0, SL_MAX_VERSION) #define SLE_CONDNULL(length, from, to) SLE_CONDARR(NullStruct, null, SLE_FILE_U8 | SLE_VAR_NULL | SLF_CONFIG_NO, length, from, to) @@ -224,11 +227,13 @@ typedef SaveLoad SaveLoadGlobVarList; #define SLEG_CONDREF(variable, type, from, to) SLEG_GENERAL(SL_REF, variable, type, 0, from, to) #define SLEG_CONDARR(variable, type, length, from, to) SLEG_GENERAL(SL_ARR, variable, type, length, from, to) #define SLEG_CONDSTR(variable, type, length, from, to) SLEG_GENERAL(SL_STR, variable, type, length, from, to) +#define SLEG_CONDLST(variable, type, from, to) SLEG_GENERAL(SL_LST, variable, type, 0, from, to) #define SLEG_VAR(variable, type) SLEG_CONDVAR(variable, type, 0, SL_MAX_VERSION) #define SLEG_REF(variable, type) SLEG_CONDREF(variable, type, 0, SL_MAX_VERSION) #define SLEG_ARR(variable, type) SLEG_CONDARR(variable, type, lengthof(variable), 0, SL_MAX_VERSION) #define SLEG_STR(variable, type) SLEG_CONDSTR(variable, type, lengthof(variable), 0, SL_MAX_VERSION) +#define SLEG_LST(variable, type) SLEG_CONDLST(variable, type, 0, SL_MAX_VERSION) #define SLEG_CONDNULL(length, from, to) {SL_ARR, SLE_FILE_U8 | SLE_VAR_NULL | SLF_CONFIG_NO, length, from, to, (void*)NULL}