Fix: Use modern comparisons instead of memcmp in cache check.

This uses C++20 default operator<=> to provide comparisons of some objects.

This works properly with caches that containers.
This commit is contained in:
Peter Nelson 2024-04-16 20:57:12 +01:00 committed by Peter Nelson
parent 21d11ee361
commit 3b75d8bbf8
8 changed files with 36 additions and 14 deletions

View File

@ -50,7 +50,7 @@ void CheckCaches()
uint i = 0;
for (Town *t : Town::Iterate()) {
if (MemCmpT(old_town_caches.data() + i, &t->cache) != 0) {
if (old_town_caches[i] != t->cache) {
Debug(desync, 2, "warning: town cache mismatch: town {}", t->index);
}
i++;
@ -64,7 +64,7 @@ void CheckCaches()
i = 0;
for (const Company *c : Company::Iterate()) {
if (MemCmpT(old_infrastructure.data() + i, &c->infrastructure) != 0) {
if (old_infrastructure[i] != c->infrastructure) {
Debug(desync, 2, "warning: infrastructure cache mismatch: company {}", c->index);
}
i++;
@ -120,23 +120,23 @@ void CheckCaches()
length = 0;
for (const Vehicle *u = v; u != nullptr; u = u->Next()) {
FillNewGRFVehicleCache(u);
if (memcmp(&grf_cache[length], &u->grf_cache, sizeof(NewGRFCache)) != 0) {
if (grf_cache[length] != u->grf_cache) {
Debug(desync, 2, "warning: newgrf cache mismatch: type {}, vehicle {}, company {}, unit number {}, wagon {}", v->type, v->index, v->owner, v->unitnumber, length);
}
if (memcmp(&veh_cache[length], &u->vcache, sizeof(VehicleCache)) != 0) {
if (veh_cache[length] != u->vcache) {
Debug(desync, 2, "warning: vehicle cache mismatch: type {}, vehicle {}, company {}, unit number {}, wagon {}", v->type, v->index, v->owner, v->unitnumber, length);
}
switch (u->type) {
case VEH_TRAIN:
if (memcmp(&gro_cache[length], &Train::From(u)->gcache, sizeof(GroundVehicleCache)) != 0) {
if (gro_cache[length] != Train::From(u)->gcache) {
Debug(desync, 2, "warning: train ground vehicle cache mismatch: vehicle {}, company {}, unit number {}, wagon {}", v->index, v->owner, v->unitnumber, length);
}
if (memcmp(&tra_cache[length], &Train::From(u)->tcache, sizeof(TrainCache)) != 0) {
if (tra_cache[length] != Train::From(u)->tcache) {
Debug(desync, 2, "warning: train cache mismatch: vehicle {}, company {}, unit number {}, wagon {}", v->index, v->owner, v->unitnumber, length);
}
break;
case VEH_ROAD:
if (memcmp(&gro_cache[length], &RoadVehicle::From(u)->gcache, sizeof(GroundVehicleCache)) != 0) {
if (gro_cache[length] != RoadVehicle::From(u)->gcache) {
Debug(desync, 2, "warning: road vehicle ground vehicle cache mismatch: vehicle {}, company {}, unit number {}, wagon {}", v->index, v->owner, v->unitnumber, length);
}
break;
@ -154,10 +154,13 @@ void CheckCaches()
/* Check whether the caches are still valid */
for (Vehicle *v : Vehicle::Iterate()) {
uint8_t buff[sizeof(VehicleCargoList)];
memcpy(buff, &v->cargo, sizeof(VehicleCargoList));
[[maybe_unused]] const auto a = v->cargo.PeriodsInTransit();
[[maybe_unused]] const auto b = v->cargo.TotalCount();
[[maybe_unused]] const auto c = v->cargo.GetFeederShare();
v->cargo.InvalidateCache();
assert(memcmp(&v->cargo, buff, sizeof(VehicleCargoList)) == 0);
assert(a == v->cargo.PeriodsInTransit());
assert(b == v->cargo.TotalCount());
assert(c == v->cargo.GetFeederShare());
}
/* Backup stations_near */
@ -172,10 +175,11 @@ void CheckCaches()
for (Station *st : Station::Iterate()) {
for (GoodsEntry &ge : st->goods) {
uint8_t buff[sizeof(StationCargoList)];
memcpy(buff, &ge.cargo, sizeof(StationCargoList));
[[maybe_unused]] const auto a = ge.cargo.PeriodsInTransit();
[[maybe_unused]] const auto b = ge.cargo.TotalCount();
ge.cargo.InvalidateCache();
assert(memcmp(&ge.cargo, buff, sizeof(StationCargoList)) == 0);
assert(a == ge.cargo.PeriodsInTransit());
assert(b == ge.cargo.TotalCount());
}
/* Check docking tiles */

View File

@ -37,6 +37,8 @@ struct CompanyInfrastructure {
uint32_t station; ///< Count of company owned station tiles.
uint32_t airport; ///< Count of company owned airports.
auto operator<=>(const CompanyInfrastructure &) const = default;
/** Get total sum of all owned track bits. */
uint32_t GetRailTotal() const
{

View File

@ -46,6 +46,8 @@ struct GroundVehicleCache {
/* Cached UI information. */
uint16_t last_speed; ///< The last speed we did display, so we only have to redraw when this changes.
auto operator<=>(const GroundVehicleCache &) const = default;
};
/** Ground vehicle flags. */

View File

@ -96,7 +96,7 @@ CompanyManagerFace ConvertFromOldCompanyManagerFace(uint32_t face)
void AfterLoadCompanyStats()
{
/* Reset infrastructure statistics to zero. */
for (Company *c : Company::Iterate()) MemSetT(&c->infrastructure, 0);
for (Company *c : Company::Iterate()) c->infrastructure = {};
/* Collect airport count. */
for (const Station *st : Station::Iterate()) {

View File

@ -21,6 +21,8 @@ template <typename T>
struct BuildingCounts {
std::vector<T> id_count;
std::vector<T> class_count;
auto operator<=>(const BuildingCounts &) const = default;
};
static const uint CUSTOM_TOWN_NUMBER_DIFFICULTY = 4; ///< value for custom town number in difficulty settings
@ -44,6 +46,8 @@ struct TownCache {
PartOfSubsidy part_of_subsidy; ///< Is this town a source/destination of a subsidy?
std::array<uint32_t, HZB_END> squared_town_zone_radius; ///< UpdateTownRadius updates this given the house count
BuildingCounts<uint16_t> building_counts; ///< The number of each type of building in the town
auto operator<=>(const TownCache &) const = default;
};
/** Town data structure. */

View File

@ -79,6 +79,8 @@ struct TrainCache {
int16_t cached_curve_speed_mod; ///< curve speed modifier of the entire train
uint16_t cached_max_curve_speed; ///< max consist speed limited by curves
auto operator<=>(const TrainCache &) const = default;
};
/**

View File

@ -73,6 +73,8 @@ struct NewGRFCache {
uint32_t company_information; ///< Cache for NewGRF var 43.
uint32_t position_in_vehicle; ///< Cache for NewGRF var 4D.
uint8_t cache_valid; ///< Bitset that indicates which cache values are valid.
auto operator<=>(const NewGRFCache &) const = default;
};
/** Meaning of the various bits of the visual effect. */
@ -125,6 +127,8 @@ struct VehicleCache {
uint16_t cached_cargo_age_period; ///< Number of ticks before carried cargo is aged.
uint8_t cached_vis_effect; ///< Visual effect to show (see #VisualEffect)
auto operator<=>(const VehicleCache &) const = default;
};
/** Sprite sequence for a vehicle part. */

View File

@ -41,6 +41,8 @@ struct ViewportSign {
uint16_t width_normal; ///< The width when not zoomed out (normal font)
uint16_t width_small; ///< The width when zoomed out (small font)
auto operator<=>(const ViewportSign &) const = default;
void UpdatePosition(int center, int top, StringID str, StringID str_small = STR_NULL);
void MarkDirty(ZoomLevel maxzoom = ZOOM_LVL_MAX) const;
};
@ -49,6 +51,8 @@ struct ViewportSign {
struct TrackedViewportSign : ViewportSign {
bool kdtree_valid; ///< Are the sign data valid for use with the _viewport_sign_kdtree?
auto operator<=>(const TrackedViewportSign &) const = default;
/**
* Update the position of the viewport sign.
* Note that this function hides the base class function.