(svn r11004) -Codechange: some reworks of the saveload mechanism to be able to save and load private and protected variables in the vehicle struct.
authorrubidium
Thu, 30 Aug 2007 13:09:44 +0000
changeset 7989 116c8f9769af
parent 7988 6075538f6111
child 7990 70039e33e893
(svn r11004) -Codechange: some reworks of the saveload mechanism to be able to save and load private and protected variables in the vehicle struct.
src/aircraft_cmd.cpp
src/disaster_cmd.cpp
src/oldloader.cpp
src/saveload.cpp
src/saveload.h
src/train_cmd.cpp
src/vehicle.cpp
src/vehicle.h
--- a/src/aircraft_cmd.cpp	Thu Aug 30 13:03:56 2007 +0000
+++ b/src/aircraft_cmd.cpp	Thu Aug 30 13:09:44 2007 +0000
@@ -405,7 +405,7 @@
 		v->u.air.state = HANGAR;
 		v->u.air.previous_pos = v->u.air.pos;
 		v->u.air.targetairport = GetStationIndex(tile);
-		v->next = u;
+		v->SetNext(u);
 
 		v->service_interval = _patches.servint_aircraft;
 
@@ -429,8 +429,6 @@
 		if (v->subtype == AIR_HELICOPTER) {
 			Vehicle *w = vl[2];
 
-			u->next = w;
-
 			w = new (w) Aircraft();
 			w->direction = DIR_N;
 			w->owner = _current_player;
@@ -445,6 +443,8 @@
 			/* Use rotor's air.state to store the rotor animation frame */
 			w->u.air.state = HRS_ROTOR_STOPPED;
 			w->UpdateDeltaXY(INVALID_DIR);
+
+			u->SetNext(w);
 			VehiclePositionChanged(w);
 		}
 
--- a/src/disaster_cmd.cpp	Thu Aug 30 13:03:56 2007 +0000
+++ b/src/disaster_cmd.cpp	Thu Aug 30 13:09:44 2007 +0000
@@ -611,7 +611,7 @@
 		w = new DisasterVehicle();
 		if (w == NULL) return;
 
-		u->next = w;
+		u->SetNext(w);
 		InitializeDisasterVehicle(w, -6 * TILE_SIZE, v->y_pos, 0, DIR_SW, ST_Big_Ufo_Destroyer_Shadow);
 		w->vehstatus |= VS_SHADOW;
 	} else if (v->current_order.dest == 0) {
@@ -782,7 +782,7 @@
 	/* Allocate shadow too? */
 	u = new DisasterVehicle();
 	if (u != NULL) {
-		v->next = u;
+		v->SetNext(u);
 		InitializeDisasterVehicle(u, x, 0, 0, DIR_SE, ST_Zeppeliner_Shadow);
 		u->vehstatus |= VS_SHADOW;
 	}
@@ -807,7 +807,7 @@
 	/* Allocate shadow too? */
 	u = new DisasterVehicle();
 	if (u != NULL) {
-		v->next = u;
+		v->SetNext(u);
 		InitializeDisasterVehicle(u, x, 0, 0, DIR_SE, ST_Small_Ufo_Shadow);
 		u->vehstatus |= VS_SHADOW;
 	}
@@ -843,7 +843,7 @@
 
 	u = new DisasterVehicle();
 	if (u != NULL) {
-		v->next = u;
+		v->SetNext(u);
 		InitializeDisasterVehicle(u, x, y, 0, DIR_SE, ST_Airplane_Shadow);
 		u->vehstatus |= VS_SHADOW;
 	}
@@ -878,13 +878,13 @@
 
 	u = new DisasterVehicle();
 	if (u != NULL) {
-		v->next = u;
+		v->SetNext(u);
 		InitializeDisasterVehicle(u, x, y, 0, DIR_SW, ST_Helicopter_Shadow);
 		u->vehstatus |= VS_SHADOW;
 
 		w = new DisasterVehicle();
 		if (w != NULL) {
-			u->next = w;
+			u->SetNext(w);
 			InitializeDisasterVehicle(w, x, y, 140, DIR_SW, ST_Helicopter_Rotors);
 		}
 	}
@@ -910,7 +910,7 @@
 	/* Allocate shadow too? */
 	u = new DisasterVehicle();
 	if (u != NULL) {
-		v->next = u;
+		v->SetNext(u);
 		InitializeDisasterVehicle(u, x, y, 0, DIR_NW, ST_Big_Ufo_Shadow);
 		u->vehstatus |= VS_SHADOW;
 	}
--- a/src/oldloader.cpp	Thu Aug 30 13:03:56 2007 +0000
+++ b/src/oldloader.cpp	Thu Aug 30 13:09:44 2007 +0000
@@ -1206,7 +1206,7 @@
 			default:   v->spritenum >>= 1; break;
 		}
 
