changeset 11988:935e4f91c83c draft

(svn r16394) -Codechange: move (NewGRF) cache variables into a separate struct so (some vehicle related) NewGRF cache 'desyncs' can be tested easier.
author rubidium <rubidium@openttd.org>
date Sat, 23 May 2009 09:10:56 +0000
parents 81554d4e6d76
children f70071553e5a
files src/ai/api/ai_vehicle.cpp src/aircraft.h src/aircraft_cmd.cpp src/articulated_vehicles.cpp src/depot_gui.cpp src/misc_cmd.cpp src/newgrf_engine.cpp src/openttd.cpp src/roadveh.h src/roadveh_cmd.cpp src/roadveh_gui.cpp src/saveload/vehicle_sl.cpp src/train_cmd.cpp src/vehicle.cpp src/vehicle_base.h src/vehicle_gui.cpp
diffstat 16 files changed, 71 insertions(+), 53 deletions(-) [+]
line wrap: on
line diff
--- a/src/ai/api/ai_vehicle.cpp
+++ b/src/ai/api/ai_vehicle.cpp
@@ -45,7 +45,7 @@
 		case VEH_ROAD: {
 			uint total_length = 0;
 			for (const Vehicle *u = v; u != NULL; u = u->Next()) {
-				total_length += ((RoadVehicle*)u)->cached_veh_length;
+				total_length += ((RoadVehicle*)u)->rcache.cached_veh_length;
 			}
 			return total_length;
 		}
--- a/src/aircraft.h
+++ b/src/aircraft.h
@@ -83,6 +83,11 @@
 void SetAircraftPosition(Aircraft *v, int x, int y, int z);
 byte GetAircraftFlyingAltitude(const Aircraft *v);
 
+/** Cached oftenly queried (NewGRF) values */
+struct AircraftCache {
+	uint16 cached_max_speed; ///< Cached maximum speed of the aircraft.
+};
+
 /**
  * This class 'wraps' Vehicle; you do not actually instantiate this class.
  * You create a Vehicle using AllocateVehicle, so it is added to the pool
@@ -92,8 +97,9 @@
  * As side-effect the vehicle type is set correctly.
  */
 struct Aircraft : public Vehicle {
+	AircraftCache acache; ///< Cache of often used calculated values
+
 	uint16 crashed_counter;
-	uint16 cached_max_speed;
 	byte pos;
 	byte previous_pos;
 	StationID targetairport;
--- a/src/aircraft_cmd.cpp
+++ b/src/aircraft_cmd.cpp
@@ -757,9 +757,9 @@
 		/* Convert from original units to (approx) km/h */
 		max_speed = (max_speed * 129) / 10;
 
-		v->cached_max_speed = max_speed;
+		v->acache.cached_max_speed = max_speed;
 	} else {
-		v->cached_max_speed = 0xFFFF;
+		v->acache.cached_max_speed = 0xFFFF;
 	}
 }
 
@@ -791,9 +791,9 @@
 	 * and take-off speeds being too low. */
 	speed_limit *= _settings_game.vehicle.plane_speed;
 
-	if (v->cached_max_speed < speed_limit) {
+	if (v->acache.cached_max_speed < speed_limit) {
 		if (v->cur_speed < speed_limit) hard_limit = false;
-		speed_limit = v->cached_max_speed;
+		speed_limit = v->acache.cached_max_speed;
 	}
 
 	speed_limit = min(speed_limit, v->max_speed);
--- a/src/articulated_vehicles.cpp
+++ b/src/articulated_vehicles.cpp
@@ -334,8 +334,8 @@
 				RoadVehicle *rv = new RoadVehicle();
 				rv->subtype = 0;
 				previous->SetNext(u);
-				rv->first_engine = front->engine_type;
-				rv->cached_veh_length = 8; // Callback is called when the consist is finished
+				rv->rcache.first_engine = front->engine_type;
+				rv->rcache.cached_veh_length = 8; // Callback is called when the consist is finished
 				rv->state = RVSB_IN_DEPOT;
 
 				rv->roadtype = front->roadtype;
--- a/src/depot_gui.cpp
+++ b/src/depot_gui.cpp
@@ -518,7 +518,7 @@
 							break;
 
 						case VEH_ROAD:
-							_cursor.short_vehicle_offset = 16 - ((RoadVehicle *)v)->cached_veh_length * 2;
+							_cursor.short_vehicle_offset = 16 - ((RoadVehicle *)v)->rcache.cached_veh_length * 2;
 							break;
 
 						default:
--- a/src/misc_cmd.cpp
+++ b/src/misc_cmd.cpp
@@ -122,7 +122,7 @@
 		/* Company colour data is indirectly cached. */
 		Vehicle *v;
 		FOR_ALL_VEHICLES(v) {
-			if (v->owner == _current_company) v->cache_valid = 0;
+			if (v->owner == _current_company) v->vcache.cache_valid = 0;
 		}
 	}
 	return CommandCost();
