OpenTTD Source 20241224-master-gee860a5c8e
cachecheck.cpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6 */
7
10#include "stdafx.h"
11#include "aircraft.h"
12#include "company_base.h"
13#include "debug.h"
14#include "industry.h"
15#include "roadstop_base.h"
16#include "roadveh.h"
17#include "ship.h"
18#include "station_base.h"
19#include "station_map.h"
20#include "subsidy_func.h"
21#include "town.h"
22#include "train.h"
23#include "vehicle_base.h"
24
25#include "safeguards.h"
26
27extern void AfterLoadCompanyStats();
28extern void RebuildTownCaches();
29
37{
38 /* Return here so it is easy to add checks that are run
39 * always to aid testing of caches. */
40 if (_debug_desync_level <= 1) return;
41
42 /* Check the town caches. */
43 std::vector<TownCache> old_town_caches;
44 for (const Town *t : Town::Iterate()) {
45 old_town_caches.push_back(t->cache);
46 }
47
50
51 uint i = 0;
52 for (Town *t : Town::Iterate()) {
53 if (old_town_caches[i] != t->cache) {
54 Debug(desync, 2, "warning: town cache mismatch: town {}", t->index);
55 }
56 i++;
57 }
58
59 /* Check company infrastructure cache. */
60 std::vector<CompanyInfrastructure> old_infrastructure;
61 for (const Company *c : Company::Iterate()) old_infrastructure.push_back(c->infrastructure);
62
64
65 i = 0;
66 for (const Company *c : Company::Iterate()) {
67 if (old_infrastructure[i] != c->infrastructure) {
68 Debug(desync, 2, "warning: infrastructure cache mismatch: company {}", c->index);
69 }
70 i++;
71 }
72
73 /* Strict checking of the road stop cache entries */
74 for (const RoadStop *rs : RoadStop::Iterate()) {
75 if (IsBayRoadStopTile(rs->xy)) continue;
76
77 assert(rs->GetEntry(DIAGDIR_NE) != rs->GetEntry(DIAGDIR_NW));
78 rs->GetEntry(DIAGDIR_NE)->CheckIntegrity(rs);
79 rs->GetEntry(DIAGDIR_NW)->CheckIntegrity(rs);
80 }
81
82 std::vector<NewGRFCache> grf_cache;
83 std::vector<VehicleCache> veh_cache;
84 std::vector<GroundVehicleCache> gro_cache;
85 std::vector<TrainCache> tra_cache;
86
87 for (Vehicle *v : Vehicle::Iterate()) {
88 if (v != v->First() || v->vehstatus & VS_CRASHED || !v->IsPrimaryVehicle()) continue;
89
90 for (const Vehicle *u = v; u != nullptr; u = u->Next()) {
92 grf_cache.emplace_back(u->grf_cache);
93 veh_cache.emplace_back(u->vcache);
94 switch (u->type) {
95 case VEH_TRAIN:
96 gro_cache.emplace_back(Train::From(u)->gcache);
97 tra_cache.emplace_back(Train::From(u)->tcache);
98 break;
99 case VEH_ROAD:
100 gro_cache.emplace_back(RoadVehicle::From(u)->gcache);
101 break;
102 default:
103 break;
104 }
105 }
106
107 switch (v->type) {
108 case VEH_TRAIN: Train::From(v)->ConsistChanged(CCF_TRACK); break;
111 case VEH_SHIP: Ship::From(v)->UpdateCache(); break;
112 default: break;
113 }
114
115 uint length = 0;
116 for (const Vehicle *u = v; u != nullptr; u = u->Next()) {
118 if (grf_cache[length] != u->grf_cache) {
119 Debug(desync, 2, "warning: newgrf cache mismatch: type {}, vehicle {}, company {}, unit number {}, wagon {}", v->type, v->index, v->owner, v->unitnumber, length);
120 }
121 if (veh_cache[length] != u->vcache) {
122 Debug(desync, 2, "warning: vehicle cache mismatch: type {}, vehicle {}, company {}, unit number {}, wagon {}", v->type, v->index, v->owner, v->unitnumber, length);
123 }
124 switch (u->type) {
125 case VEH_TRAIN:
126 if (gro_cache[length] != Train::From(u)->gcache) {
127 Debug(desync, 2, "warning: train ground vehicle cache mismatch: vehicle {}, company {}, unit number {}, wagon {}", v->index, v->owner, v->unitnumber, length);
128 }
129 if (tra_cache[length] != Train::From(u)->tcache) {
130 Debug(desync, 2, "warning: train cache mismatch: vehicle {}, company {}, unit number {}, wagon {}", v->index, v->owner, v->unitnumber, length);
131 }
132 break;
133 case VEH_ROAD:
134 if (gro_cache[length] != RoadVehicle::From(u)->gcache) {
135 Debug(desync, 2, "warning: road vehicle ground vehicle cache mismatch: vehicle {}, company {}, unit number {}, wagon {}", v->index, v->owner, v->unitnumber, length);
136 }
137 break;
138 default:
139 break;
140 }
141 length++;
142 }
143
144 grf_cache.clear();
145 veh_cache.clear();
146 gro_cache.clear();
147 tra_cache.clear();
148 }
149
150 /* Check whether the caches are still valid */
151 for (Vehicle *v : Vehicle::Iterate()) {
152 [[maybe_unused]] const auto a = v->cargo.PeriodsInTransit();
153 [[maybe_unused]] const auto b = v->cargo.TotalCount();
154 [[maybe_unused]] const auto c = v->cargo.GetFeederShare();
155 v->cargo.InvalidateCache();
156 assert(a == v->cargo.PeriodsInTransit());
157 assert(b == v->cargo.TotalCount());
158 assert(c == v->cargo.GetFeederShare());
159 }
160
161 /* Backup stations_near */
162 std::vector<StationList> old_town_stations_near;
163 for (Town *t : Town::Iterate()) old_town_stations_near.push_back(t->stations_near);
164
165 std::vector<StationList> old_industry_stations_near;
166 for (Industry *ind : Industry::Iterate()) old_industry_stations_near.push_back(ind->stations_near);
167
168 std::vector<IndustryList> old_station_industries_near;
169 for (Station *st : Station::Iterate()) old_station_industries_near.push_back(st->industries_near);
170
171 for (Station *st : Station::Iterate()) {
172 for (GoodsEntry &ge : st->goods) {
173 [[maybe_unused]] const auto a = ge.cargo.PeriodsInTransit();
174 [[maybe_unused]] const auto b = ge.cargo.TotalCount();
175 ge.cargo.InvalidateCache();
176 assert(a == ge.cargo.PeriodsInTransit());
177 assert(b == ge.cargo.TotalCount());
178 }
179
180 /* Check docking tiles */
181 TileArea ta;
182 std::map<TileIndex, bool> docking_tiles;
183 for (TileIndex tile : st->docking_station) {
184 ta.Add(tile);
185 docking_tiles[tile] = IsDockingTile(tile);
186 }
187 UpdateStationDockingTiles(st);
188 if (ta.tile != st->docking_station.tile || ta.w != st->docking_station.w || ta.h != st->docking_station.h) {
189 Debug(desync, 2, "warning: station docking mismatch: station {}, company {}", st->index, st->owner);
190 }
191 for (TileIndex tile : ta) {
192 if (docking_tiles[tile] != IsDockingTile(tile)) {
193 Debug(desync, 2, "warning: docking tile mismatch: tile {}", tile);
194 }
195 }
196 }
197
199
200 /* Check industries_near */
201 i = 0;
202 for (Station *st : Station::Iterate()) {
203 if (st->industries_near != old_station_industries_near[i]) {
204 Debug(desync, 2, "warning: station industries near mismatch: station {}", st->index);
205 }
206 i++;
207 }
208
209 /* Check stations_near */
210 i = 0;
211 for (Town *t : Town::Iterate()) {
212 if (t->stations_near != old_town_stations_near[i]) {
213 Debug(desync, 2, "warning: town stations near mismatch: town {}", t->index);
214 }
215 i++;
216 }
217 i = 0;
218 for (Industry *ind : Industry::Iterate()) {
219 if (ind->stations_near != old_industry_stations_near[i]) {
220 Debug(desync, 2, "warning: industry stations near mismatch: industry {}", ind->index);
221 }
222 i++;
223 }
224}
Base for aircraft.
void UpdateAircraftCache(Aircraft *v, bool update_range=false)
Update cached values of an aircraft.
void RebuildTownCaches()
Rebuild all the cached variables of towns.
Definition town_sl.cpp:27
void AfterLoadCompanyStats()
Rebuilding of company statistics after loading a savegame.
void CheckCaches()
Check the validity of some of the caches.
Definition of stuff that is very close to a company, like the company struct itself.
Functions related to debugging.
#define Debug(category, level, format_string,...)
Ouptut a line of debugging information.
Definition debug.h:37
@ DIAGDIR_NE
Northeast, upper right on your monitor.
@ DIAGDIR_NW
Northwest.
Base of all industries.
void FillNewGRFVehicleCache(const Vehicle *v)
Fill the grf_cache of the given vehicle.
Base class for roadstops.
Road vehicle states.
void RoadVehUpdateCache(RoadVehicle *v, bool same_length=false)
Update the cache of a road vehicle.
A number of safeguards to prevent using unsafe methods.
Base for ships.
Base classes/functions for stations.
Maps accessors for stations.
bool IsBayRoadStopTile(Tile t)
Is tile t a bay (non-drive through) road stop station?
Definition of base types and functions in a cross-platform compatible way.
Stores station stats for a single cargo.
Defines the internal data of a functional industry.
Definition industry.h:66
Represents the covered area of e.g.
uint16_t w
The width of the area.
void Add(TileIndex to_add)
Add a single tile to a tile area; enlarge if needed.
Definition tilearea.cpp:43
TileIndex tile
The base tile of the area.
uint16_t h
The height of the area.
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
A Stop for a Road Vehicle.
void UpdateCache()
Update the caches of this ship.
Definition ship_cmd.cpp:232
static Pool::IterateWrapper< Station > Iterate(size_t from=0)
Returns an iterable ensemble of all valid stations of type T.
static T * From(Vehicle *v)
Converts a Vehicle to SpecializedVehicle with type checking.
Station data structure.
static void RecomputeCatchmentForAll()
Recomputes catchment of all stations.
Definition station.cpp:530
Town data structure.
Definition town.h:54
Vehicle data structure.
Vehicle * Next() const
Get the next vehicle of this vehicle.
void RebuildSubsidisedSourceAndDestinationCache()
Perform a full rebuild of the subsidies cache.
Definition subsidy.cpp:134
Functions related to subsidies.
Base of the town class.
Base for the train class.
@ CCF_TRACK
Valid changes while vehicle is driving, and possibly changing tracks.
Definition train.h:48
Base class for all vehicles.
@ VS_CRASHED
Vehicle is crashed.
@ VEH_ROAD
Road vehicle type.
@ VEH_AIRCRAFT
Aircraft vehicle type.
@ VEH_SHIP
Ship vehicle type.
@ VEH_TRAIN
Train vehicle type.
bool IsDockingTile(Tile t)
Checks whether the tile is marked as a dockling tile.
Definition water_map.h:371