-		if (_old_next_ptr != 0xFFFF) v->next = GetVehicle(_old_next_ptr);
+		if (_old_next_ptr != 0xFFFF) v->SetNext(GetVehicle(_old_next_ptr));
 
 		v->string_id = RemapOldStringID(_old_string_id);
 
--- a/src/saveload.cpp	Thu Aug 30 13:03:56 2007 +0000
+++ b/src/saveload.cpp	Thu Aug 30 13:09:44 2007 +0000
@@ -52,7 +52,6 @@
 	ReaderProc *read_bytes;              ///< savegame loader function
 
 	const ChunkHandler* const *chs;      ///< the chunk of data that is being processed atm (vehicles, signs, etc.)
-	const SaveLoad* const *includes;     ///< the internal layouf of the given chunk
 
 	/* When saving/loading savegames, they are always saved to a temporary memory-place
 	 * to be flushed to file (save) or to final place (load) when full. */
@@ -755,7 +754,7 @@
 			}
 			break;
 		case SL_WRITEBYTE: return 1; // a byte is logically of size 1
-		case SL_INCLUDE: return SlCalcObjLength(object, _sl.includes[sld->version_from]);
+		case SL_VEH_INCLUDE: return SlCalcObjLength(object, GetVehicleDescription(VEH_END));
 		default: NOT_REACHED();
 	}
 	return 0;
@@ -804,11 +803,9 @@
 		}
 		break;
 
-	/* SL_INCLUDE loads common code for a type
-	 * XXX - variable renaming abuse
-	 * include_index: common code to include from _desc_includes[], abused by sld->version_from */
-	case SL_INCLUDE:
-		SlObject(ptr, _sl.includes[sld->version_from]);
+	/* SL_VEH_INCLUDE loads common code for vehicles */
+	case SL_VEH_INCLUDE:
+		SlObject(ptr, GetVehicleDescription(VEH_END));
 		break;
 	default: NOT_REACHED();
 	}
@@ -1281,12 +1278,6 @@
 	NULL,
 };
 
-/* used to include a vehicle desc in another desc. */
-extern const SaveLoad _common_veh_desc[];
-static const SaveLoad* const _desc_includes[] = {
-	_common_veh_desc
-};
-
 /**
  * Pointers cannot be saved to a savegame, so this functions gets
  * the index of the item, and if not available, it hussles with
@@ -1628,7 +1619,6 @@
 		_sl.bufe = _sl.bufp = NULL;
 		_sl.offs_base = 0;
 		_sl.save = (mode != 0);
-		_sl.includes = _desc_includes;
 		_sl.chs = _chunk_handlers;
 
 		/* General tactic is to first save the game to memory, then use an available writer
--- a/src/saveload.h	Thu Aug 30 13:03:56 2007 +0000
+++ b/src/saveload.h	Thu Aug 30 13:09:44 2007 +0000
@@ -160,15 +160,15 @@
 typedef uint32 VarType;
 
 enum SaveLoadTypes {
-	SL_VAR       =  0,
-	SL_REF       =  1,
-	SL_ARR       =  2,
-	SL_STR       =  3,
-	SL_LST       =  4,
+	SL_VAR         =  0,
+	SL_REF         =  1,
+	SL_ARR         =  2,
+	SL_STR         =  3,
+	SL_LST         =  4,
 	// non-normal save-load types
-	SL_WRITEBYTE =  8,
-	SL_INCLUDE   =  9,
-	SL_END       = 15
+	SL_WRITEBYTE   =  8,
+	SL_VEH_INCLUDE =  9,
+	SL_END         = 15
 };
 
 typedef byte SaveLoadType;
@@ -209,8 +209,6 @@
 
 /* Translate values ingame to different values in the savegame and vv */
 #define SLE_WRITEBYTE(base, variable, value) SLE_GENERAL(SL_WRITEBYTE, base, variable, 0, 0, value, value)