--- a/src/newgrf_engine.cpp
+++ b/src/newgrf_engine.cpp
@@ -436,7 +436,7 @@
 	} else if (v->type == VEH_TRAIN) {
 		l = GetEngineLivery(v->engine_type, v->owner, ((Train *)v)->tcache.first_engine, v);
 	} else if (v->type == VEH_ROAD) {
-		l = GetEngineLivery(v->engine_type, v->owner, ((RoadVehicle *)v)->first_engine, v);
+		l = GetEngineLivery(v->engine_type, v->owner, ((RoadVehicle *)v)->rcache.first_engine, v);
 	} else {
 		l = GetEngineLivery(v->engine_type, v->owner, INVALID_ENGINE, v);
 	}
@@ -506,21 +506,21 @@
 			return GetEngineGRFID(v->engine_type);
 
 		case 0x40: // Get length of consist
-			if (!HasBit(v->cache_valid, 0)) {
-				v->cached_var40 = PositionHelper(v, false);
-				SetBit(v->cache_valid, 0);
+			if (!HasBit(v->vcache.cache_valid, 0)) {
+				v->vcache.cached_var40 = PositionHelper(v, false);
+				SetBit(v->vcache.cache_valid, 0);
 			}
-			return v->cached_var40;
+			return v->vcache.cached_var40;
 
 		case 0x41: // Get length of same consecutive wagons
-			if (!HasBit(v->cache_valid, 1)) {
-				v->cached_var41 = PositionHelper(v, true);
-				SetBit(v->cache_valid, 1);
+			if (!HasBit(v->vcache.cache_valid, 1)) {
+				v->vcache.cached_var41 = PositionHelper(v, true);
+				SetBit(v->vcache.cache_valid, 1);
 			}
-			return v->cached_var41;
+			return v->vcache.cached_var41;
 
 		case 0x42: // Consist cargo information
-			if (!HasBit(v->cache_valid, 2)) {
+			if (!HasBit(v->vcache.cache_valid, 2)) {
 				const Vehicle *u;
 				byte cargo_classes = 0;
 				CargoID common_cargo_best = CT_INVALID;
@@ -570,17 +570,17 @@
 				}
 
 				uint8 common_bitnum = (common_cargo_type == CT_INVALID ? 0xFF : GetCargo(common_cargo_type)->bitnum);
-				v->cached_var42 = cargo_classes | (common_bitnum << 8) | (common_subtype << 16) | (user_def_data << 24);
-				SetBit(v->cache_valid, 2);
+				v->vcache.cached_var42 = cargo_classes | (common_bitnum << 8) | (common_subtype << 16) | (user_def_data << 24);
+				SetBit(v->vcache.cache_valid, 2);
 			}
-			return v->cached_var42;
+			return v->vcache.cached_var42;
 
 		case 0x43: // Company information
-			if (!HasBit(v->cache_valid, 3)) {
-				v->cached_var43 = v->owner | (Company::Get(v->owner)->is_ai ? 0x10000 : 0) | (LiveryHelper(v->engine_type, v) << 24);
-				SetBit(v->cache_valid, 3);
+			if (!HasBit(v->vcache.cache_valid, 3)) {
+				v->vcache.cached_var43 = v->owner | (Company::Get(v->owner)->is_ai ? 0x10000 : 0) | (LiveryHelper(v->engine_type, v) << 24);
+				SetBit(v->vcache.cache_valid, 3);
 			}
-			return v->cached_var43;
+			return v->vcache.cached_var43;
 
 		case 0x44: // Aircraft information
 			if (v->type != VEH_AIRCRAFT) return UINT_MAX;
@@ -889,7 +889,7 @@
 			group = use_cache ? ((Train *)v)->tcache.cached_override : GetWagonOverrideSpriteSet(v->engine_type, v->cargo_type, ((Train *)v)->tcache.first_engine);
 			if (group != NULL) return group;
 		} else if (v->type == VEH_ROAD) {
-			group = GetWagonOverrideSpriteSet(v->engine_type, v->cargo_type, ((RoadVehicle *)v)->first_engine);
+			group = GetWagonOverrideSpriteSet(v->engine_type, v->cargo_type, ((RoadVehicle *)v)->rcache.first_engine);
 			if (group != NULL) return group;
 		}
 	}
--- a/src/openttd.cpp
+++ b/src/openttd.cpp
@@ -1119,8 +1119,11 @@
 
 				switch (v->type) {
 					case VEH_ROAD: {
-						extern byte GetRoadVehLength(const RoadVehicle *v);
-						if (GetRoadVehLength((RoadVehicle *)v) != ((RoadVehicle *)v)->cached_veh_length) {
+						RoadVehicle *rv = (RoadVehicle *)v;
+						RoadVehicleCache cache = rv->rcache;
+						RoadVehUpdateCache(rv);
+
+						if (memcmp(&cache, &rv->rcache, sizeof(RoadVehicleCache)) != 0) {
 							DEBUG(desync, 2, "cache mismatch: vehicle %i, company %i, unit number %i\n", v->index, (int)v->owner, v->unitnumber);
 						}
 					} break;
@@ -1149,9 +1152,10 @@
 
 					case VEH_AIRCRAFT: {
 						Aircraft *a = (Aircraft *)v;
-						uint speed = a->cached_max_speed;
+						AircraftCache cache = a->acache;
 						UpdateAircraftCache(a);
-						if (speed != a->cached_max_speed) {
+
+						if (memcmp(&cache, &a->acache, sizeof(AircraftCache)) != 0) {
 							DEBUG(desync, 2, "cache mismatch: vehicle %i, company %i, unit number %i\n", v->index, (int)v->owner, v->unitnumber);
 						}
 					} break;
--- a/src/roadveh.h
+++ b/src/roadveh.h
@@ -109,6 +109,11 @@
 
 void RoadVehUpdateCache(RoadVehicle *v);
 
+/** Cached oftenly queried (NewGRF) values */
+struct RoadVehicleCache {
+	byte cached_veh_length;
+	EngineID first_engine;
+};
 
 /**
  * This class 'wraps' Vehicle; you do not actually instantiate this class.
@@ -119,6 +124,7 @@
  * As side-effect the vehicle type is set correctly.
  */
 struct RoadVehicle : public Vehicle {
+	RoadVehicleCache rcache; ///< Cache of often used calculated values
 	byte state;             ///< @see RoadVehicleStates
 	byte frame;
 	uint16 blocked_ctr;
@@ -128,8 +134,6 @@
 	byte reverse_ctr;
 	struct RoadStop *slot;
 	byte slot_age;
-	EngineID first_engine;
-	byte cached_veh_length;
 
 	RoadType roadtype;
 	RoadTypes compatible_roadtypes;
--- a/src/roadveh_cmd.cpp
+++ b/src/roadveh_cmd.cpp
@@ -142,10 +142,10 @@
 		assert(u->First() == v);
 
 		/* Update the 'first engine' */
-		u->first_engine = (v == u) ? INVALID_ENGINE : v->engine_type;
+		u->rcache.first_engine = (v == u) ? INVALID_ENGINE : v->engine_type;
 
 		/* Update the length of the vehicle. */
-		u->cached_veh_length = GetRoadVehLength(u);
+		u->rcache.cached_veh_length = GetRoadVehLength(u);
 
 		/* Invalidate the vehicle colour map */
 		u->colourmap = PAL_NONE;
@@ -244,7 +244,7 @@
 
 		v->roadtype = HasBit(EngInfo(v->engine_type)->misc_flags, EF_ROAD_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD;
 		v->compatible_roadtypes = RoadTypeToRoadTypes(v->roadtype);
-		v->cached_veh_length = 8;
+		v->rcache.cached_veh_length = 8;
 
 		v->vehicle_flags = 0;
 		if (e->flags & ENGINE_EXCLUSIVE_PREVIEW) SetBit(v->vehicle_flags, VF_BUILT_AS_PROTOTYPE);
@@ -255,7 +255,7 @@
 
 		/* Call various callbacks after the whole consist has been constructed */
 		for (RoadVehicle *u = v; u != NULL; u = u->Next()) {
-			u->cached_veh_length = GetRoadVehLength(u);
+			u->rcache.cached_veh_length = GetRoadVehLength(u);
 			/* Cargo capacity is zero if and only if the vehicle cannot carry anything */
 			if (u->cargo_cap != 0) u->cargo_cap = GetVehicleProperty(u, 0x0F, u->cargo_cap);
 		}
@@ -1582,7 +1582,7 @@
 	 * it's on a depot tile, check if it's time to activate the next vehicle in
 	 * the chain yet. */
 	if (v->Next() != NULL && IsRoadDepotTile(v->tile)) {
-		if (v->frame == v->cached_veh_length + RVC_DEPOT_START_FRAME) {
+		if (v->frame == v->rcache.cached_veh_length + RVC_DEPOT_START_FRAME) {
 			RoadVehLeaveDepot(v->Next(), false);
 		}
 	}
--- a/src/roadveh_gui.cpp
+++ b/src/roadveh_gui.cpp
@@ -130,7 +130,7 @@
 	int highlight_w = 0;
 
 	for (int dx = 0; v != NULL && dx < max_length ; v = v->Next()) {
-		int width = ((RoadVehicle *)v)->cached_veh_length;
+		int width = ((RoadVehicle *)v)->rcache.cached_veh_length;
 
 		if (dx + width > 0 && dx <= max_length) {
 			SpriteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v);
--- a/src/saveload/vehicle_sl.cpp
+++ b/src/saveload/vehicle_sl.cpp
@@ -253,7 +253,7 @@
 		if (part_of_load) v->fill_percent_te_id = INVALID_TE_ID;
 		v->first = NULL;
 		if (v->type == VEH_TRAIN) ((Train *)v)->tcache.first_engine = INVALID_ENGINE;
-		if (v->type == VEH_ROAD)  ((RoadVehicle *)v)->first_engine = INVALID_ENGINE;
+		if (v->type == VEH_ROAD)  ((RoadVehicle *)v)->rcache.first_engine = INVALID_ENGINE;
 
 		v->cargo.InvalidateCache();
 	}
--- a/src/train_cmd.cpp
+++ b/src/train_cmd.cpp
@@ -241,13 +241,13 @@
 
 		/* Set user defined data to its default value */
 		u->tcache.user_def_data = rvi_u->user_def_data;
-		u->cache_valid = 0;
+		u->vcache.cache_valid = 0;
 	}
 
 	for (Train *u = v; u != NULL; u = u->Next()) {
 		/* Update user defined data (must be done before other properties) */
 		u->tcache.user_def_data = GetVehicleProperty(u, 0x25, u->tcache.user_def_data);
-		u->cache_valid = 0;
+		u->vcache.cache_valid = 0;
 	}
 
 	for (Train *u = v; u != NULL; u = u->Next()) {
@@ -333,7 +333,7 @@
 		if (!same_length) u->tcache.cached_veh_length = veh_len;
 
 		v->tcache.cached_total_length += u->tcache.cached_veh_length;
-		u->cache_valid = 0;
+		u->vcache.cache_valid = 0;
 	}
 
 	/* store consist weight/max speed in cache */
--- a/src/vehicle.cpp
+++ b/src/vehicle.cpp
@@ -1426,7 +1426,7 @@
 	if (v->type == VEH_TRAIN) {
 		return GetEngineColourMap(v->engine_type, v->owner, ((Train *)v)->tcache.first_engine, v);
 	} else if (v->type == VEH_ROAD) {
-		return GetEngineColourMap(v->engine_type, v->owner, ((RoadVehicle *)v)->first_engine, v);
+		return GetEngineColourMap(v->engine_type, v->owner, ((RoadVehicle *)v)->rcache.first_engine, v);
 	}
 
 	return GetEngineColourMap(v->engine_type, v->owner, INVALID_ENGINE, v);
--- a/src/vehicle_base.h
+++ b/src/vehicle_base.h
@@ -43,6 +43,15 @@
 	VF_AUTOFILL_PRES_WAIT_TIME, ///< Whether non-destructive auto-fill should preserve waiting times
 };
 
+/** Cached oftenly queried (NewGRF) values */
+struct VehicleCache {
+	uint8 cache_valid;   ///< Whether the caches are valid
+	uint32 cached_var40; ///< Cache for NewGRF var 40
+	uint32 cached_var41; ///< Cache for NewGRF var 41
+	uint32 cached_var42; ///< Cache for NewGRF var 42
+	uint32 cached_var43; ///< Cache for NewGRF var 43
+};
+
 typedef Pool<Vehicle, VehicleID, 512, 64000> VehiclePool;
 extern VehiclePool _vehicle_pool;
 
@@ -170,12 +179,7 @@
 
 	byte subtype;                   ///< subtype (Filled with values from EffectVehicles/TrainSubTypes/AircraftSubTypes)
 
-	/* cached oftenly queried NewGRF values */
-	uint8 cache_valid;   ///< Whether the caches are valid
-	uint32 cached_var40; ///< Cache for NewGRF var 40
-	uint32 cached_var41; ///< Cache for NewGRF var 41
-	uint32 cached_var42; ///< Cache for NewGRF var 42
-	uint32 cached_var43; ///< Cache for NewGRF var 43
+	VehicleCache vcache;            ///< Cache of often used calculated values
 
 	/** Create a new vehicle */
 	Vehicle();
--- a/src/vehicle_gui.cpp
+++ b/src/vehicle_gui.cpp
@@ -641,8 +641,8 @@
 
 		case VEH_ROAD: {
 			const RoadVehicle *u;
-			for (u = (RoadVehicle *)*a; u != NULL; u = u->Next()) r += u->cached_veh_length;
-			for (u = (RoadVehicle *)*b; u != NULL; u = u->Next()) r -= u->cached_veh_length;
+			for (u = (RoadVehicle *)*a; u != NULL; u = u->Next()) r += u->rcache.cached_veh_length;
+			for (u = (RoadVehicle *)*b; u != NULL; u = u->Next()) r -= u->rcache.cached_veh_length;
 		} break;
 
 		default: NOT_REACHED();