From 6237fe146228e84761c6aba14bf7acf6c359f061 Mon Sep 17 00:00:00 2001 From: rubidium Date: Sat, 23 May 2009 09:10:56 +0000 Subject: [PATCH] (svn r16394) -Codechange: move (NewGRF) cache variables into a separate struct so (some vehicle related) NewGRF cache 'desyncs' can be tested easier. --- src/ai/api/ai_vehicle.cpp | 2 +- src/aircraft.h | 8 +++++++- src/aircraft_cmd.cpp | 8 ++++---- src/articulated_vehicles.cpp | 4 ++-- src/depot_gui.cpp | 2 +- src/misc_cmd.cpp | 2 +- src/newgrf_engine.cpp | 36 ++++++++++++++++++------------------ src/openttd.cpp | 12 ++++++++---- src/roadveh.h | 8 ++++++-- src/roadveh_cmd.cpp | 10 +++++----- src/roadveh_gui.cpp | 2 +- src/saveload/vehicle_sl.cpp | 2 +- src/train_cmd.cpp | 6 +++--- src/vehicle.cpp | 2 +- src/vehicle_base.h | 16 ++++++++++------ src/vehicle_gui.cpp | 4 ++-- 16 files changed, 71 insertions(+), 53 deletions(-) diff --git a/src/ai/api/ai_vehicle.cpp b/src/ai/api/ai_vehicle.cpp index 046cc3cb50..6df24b8759 100644 --- 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; } diff --git a/src/aircraft.h b/src/aircraft.h index d4e11f206c..24f4659f09 100644 --- a/src/aircraft.h +++ b/src/aircraft.h @@ -83,6 +83,11 @@ void AircraftNextAirportPos_and_Order(Aircraft *v); 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 @@ byte GetAircraftFlyingAltitude(const Aircraft *v); * 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; diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp index c06e3e64b3..488b260b28 100644 --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -757,9 +757,9 @@ void UpdateAircraftCache(Aircraft *v) /* 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 @@ static int UpdateAircraftSpeed(Aircraft *v, uint speed_limit = SPEED_LIMIT_NONE, * 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); diff --git a/src/articulated_vehicles.cpp b/src/articulated_vehicles.cpp index 29a7210f42..1407ad9d35 100644 --- a/src/articulated_vehicles.cpp +++ b/src/articulated_vehicles.cpp @@ -334,8 +334,8 @@ void AddArticulatedParts(Vehicle *first, VehicleType type) 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; diff --git a/src/depot_gui.cpp b/src/depot_gui.cpp index 891fc5ceb4..98d7718307 100644 --- a/src/depot_gui.cpp +++ b/src/depot_gui.cpp @@ -518,7 +518,7 @@ struct DepotWindow : Window { 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: diff --git a/src/misc_cmd.cpp b/src/misc_cmd.cpp index 952a8e7520..d79ab92b90 100644 --- a/src/misc_cmd.cpp +++ b/src/misc_cmd.cpp @@ -122,7 +122,7 @@ CommandCost CmdSetCompanyColour(TileIndex tile, DoCommandFlag flags, uint32 p1, /* 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(); diff --git a/src/newgrf_engine.cpp b/src/newgrf_engine.cpp index c4073f3437..550e032779 100644 --- a/src/newgrf_engine.cpp +++ b/src/newgrf_engine.cpp @@ -436,7 +436,7 @@ static uint8 LiveryHelper(EngineID engine, const Vehicle *v) } 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 @@ static uint32 VehicleGetVariable(const ResolverObject *object, byte variable, by 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 @@ static uint32 VehicleGetVariable(const ResolverObject *object, byte variable, by } 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 @@ static const SpriteGroup *GetVehicleSpriteGroup(EngineID engine, const Vehicle * 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; } } diff --git a/src/openttd.cpp b/src/openttd.cpp index 5268de747d..0758bf29b6 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -1119,8 +1119,11 @@ void StateGameLoop() 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 @@ void StateGameLoop() 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; diff --git a/src/roadveh.h b/src/roadveh.h index 905fc5982c..64218e62fb 100644 --- a/src/roadveh.h +++ b/src/roadveh.h @@ -109,6 +109,11 @@ byte GetRoadVehLength(const RoadVehicle *v); 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 @@ void RoadVehUpdateCache(RoadVehicle *v); * 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 @@ struct RoadVehicle : public Vehicle { byte reverse_ctr; struct RoadStop *slot; byte slot_age; - EngineID first_engine; - byte cached_veh_length; RoadType roadtype; RoadTypes compatible_roadtypes; diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp index cdc797e069..f6bf44a885 100644 --- a/src/roadveh_cmd.cpp +++ b/src/roadveh_cmd.cpp @@ -142,10 +142,10 @@ void RoadVehUpdateCache(RoadVehicle *v) 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 @@ CommandCost CmdBuildRoadVeh(TileIndex tile, DoCommandFlag flags, uint32 p1, uint 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 @@ CommandCost CmdBuildRoadVeh(TileIndex tile, DoCommandFlag flags, uint32 p1, uint /* 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 @@ again: * 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); } } diff --git a/src/roadveh_gui.cpp b/src/roadveh_gui.cpp index 58d0d06330..5d0f950f23 100644 --- a/src/roadveh_gui.cpp +++ b/src/roadveh_gui.cpp @@ -130,7 +130,7 @@ void DrawRoadVehImage(const Vehicle *v, int x, int y, VehicleID selection, int c 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); diff --git a/src/saveload/vehicle_sl.cpp b/src/saveload/vehicle_sl.cpp index 5de480a56c..6554baf023 100644 --- a/src/saveload/vehicle_sl.cpp +++ b/src/saveload/vehicle_sl.cpp @@ -253,7 +253,7 @@ void AfterLoadVehicles(bool part_of_load) 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(); } diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index e550c5dbd7..d0bba76b69 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -241,13 +241,13 @@ void TrainConsistChanged(Train *v, bool same_length) /* 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 @@ void TrainConsistChanged(Train *v, bool same_length) 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 */ diff --git a/src/vehicle.cpp b/src/vehicle.cpp index e356b0ea3d..d1665a26a4 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -1426,7 +1426,7 @@ SpriteID GetVehiclePalette(const Vehicle *v) 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); diff --git a/src/vehicle_base.h b/src/vehicle_base.h index 841acb5bb1..350b5e7c5d 100644 --- a/src/vehicle_base.h +++ b/src/vehicle_base.h @@ -43,6 +43,15 @@ enum VehicleFlags { 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 VehiclePool; extern VehiclePool _vehicle_pool; @@ -170,12 +179,7 @@ public: 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(); diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index 2cd83a57d7..e2030df89f 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -641,8 +641,8 @@ static int CDECL VehicleLengthSorter(const Vehicle * const *a, const Vehicle * c 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();