-/* Load common code and put it into each struct (currently only for vehicles */
-#define SLE_INCLUDE(base, variable, include_index) SLE_GENERAL(SL_INCLUDE, base, variable, 0, 0, include_index, 0)
 
 /* The same as the ones at the top, only the offset is given directly; used for unions */
 #define SLE_GENERALX(cmd, offset, type, param1, param2) {false, cmd, type, 0, param1, param2, (void*)(offset)}
@@ -221,7 +219,7 @@
 #define SLE_REFX(offset, type) SLE_CONDREFX(offset, type, 0, SL_MAX_VERSION)
 
 #define SLE_WRITEBYTEX(offset, something) SLE_GENERALX(SL_WRITEBYTE, offset, 0, something, 0)
-#define SLE_INCLUDEX(offset, type) SLE_GENERALX(SL_INCLUDE, offset, type, 0, SL_MAX_VERSION)
+#define SLE_VEH_INCLUDEX() SLE_GENERALX(SL_VEH_INCLUDE, 0, 0, 0, SL_MAX_VERSION)
 
 /* End marker */
 #define SLE_END() {false, SL_END, 0, 0, 0, 0, NULL}
--- a/src/train_cmd.cpp	Thu Aug 30 13:03:56 2007 +0000
+++ b/src/train_cmd.cpp	Thu Aug 30 13:09:44 2007 +0000
@@ -558,7 +558,7 @@
 			SetTrainWagon(v);
 
 			if (u != NULL) {
-				u->next = v;
+				u->SetNext(v);
 			} else {
 				SetFreeWagon(v);
 				InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile);
@@ -636,7 +636,7 @@
 	u->cargo_subtype = v->cargo_subtype;
 	u->cargo_cap = v->cargo_cap;
 	u->u.rail.railtype = v->u.rail.railtype;
-	if (building) v->next = u;
+	if (building) v->SetNext(u);
 	u->engine_type = v->engine_type;
 	u->build_year = v->build_year;
 	if (building) v->value >>= 1;
@@ -840,7 +840,7 @@
 
 	Vehicle *u;
 	for (u = first; GetNextVehicle(u) != v; u = GetNextVehicle(u)) {}
-	GetLastEnginePart(u)->next = GetNextVehicle(v);
+	GetLastEnginePart(u)->SetNext(GetNextVehicle(v));
 	v->first = NULL; // we shouldn't point to the old first, since the vehicle isn't in that chain anymore
 	return first;
 }
@@ -1041,7 +1041,7 @@
 			if (src != src_head) {
 				Vehicle *v = src_head;
 				while (GetNextVehicle(v) != src) v = GetNextVehicle(v);
-				GetLastEnginePart(v)->next = NULL;
+				GetLastEnginePart(v)->SetNext(NULL);
 			} else {
 				InvalidateWindowData(WC_VEHICLE_DEPOT, src_head->tile); // We removed a line
 				src_head = NULL;
@@ -1051,7 +1051,7 @@
 			if (src_head == dst_head) dst_head = NULL;
 			/* unlink single wagon from linked list */
 			src_head = UnlinkWagon(src, src_head);
-			GetLastEnginePart(src)->next = NULL;
+			GetLastEnginePart(src)->SetNext(NULL);
 		}
 
 		if (dst == NULL) {
--- a/src/vehicle.cpp	Thu Aug 30 13:03:56 2007 +0000
+++ b/src/vehicle.cpp	Thu Aug 30 13:09:44 2007 +0000
@@ -2724,8 +2724,15 @@
 static Money  _cargo_feeder_share;
 static uint32 _cargo_loaded_at_xy;
 
+/**
+ * Make it possible to make the saveload tables "friends" of other classes.
+ * @param vt the vehicle type. Can be VEH_END for the common vehicle description data
+ * @return the saveload description
+ */
+const SaveLoad *GetVehicleDescription(VehicleType vt)
+{
 /** Save and load of vehicles */
-extern const SaveLoad _common_veh_desc[] = {
+static const SaveLoad _common_veh_desc[] = {
 	    SLE_VAR(Vehicle, subtype,              SLE_UINT8),
 
 	    SLE_REF(Vehicle, next,                 REF_VEHICLE_OLD),
@@ -2848,7 +2855,7 @@
 
 static const SaveLoad _train_desc[] = {
 	SLE_WRITEBYTE(Vehicle, type, VEH_TRAIN),
-	SLE_INCLUDEX(0, INC_VEHICLE_COMMON),
+	SLE_VEH_INCLUDEX(),
 	    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, crash_anim_pos),         SLE_UINT16),
 	    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, force_proceed),          SLE_UINT8),
 	    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, railtype),               SLE_UINT8),
