1
0
Fork 0

Codechange: Use EnumBitSet for Linkgraph RefreshFlags. (#13930)

pull/13939/head
Peter Nelson 2025-03-31 20:33:32 +01:00 committed by GitHub
parent 047497734b
commit e200e9b401
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 29 additions and 28 deletions

View File

@ -35,7 +35,7 @@
HopSet seen_hops; HopSet seen_hops;
LinkRefresher refresher(v, &seen_hops, allow_merge, is_full_loading); LinkRefresher refresher(v, &seen_hops, allow_merge, is_full_loading);
refresher.RefreshLinks(first, first, v->last_loading_station != StationID::Invalid() ? 1 << HAS_CARGO : 0); refresher.RefreshLinks(first, first, v->last_loading_station != StationID::Invalid() ? RefreshFlags{RefreshFlag::HasCargo} : RefreshFlags{});
} }
/** /**
@ -158,17 +158,17 @@ void LinkRefresher::ResetRefit()
* @param num_hops Number of hops already taken by recursive calls to this method. * @param num_hops Number of hops already taken by recursive calls to this method.
* @return new next Order. * @return new next Order.
*/ */
const Order *LinkRefresher::PredictNextOrder(const Order *cur, const Order *next, uint8_t flags, uint num_hops) const Order *LinkRefresher::PredictNextOrder(const Order *cur, const Order *next, RefreshFlags flags, uint num_hops)
{ {
/* next is good if it's either nullptr (then the caller will stop the /* next is good if it's either nullptr (then the caller will stop the
* evaluation) or if it's not conditional and the caller allows it to be * evaluation) or if it's not conditional and the caller allows it to be
* chosen (by setting USE_NEXT). */ * chosen (by setting RefreshFlag::UseNext). */
while (next != nullptr && (!HasBit(flags, USE_NEXT) || next->IsType(OT_CONDITIONAL))) { while (next != nullptr && (!flags.Test(RefreshFlag::UseNext) || next->IsType(OT_CONDITIONAL))) {
/* After the first step any further non-conditional order is good, /* After the first step any further non-conditional order is good,
* regardless of previous USE_NEXT settings. The case of cur and next or * regardless of previous RefreshFlag::UseNext settings. The case of cur and next or
* their respective stations being equal is handled elsewhere. */ * their respective stations being equal is handled elsewhere. */
SetBit(flags, USE_NEXT); flags.Set(RefreshFlag::UseNext);
if (next->IsType(OT_CONDITIONAL)) { if (next->IsType(OT_CONDITIONAL)) {
const Order *skip_to = this->vehicle->orders->GetNextDecisionNode( const Order *skip_to = this->vehicle->orders->GetNextDecisionNode(
@ -260,16 +260,16 @@ void LinkRefresher::RefreshStats(const Order *cur, const Order *next)
* @param flags RefreshFlags to give hints about the previous link and state carried over from that. * @param flags RefreshFlags to give hints about the previous link and state carried over from that.
* @param num_hops Number of hops already taken by recursive calls to this method. * @param num_hops Number of hops already taken by recursive calls to this method.
*/ */
void LinkRefresher::RefreshLinks(const Order *cur, const Order *next, uint8_t flags, uint num_hops) void LinkRefresher::RefreshLinks(const Order *cur, const Order *next, RefreshFlags flags, uint num_hops)
{ {
while (next != nullptr) { while (next != nullptr) {
if ((next->IsType(OT_GOTO_DEPOT) || next->IsType(OT_GOTO_STATION)) && next->IsRefit()) { if ((next->IsType(OT_GOTO_DEPOT) || next->IsType(OT_GOTO_STATION)) && next->IsRefit()) {
SetBit(flags, WAS_REFIT); flags.Set(RefreshFlag::WasRefit);
if (!next->IsAutoRefit()) { if (!next->IsAutoRefit()) {
this->HandleRefit(next->GetRefitCargo()); this->HandleRefit(next->GetRefitCargo());
} else if (!HasBit(flags, IN_AUTOREFIT)) { } else if (!flags.Test(RefreshFlag::InAutorefit)) {
SetBit(flags, IN_AUTOREFIT); flags.Set(RefreshFlag::InAutorefit);
LinkRefresher backup(*this); LinkRefresher backup(*this);
for (CargoType cargo = 0; cargo != NUM_CARGO; ++cargo) { for (CargoType cargo = 0; cargo != NUM_CARGO; ++cargo) {
if (CargoSpec::Get(cargo)->IsValid() && this->HandleRefit(cargo)) { if (CargoSpec::Get(cargo)->IsValid() && this->HandleRefit(cargo)) {
@ -283,10 +283,10 @@ void LinkRefresher::RefreshLinks(const Order *cur, const Order *next, uint8_t fl
/* Only reset the refit capacities if the "previous" next is a station, /* Only reset the refit capacities if the "previous" next is a station,
* meaning that either the vehicle was refit at the previous station or * meaning that either the vehicle was refit at the previous station or
* it wasn't at all refit during the current hop. */ * it wasn't at all refit during the current hop. */
if (HasBit(flags, WAS_REFIT) && (next->IsType(OT_GOTO_STATION) || next->IsType(OT_IMPLICIT))) { if (flags.Test(RefreshFlag::WasRefit) && (next->IsType(OT_GOTO_STATION) || next->IsType(OT_IMPLICIT))) {
SetBit(flags, RESET_REFIT); flags.Set(RefreshFlag::ResetRefit);
} else { } else {
ClrBit(flags, RESET_REFIT); flags.Reset(RefreshFlag::ResetRefit);
} }
next = this->PredictNextOrder(cur, next, flags, num_hops); next = this->PredictNextOrder(cur, next, flags, num_hops);
@ -299,23 +299,22 @@ void LinkRefresher::RefreshLinks(const Order *cur, const Order *next, uint8_t fl
} }
/* Don't use the same order again, but choose a new one in the next round. */ /* Don't use the same order again, but choose a new one in the next round. */
ClrBit(flags, USE_NEXT); flags.Reset(RefreshFlag::UseNext);
/* Skip resetting and link refreshing if next order won't do anything with cargo. */ /* Skip resetting and link refreshing if next order won't do anything with cargo. */
if (!next->IsType(OT_GOTO_STATION) && !next->IsType(OT_IMPLICIT)) continue; if (!next->IsType(OT_GOTO_STATION) && !next->IsType(OT_IMPLICIT)) continue;
if (HasBit(flags, RESET_REFIT)) { if (flags.Test(RefreshFlag::ResetRefit)) {
this->ResetRefit(); this->ResetRefit();
ClrBit(flags, RESET_REFIT); flags.Reset({RefreshFlag::ResetRefit, RefreshFlag::WasRefit});
ClrBit(flags, WAS_REFIT);
} }
if (cur->IsType(OT_GOTO_STATION) || cur->IsType(OT_IMPLICIT)) { if (cur->IsType(OT_GOTO_STATION) || cur->IsType(OT_IMPLICIT)) {
if (cur->CanLeaveWithCargo(HasBit(flags, HAS_CARGO))) { if (cur->CanLeaveWithCargo(flags.Test(RefreshFlag::HasCargo))) {
SetBit(flags, HAS_CARGO); flags.Set(RefreshFlag::HasCargo);
this->RefreshStats(cur, next); this->RefreshStats(cur, next);
} else { } else {
ClrBit(flags, HAS_CARGO); flags.Reset(RefreshFlag::HasCargo);
} }
} }

View File

@ -25,14 +25,16 @@ protected:
* Various flags about properties of the last examined link that might have * Various flags about properties of the last examined link that might have
* an influence on the next one. * an influence on the next one.
*/ */
enum RefreshFlags : uint8_t { enum class RefreshFlag : uint8_t {
USE_NEXT, ///< There was a conditional jump. Try to use the given next order when looking for a new one. UseNext, ///< There was a conditional jump. Try to use the given next order when looking for a new one.
HAS_CARGO, ///< Consist could leave the last stop where it could interact with cargo carrying cargo (i.e. not an "unload all" + "no loading" order). HasCargo, ///< Consist could leave the last stop where it could interact with cargo carrying cargo (i.e. not an "unload all" + "no loading" order).
WAS_REFIT, ///< Consist was refit since the last stop where it could interact with cargo. WasRefit, ///< Consist was refit since the last stop where it could interact with cargo.
RESET_REFIT, ///< Consist had a chance to load since the last refit and the refit capacities can be reset. ResetRefit, ///< Consist had a chance to load since the last refit and the refit capacities can be reset.
IN_AUTOREFIT, ///< Currently doing an autorefit loop. Ignore the first autorefit order. InAutorefit, ///< Currently doing an autorefit loop. Ignore the first autorefit order.
}; };
using RefreshFlags = EnumBitSet<RefreshFlag, uint8_t>;
/** /**
* Simulated cargo type and capacity for prediction of future links. * Simulated cargo type and capacity for prediction of future links.
*/ */
@ -90,9 +92,9 @@ protected:
bool HandleRefit(CargoType refit_cargo); bool HandleRefit(CargoType refit_cargo);
void ResetRefit(); void ResetRefit();
void RefreshStats(const Order *cur, const Order *next); void RefreshStats(const Order *cur, const Order *next);
const Order *PredictNextOrder(const Order *cur, const Order *next, uint8_t flags, uint num_hops = 0); const Order *PredictNextOrder(const Order *cur, const Order *next, RefreshFlags flags, uint num_hops = 0);
void RefreshLinks(const Order *cur, const Order *next, uint8_t flags, uint num_hops = 0); void RefreshLinks(const Order *cur, const Order *next, RefreshFlags flags, uint num_hops = 0);
}; };
#endif /* REFRESH_H */ #endif /* REFRESH_H */