(svn r9682) -Codechange: Add support for saving/loading std::lists containing object references (REF_*)
authorpeter1138
Fri, 20 Apr 2007 07:51:20 +0000
changeset 6995 0b1b26cc01b7
parent 6994 eca701b21810
child 6996 99dd61b18d69
(svn r9682) -Codechange: Add support for saving/loading std::lists containing object references (REF_*)
src/saveload.cpp
src/saveload.h
--- a/src/saveload.cpp	Thu Apr 19 19:19:53 2007 +0000
+++ b/src/saveload.cpp	Fri Apr 20 07:51:20 2007 +0000
@@ -27,6 +27,7 @@
 #include "network/network.h"
 #include "variables.h"
 #include <setjmp.h>
+#include <list>
 
 extern const uint16 SAVEGAME_VERSION = 56;
 uint16 _sl_version;       ///< the major savegame version identifier
@@ -627,6 +628,61 @@
 	}
 }
 
+
+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<void *> *l = (std::list<void *> *) 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<void *> *l = (std::list<void *> *) list;
+
+	if (_sl.save) {
+		SlWriteUint16(l->size());
+
+		std::list<void *>::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 @@
 		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 @@
 			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 @@
 }
 
 
-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 @@
 	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 @@
 			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;
--- a/src/saveload.h	Thu Apr 19 19:19:53 2007 +0000
+++ b/src/saveload.h	Fri Apr 20 07:51:20 2007 +0000
@@ -159,6 +159,7 @@
 	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 @@
 #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 @@
 #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}