@@ -2866,7 +2873,7 @@
 
 static const SaveLoad _roadveh_desc[] = {
 	SLE_WRITEBYTE(Vehicle, type, VEH_ROAD),
-	SLE_INCLUDEX(0, INC_VEHICLE_COMMON),
+	SLE_VEH_INCLUDEX(),
 	    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, state),          SLE_UINT8),
 	    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, frame),          SLE_UINT8),
 	    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, blocked_ctr),    SLE_UINT16),
@@ -2886,7 +2893,7 @@
 
 static const SaveLoad _ship_desc[] = {
 	SLE_WRITEBYTE(Vehicle, type, VEH_SHIP),
-	SLE_INCLUDEX(0, INC_VEHICLE_COMMON),
+	SLE_VEH_INCLUDEX(),
 	SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleShip, state), SLE_UINT8),
 
 	/* reserve extra space in savegame here. (currently 16 bytes) */
@@ -2897,7 +2904,7 @@
 
 static const SaveLoad _aircraft_desc[] = {
 	SLE_WRITEBYTE(Vehicle, type, VEH_AIRCRAFT),
-	SLE_INCLUDEX(0, INC_VEHICLE_COMMON),
+	SLE_VEH_INCLUDEX(),
 	    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, crashed_counter), SLE_UINT16),
 	    SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, pos),             SLE_UINT8),
 
@@ -2988,8 +2995,12 @@
 	_aircraft_desc,
 	_special_desc,
 	_disaster_desc,
+	_common_veh_desc,
 };
 
+	return _veh_descs[vt];
+}
+
 /** Will be called when the vehicles need to be saved. */
 static void Save_VEHS()
 {
@@ -2997,7 +3008,7 @@
 	/* Write the vehicles */
 	FOR_ALL_VEHICLES(v) {
 		SlSetArrayIndex(v->index);
-		SlObject(v, _veh_descs[v->type]);
+		SlObject(v, GetVehicleDescription(v->type));
 	}
 }
 
@@ -3024,7 +3035,7 @@
 			default: NOT_REACHED();
 		}
 
-		SlObject(v, _veh_descs[vtype]);
+		SlObject(v, GetVehicleDescription(vtype));
 
 		if (_cargo_count != 0 && IsPlayerBuildableVehicleType(v)) {
 			/* Don't construct the packet with station here, because that'll fail with old savegames */
@@ -3157,7 +3168,6 @@
 	InvalidateVehicleOrder(this);
 }
 
-
 void SpecialVehicle::UpdateDeltaXY(Direction direction)
 {
 	this->x_offs        = 0;
--- a/src/vehicle.h	Thu Aug 30 13:03:56 2007 +0000
+++ b/src/vehicle.h	Thu Aug 30 13:09:44 2007 +0000
@@ -218,11 +218,18 @@
 struct Vehicle;
 DECLARE_OLD_POOL(Vehicle, Vehicle, 9, 125)
 
+struct SaveLoad;
+extern const SaveLoad *GetVehicleDescription(VehicleType vt);
+
 struct Vehicle : PoolItem<Vehicle, VehicleID, &_Vehicle_pool> {
 	VehicleTypeByte type;    ///< Type of vehicle
 	byte subtype;            // subtype (Filled with values from EffectVehicles/TrainSubTypes/AircraftSubTypes)
 
+private:
 	Vehicle *next;           // pointer to the next vehicle in the chain
+public:
+	friend const SaveLoad *GetVehicleDescription(VehicleType vt); // So we can use private/protected variables in the saveload code
+
 	Vehicle *first;          // NOSAVE: pointer to the first vehicle in the chain
 	Vehicle *depot_list;     // NOSAVE: linked list to tell what vehicles entered a depot during the last tick. Used by autoreplace