changeset 13307:d998ec8f4d78 draft

(svn r17816) -Codechange: move the CargoList invalidation-after-saveload to the function that handles the CargoPackets instead of spreading it around over the saveload files. Also add some code to validate whether the caches are valid; to be removed later when no problems turn up
author rubidium <rubidium@openttd.org>
date Tue, 20 Oct 2009 12:20:53 +0000
parents 668cf751db70
children e44c31238b3c
files src/openttd.cpp src/saveload/afterload.cpp src/saveload/cargopacket_sl.cpp src/saveload/station_sl.cpp src/saveload/vehicle_sl.cpp
diffstat 5 files changed, 41 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/src/openttd.cpp
+++ b/src/openttd.cpp
@@ -60,6 +60,7 @@
 #include "highscore.h"
 #include "thread/thread.h"
 #include "base_station_base.h"
+#include "station_base.h"
 #include "airport.h"
 #include "crashlog.h"
 
@@ -1154,6 +1155,25 @@
 			}
 		}
 
+		/* Check whether the caches are still valid */
+		Vehicle *v;
+		FOR_ALL_VEHICLES(v) {
+			byte buff[sizeof(VehicleCargoList)];
+			memcpy(buff, &v->cargo, sizeof(VehicleCargoList));
+			v->cargo.InvalidateCache();
+			assert(memcmp(&v->cargo, buff, sizeof(VehicleCargoList)) == 0);
+		}
+
+		Station *st;
+		FOR_ALL_STATIONS(st) {
+			for (CargoID c = 0; c < NUM_CARGO; c++) {
+				byte buff[sizeof(StationCargoList)];
+				memcpy(buff, &st->goods[c].cargo, sizeof(StationCargoList));
+				st->goods[c].cargo.InvalidateCache();
+				assert(memcmp(&st->goods[c].cargo, buff, sizeof(StationCargoList)) == 0);
+			}
+		}
+
 		/* All these actions has to be done from OWNER_NONE
 		 *  for multiplayer compatibility */
 		CompanyID old_company = _current_company;
--- a/src/saveload/afterload.cpp
+++ b/src/saveload/afterload.cpp
@@ -535,6 +535,14 @@
 	/* Connect front and rear engines of multiheaded trains */
 	ConnectMultiheadedTrains();
 
+	/* Fix the CargoPackets *and* fix the caches of CargoLists.
+	 * If this isn't done before Stations and especially Vehicles are
+	 * running their AfterLoad we might get in trouble. In the case of
+	 * vehicles we could give the wrong (cached) count of items in a
+	 * vehicle which causes different results when getting their caches
+	 * filled; and that could eventually lead to desyncs. */
+	CargoPacket::AfterLoad();
+
 	/* Update all vehicles */
 	AfterLoadVehicles(true);
 
@@ -1226,8 +1234,6 @@
 		}
 	}
 
-	CargoPacket::AfterLoad();
-
 	if (CheckSavegameVersion(45)) {
 		Vehicle *v;
 		/* Originally just the fact that some cargo had been paid for was
@@ -1237,7 +1243,6 @@
 		 * amount that has been paid is stored. */
 		FOR_ALL_VEHICLES(v) {
 			ClrBit(v->vehicle_flags, 2);
-			v->cargo.InvalidateCache();
 		}
 	}
 
--- a/src/saveload/cargopacket_sl.cpp
+++ b/src/saveload/cargopacket_sl.cpp
@@ -33,7 +33,6 @@
 				cp->source_xy = Station::IsValidID(cp->source) ? Station::Get(cp->source)->xy : v->tile;
 				cp->loaded_at_xy = cp->source_xy;
 			}
-			v->cargo.InvalidateCache();
 		}
 
 		/* Store position of the station where the goods come from, so there
@@ -63,6 +62,19 @@
 			if (!Station::IsValidID(cp->source)) cp->source = INVALID_STATION;
 		}
 	}
+
+	if (!CheckSavegameVersion(68)) {
+		/* Only since version 68 we have cargo packets. Savegames from before used
+		 * 'new CargoPacket' + cargolist.Append so their caches are already
+		 * correct and do not need rebuilding. */
+		Vehicle *v;
+		FOR_ALL_VEHICLES(v) v->cargo.InvalidateCache();
+
+		Station *st;
+		FOR_ALL_STATIONS(st) {
+			for (CargoID c = 0; c < NUM_CARGO; c++) st->goods[c].cargo.InvalidateCache();
+		}
+	}
 }
 
 /**
--- a/src/saveload/station_sl.cpp
+++ b/src/saveload/station_sl.cpp
@@ -98,10 +98,6 @@
 			st->speclist[i].spec = GetCustomStationSpecByGrf(st->speclist[i].grfid, st->speclist[i].localidx, NULL);
 		}
 
-		if (Station::IsExpected(st)) {
-			for (CargoID c = 0; c < NUM_CARGO; c++) Station::From(st)->goods[c].cargo.InvalidateCache();
-		}
-
 		StationUpdateAnimTriggers(st);
 	}
 }
--- a/src/saveload/vehicle_sl.cpp
+++ b/src/saveload/vehicle_sl.cpp
@@ -252,8 +252,6 @@
 		v->first = NULL;
 		if (v->type == VEH_TRAIN) Train::From(v)->tcache.first_engine = INVALID_ENGINE;
 		if (v->type == VEH_ROAD)  RoadVehicle::From(v)->rcache.first_engine = INVALID_ENGINE;
-
-		v->cargo.InvalidateCache();
 	}
 
 	/* AfterLoadVehicles may also be called in case of NewGRF reload, in this