From 325f7f9767b7d613918b3f2e3cc738c16eea7ce1 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Wed, 26 Mar 2025 21:22:33 +0000 Subject: [PATCH] Codechange: Use EnumBitSet for GoodsEntry status. (#13899) --- src/economy.cpp | 10 ++++------ src/linkgraph/linkgraph.cpp | 2 +- src/newgrf_house.cpp | 5 +---- src/newgrf_station.cpp | 25 +++++++++++++++++-------- src/saveload/afterload.cpp | 2 +- src/saveload/oldloader_sl.cpp | 4 ++-- src/saveload/station_sl.cpp | 4 ++-- src/script/api/script_cargolist.cpp | 2 +- src/station_base.h | 25 ++++++++++++++----------- src/station_cmd.cpp | 18 +++++++++--------- 10 files changed, 52 insertions(+), 45 deletions(-) diff --git a/src/economy.cpp b/src/economy.cpp index 6bcaaa37b8..0bad0f0f31 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -1107,9 +1107,7 @@ static Money DeliverGoods(int num_pieces, CargoType cargo_type, StationID dest, /* Update station statistics */ if (accepted_total > 0) { - SetBit(st->goods[cargo_type].status, GoodsEntry::GES_EVER_ACCEPTED); - SetBit(st->goods[cargo_type].status, GoodsEntry::GES_CURRENT_MONTH); - SetBit(st->goods[cargo_type].status, GoodsEntry::GES_ACCEPTED_BIGTICK); + st->goods[cargo_type].status.Set({GoodsEntry::State::EverAccepted, GoodsEntry::State::CurrentMonth, GoodsEntry::State::AcceptedBigtick}); } /* Update company statistics */ @@ -1285,7 +1283,7 @@ void PrepareUnload(Vehicle *front_v) const GoodsEntry *ge = &st->goods[v->cargo_type]; if (v->cargo_cap > 0 && v->cargo.TotalCount() > 0) { v->cargo.Stage( - HasBit(ge->status, GoodsEntry::GES_ACCEPTANCE), + ge->status.Test(GoodsEntry::State::Acceptance), front_v->last_station_visited, next_station, front_v->current_order.GetUnloadType(), ge, v->cargo_type, front_v->cargo_payment, @@ -1676,7 +1674,7 @@ static void LoadUnloadVehicle(Vehicle *front) uint amount_unloaded = _settings_game.order.gradual_loading ? std::min(cargo_count, GetLoadAmount(v)) : cargo_count; bool remaining = false; // Are there cargo entities in this vehicle that can still be unloaded here? - if (!HasBit(ge->status, GoodsEntry::GES_ACCEPTANCE) && v->cargo.ActionCount(VehicleCargoList::MTA_DELIVER) > 0) { + if (!ge->status.Test(GoodsEntry::State::Acceptance) && v->cargo.ActionCount(VehicleCargoList::MTA_DELIVER) > 0) { /* The station does not accept our goods anymore. */ if (front->current_order.GetUnloadType() & (OUFB_TRANSFER | OUFB_UNLOAD)) { /* Transfer instead of delivering. */ @@ -1709,7 +1707,7 @@ static void LoadUnloadVehicle(Vehicle *front) /* Upon transferring cargo, make sure the station has a rating. Fake a pickup for the * first unload to prevent the cargo from quickly decaying after the initial drop. */ ge->time_since_pickup = 0; - SetBit(ge->status, GoodsEntry::GES_RATING); + ge->status.Set(GoodsEntry::State::Rating); } } diff --git a/src/linkgraph/linkgraph.cpp b/src/linkgraph/linkgraph.cpp index dcbbc3eda2..a5743fc6ab 100644 --- a/src/linkgraph/linkgraph.cpp +++ b/src/linkgraph/linkgraph.cpp @@ -151,7 +151,7 @@ NodeID LinkGraph::AddNode(const Station *st) const GoodsEntry &good = st->goods[this->cargo]; NodeID new_node = this->Size(); - this->nodes.emplace_back(st->xy, st->index, HasBit(good.status, GoodsEntry::GES_ACCEPTANCE)); + this->nodes.emplace_back(st->xy, st->index, good.status.Test(GoodsEntry::State::Acceptance)); return new_node; } diff --git a/src/newgrf_house.cpp b/src/newgrf_house.cpp index 4d99affbbc..3203688e43 100644 --- a/src/newgrf_house.cpp +++ b/src/newgrf_house.cpp @@ -462,10 +462,7 @@ static uint32_t GetDistanceFromNearbyHouse(uint8_t parameter, TileIndex tile, Ho /* Collect acceptance stats. */ uint32_t res = 0; for (Station *st : stations.GetStations()) { - if (HasBit(st->goods[cargo_type].status, GoodsEntry::GES_EVER_ACCEPTED)) SetBit(res, 0); - if (HasBit(st->goods[cargo_type].status, GoodsEntry::GES_LAST_MONTH)) SetBit(res, 1); - if (HasBit(st->goods[cargo_type].status, GoodsEntry::GES_CURRENT_MONTH)) SetBit(res, 2); - if (HasBit(st->goods[cargo_type].status, GoodsEntry::GES_ACCEPTED_BIGTICK)) SetBit(res, 3); + res |= st->goods[cargo_type].ConvertState(); } /* Cargo triggered CB 148? */ diff --git a/src/newgrf_station.cpp b/src/newgrf_station.cpp index 90bceffe43..e24d45a5aa 100644 --- a/src/newgrf_station.cpp +++ b/src/newgrf_station.cpp @@ -53,6 +53,20 @@ template class NewGRFClass; static const uint NUM_STATIONSSPECS_PER_STATION = 255; ///< Maximum number of parts per station. +/** + * Convert GoodsEntry status to the form required for NewGRF variables. + * @return NewGRF representation of GoodsEntry state. + */ +uint8_t GoodsEntry::ConvertState() const +{ + uint8_t res = 0; + if (this->status.Test(GoodsEntry::State::EverAccepted)) SetBit(res, 0); + if (this->status.Test(GoodsEntry::State::LastMonth)) SetBit(res, 1); + if (this->status.Test(GoodsEntry::State::CurrentMonth)) SetBit(res, 2); + if (this->status.Test(GoodsEntry::State::AcceptedBigtick)) SetBit(res, 3); + return res; +} + enum TriggerArea : uint8_t { TA_TILE, TA_PLATFORM, @@ -447,13 +461,8 @@ uint32_t Station::GetNewGRFVariable(const ResolverObject &object, uint8_t variab case 0x62: return ge->HasRating() ? ge->rating : 0xFFFFFFFF; case 0x63: return ge->HasData() ? ge->GetData().cargo.PeriodsInTransit() : 0; case 0x64: return ge->HasVehicleEverTriedLoading() ? ge->last_speed | (ge->last_age << 8) : 0xFF00; - case 0x65: return GB(ge->status, GoodsEntry::GES_ACCEPTANCE, 1) << 3; - case 0x69: { - static_assert((int)GoodsEntry::GES_EVER_ACCEPTED + 1 == (int)GoodsEntry::GES_LAST_MONTH); - static_assert((int)GoodsEntry::GES_EVER_ACCEPTED + 2 == (int)GoodsEntry::GES_CURRENT_MONTH); - static_assert((int)GoodsEntry::GES_EVER_ACCEPTED + 3 == (int)GoodsEntry::GES_ACCEPTED_BIGTICK); - return GB(ge->status, GoodsEntry::GES_EVER_ACCEPTED, 4); - } + case 0x65: return ge->status.Test(GoodsEntry::State::Acceptance) ? (1U << 3) : 0; + case 0x69: return ge->ConvertState(); } } @@ -462,7 +471,7 @@ uint32_t Station::GetNewGRFVariable(const ResolverObject &object, uint8_t variab const GoodsEntry *g = &this->goods[GB(variable - 0x8C, 3, 4)]; switch (GB(variable - 0x8C, 0, 3)) { case 0: return g->HasData() ? g->GetData().cargo.TotalCount() : 0; - case 1: return GB(g->HasData() ? std::min(g->GetData().cargo.TotalCount(), 4095u) : 0, 0, 4) | (GB(g->status, GoodsEntry::GES_ACCEPTANCE, 1) << 7); + case 1: return GB(g->HasData() ? std::min(g->GetData().cargo.TotalCount(), 4095u) : 0, 0, 4) | (g->status.Test(GoodsEntry::State::Acceptance) ? (1U << 7) : 0); case 2: return g->time_since_pickup; case 3: return g->rating; case 4: return (g->HasData() ? g->GetData().cargo.GetFirstStation() : StationID::Invalid()).base(); diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index 9b23b6cdaa..8d8359f2c0 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -1735,7 +1735,7 @@ bool AfterLoadGame() for (Station *st : Station::Iterate()) { for (GoodsEntry &ge : st->goods) { ge.last_speed = 0; - if (ge.HasData() && ge.GetData().cargo.AvailableCount() != 0) SetBit(ge.status, GoodsEntry::GES_RATING); + if (ge.HasData() && ge.GetData().cargo.AvailableCount() != 0) ge.status.Set(GoodsEntry::State::Rating); } } } diff --git a/src/saveload/oldloader_sl.cpp b/src/saveload/oldloader_sl.cpp index 86069c870f..f6956f49f3 100644 --- a/src/saveload/oldloader_sl.cpp +++ b/src/saveload/oldloader_sl.cpp @@ -724,8 +724,8 @@ static bool LoadOldGood(LoadgameState &ls, int num) if (!LoadChunk(ls, ge, goods_chunk)) return false; - AssignBit(ge->status, GoodsEntry::GES_ACCEPTANCE, HasBit(_waiting_acceptance, 15)); - AssignBit(ge->status, GoodsEntry::GES_RATING, _cargo_source != 0xFF); + ge->status.Set(GoodsEntry::State::Acceptance, HasBit(_waiting_acceptance, 15)); + ge->status.Set(GoodsEntry::State::Rating, _cargo_source != 0xFF); if (GB(_waiting_acceptance, 0, 12) != 0 && CargoPacket::CanAllocateItem()) { ge->GetOrCreateData().cargo.Append(new CargoPacket(GB(_waiting_acceptance, 0, 12), _cargo_periods, (_cargo_source == 0xFF) ? StationID::Invalid() : StationID{_cargo_source}, INVALID_TILE, 0), StationID::Invalid()); diff --git a/src/saveload/station_sl.cpp b/src/saveload/station_sl.cpp index 2c69be5e33..15356140ea 100644 --- a/src/saveload/station_sl.cpp +++ b/src/saveload/station_sl.cpp @@ -414,7 +414,7 @@ public: SwapPackets(&ge); } if (IsSavegameVersionBefore(SLV_68)) { - AssignBit(ge.status, GoodsEntry::GES_ACCEPTANCE, HasBit(_waiting_acceptance, 15)); + ge.status.Set(GoodsEntry::State::Acceptance, HasBit(_waiting_acceptance, 15)); if (GB(_waiting_acceptance, 0, 12) != 0) { /* In old versions, enroute_from used 0xFF as StationID::Invalid() */ StationID source = (IsSavegameVersionBefore(SLV_7) && _cargo_source == 0xFF) ? StationID::Invalid() : static_cast(_cargo_source); @@ -428,7 +428,7 @@ public: /* Don't construct the packet with station here, because that'll fail with old savegames */ CargoPacket *cp = new CargoPacket(GB(_waiting_acceptance, 0, 12), _cargo_periods, source, TileIndex{_cargo_source_xy}, _cargo_feeder_share); ge.GetOrCreateData().cargo.Append(cp, StationID::Invalid()); - SetBit(ge.status, GoodsEntry::GES_RATING); + ge.status.Set(GoodsEntry::State::Rating); } } } diff --git a/src/script/api/script_cargolist.cpp b/src/script/api/script_cargolist.cpp index 28c929b071..6744911cfb 100644 --- a/src/script/api/script_cargolist.cpp +++ b/src/script/api/script_cargolist.cpp @@ -54,6 +54,6 @@ ScriptCargoList_StationAccepting::ScriptCargoList_StationAccepting(StationID sta const Station *st = ::Station::Get(station_id); for (CargoType cargo = 0; cargo < NUM_CARGO; ++cargo) { - if (HasBit(st->goods[cargo].status, GoodsEntry::GES_ACCEPTANCE)) this->AddItem(cargo); + if (st->goods[cargo].status.Test(GoodsEntry::State::Acceptance)) this->AddItem(cargo); } } diff --git a/src/station_base.h b/src/station_base.h index 3fcdbabcf7..91189baa49 100644 --- a/src/station_base.h +++ b/src/station_base.h @@ -165,12 +165,12 @@ public: */ struct GoodsEntry { /** Status of this cargo for the station. */ - enum GoodsEntryStatus : uint8_t { + enum class State : uint8_t { /** * Set when the station accepts the cargo currently for final deliveries. * It is updated every STATION_ACCEPTANCE_TICKS ticks by checking surrounding tiles for acceptance >= 8/8. */ - GES_ACCEPTANCE, + Acceptance = 0, /** * This indicates whether a cargo has a rating at the station. @@ -180,32 +180,33 @@ struct GoodsEntry { * * This flag is cleared after 255 * STATION_RATING_TICKS of not having seen a pickup. */ - GES_RATING, + Rating = 1, /** * Set when a vehicle ever delivered cargo to the station for final delivery. * This flag is never cleared. */ - GES_EVER_ACCEPTED, + EverAccepted = 2, /** * Set when cargo was delivered for final delivery last month. - * This flag is set to the value of GES_CURRENT_MONTH at the start of each month. + * This flag is set to the value of State::CurrentMonth at the start of each month. */ - GES_LAST_MONTH, + LastMonth = 3, /** * Set when cargo was delivered for final delivery this month. * This flag is reset on the beginning of every month. */ - GES_CURRENT_MONTH, + CurrentMonth = 4, /** * Set when cargo was delivered for final delivery during the current STATION_ACCEPTANCE_TICKS interval. * This flag is reset every STATION_ACCEPTANCE_TICKS ticks. */ - GES_ACCEPTED_BIGTICK, + AcceptedBigtick = 5, }; + using States = EnumBitSet; struct GoodsEntryData { StationCargoList cargo{}; ///< The cargo packets of cargo waiting in this station @@ -221,7 +222,7 @@ struct GoodsEntry { NodeID node = INVALID_NODE; ///< ID of node in link graph referring to this goods entry. LinkGraphID link_graph = LinkGraphID::Invalid(); ///< Link graph this station belongs to. - uint8_t status = 0; ///< Status of this cargo, see #GoodsEntryStatus. + States status{}; ///< Status of this cargo, see #State. /** * Number of rating-intervals (up to 255) since the last vehicle tried to load this cargo. @@ -253,7 +254,7 @@ struct GoodsEntry { /** * Reports whether a vehicle has ever tried to load the cargo at this station. - * This does not imply that there was cargo available for loading. Refer to GES_RATING for that. + * This does not imply that there was cargo available for loading. Refer to GoodsEntry::State::Rating for that. * @return true if vehicle tried to load. */ bool HasVehicleEverTriedLoading() const { return this->last_speed != 0; } @@ -264,7 +265,7 @@ struct GoodsEntry { */ inline bool HasRating() const { - return HasBit(this->status, GES_RATING); + return this->status.Test(GoodsEntry::State::Rating); } /** @@ -339,6 +340,8 @@ struct GoodsEntry { return *this->data; } + uint8_t ConvertState() const; + private: std::unique_ptr data = nullptr; ///< Optional cargo packet and flow data. }; diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index ec66070e84..bad22a65d6 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -501,7 +501,7 @@ CargoTypes GetAcceptanceMask(const Station *st) CargoTypes mask = 0; for (auto it = std::begin(st->goods); it != std::end(st->goods); ++it) { - if (HasBit(it->status, GoodsEntry::GES_ACCEPTANCE)) SetBit(mask, std::distance(std::begin(st->goods), it)); + if (it->status.Test(GoodsEntry::State::Acceptance)) SetBit(mask, std::distance(std::begin(st->goods), it)); } return mask; } @@ -641,7 +641,7 @@ void UpdateStationAcceptance(Station *st, bool show_msg) } GoodsEntry &ge = st->goods[cargo]; - SB(ge.status, GoodsEntry::GES_ACCEPTANCE, 1, amt >= 8); + ge.status.Set(GoodsEntry::State::Acceptance, amt >= 8); if (LinkGraph::IsValidID(ge.link_graph)) { (*LinkGraph::Get(ge.link_graph))[ge.node].SetDemand(amt / 8); } @@ -3753,7 +3753,7 @@ void TriggerWatchedCargoCallbacks(Station *st) /* Collect cargoes accepted since the last big tick. */ CargoTypes cargoes = 0; for (CargoType cargo_type = 0; cargo_type < NUM_CARGO; cargo_type++) { - if (HasBit(st->goods[cargo_type].status, GoodsEntry::GES_ACCEPTED_BIGTICK)) SetBit(cargoes, cargo_type); + if (st->goods[cargo_type].status.Test(GoodsEntry::State::AcceptedBigtick)) SetBit(cargoes, cargo_type); } /* Anything to do? */ @@ -3785,7 +3785,7 @@ static bool StationHandleBigTick(BaseStation *st) TriggerWatchedCargoCallbacks(Station::From(st)); for (GoodsEntry &ge : Station::From(st)->goods) { - ClrBit(ge.status, GoodsEntry::GES_ACCEPTED_BIGTICK); + ge.status.Reset(GoodsEntry::State::AcceptedBigtick); } } @@ -3845,7 +3845,7 @@ static void UpdateStationRating(Station *st) if (ge->HasRating()) { byte_inc_sat(&ge->time_since_pickup); if (ge->time_since_pickup == 255 && _settings_game.order.selectgoods) { - ClrBit(ge->status, GoodsEntry::GES_RATING); + ge->status.Reset(GoodsEntry::State::Rating); ge->last_speed = 0; TruncateCargo(cs, ge); waiting_changed = true; @@ -4222,8 +4222,8 @@ static IntervalTimer _economy_stations_monthly({TimerGameEcono { for (Station *st : Station::Iterate()) { for (GoodsEntry &ge : st->goods) { - SB(ge.status, GoodsEntry::GES_LAST_MONTH, 1, GB(ge.status, GoodsEntry::GES_CURRENT_MONTH, 1)); - ClrBit(ge.status, GoodsEntry::GES_CURRENT_MONTH); + ge.status.Set(GoodsEntry::State::LastMonth, ge.status.Test(GoodsEntry::State::CurrentMonth)); + ge.status.Reset(GoodsEntry::State::CurrentMonth); } } }); @@ -4233,7 +4233,7 @@ void ModifyStationRatingAround(TileIndex tile, Owner owner, int amount, uint rad ForAllStationsRadius(tile, radius, [&](Station *st) { if (st->owner == owner && DistanceManhattan(tile, st->xy) <= radius) { for (GoodsEntry &ge : st->goods) { - if (ge.status != 0) { + if (ge.status.Any()) { ge.rating = ClampTo(ge.rating + amount); } } @@ -4274,7 +4274,7 @@ static uint UpdateStationWaiting(Station *st, CargoType cargo, uint amount, Sour if (!ge.HasRating()) { InvalidateWindowData(WC_STATION_LIST, st->owner); - SetBit(ge.status, GoodsEntry::GES_RATING); + ge.status.Set(GoodsEntry::State::Rating); } TriggerStationRandomisation(st, st->xy, SRT_NEW_CARGO, cargo);