1
0
Fork 0

Codechange: Use EnumBitSet for GoodsEntry status. (#13899)

pull/13901/head
Peter Nelson 2025-03-26 21:22:33 +00:00 committed by GitHub
parent 5331389765
commit 325f7f9767
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 52 additions and 45 deletions

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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? */

View File

@ -53,6 +53,20 @@ template class NewGRFClass<StationSpec, StationClassID, STAT_CLASS_MAX>;
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();

View File

@ -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);
}
}
}

View File

@ -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());

View File

@ -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<StationID>(_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);
}
}
}

View File

@ -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);
}
}

View File

@ -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<State, uint8_t>;
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<GoodsEntryData> data = nullptr; ///< Optional cargo packet and flow data.
};

View File

@ -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<TimerGameEconomy> _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<uint8_t>(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);