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;
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.
* @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
* evaluation) or if it's not conditional and the caller allows it to be
* chosen (by setting USE_NEXT). */
while (next != nullptr && (!HasBit(flags, USE_NEXT) || next->IsType(OT_CONDITIONAL))) {
* chosen (by setting RefreshFlag::UseNext). */
while (next != nullptr && (!flags.Test(RefreshFlag::UseNext) || next->IsType(OT_CONDITIONAL))) {
/* 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. */
SetBit(flags, USE_NEXT);
flags.Set(RefreshFlag::UseNext);
if (next->IsType(OT_CONDITIONAL)) {
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 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) {
if ((next->IsType(OT_GOTO_DEPOT) || next->IsType(OT_GOTO_STATION)) && next->IsRefit()) {
SetBit(flags, WAS_REFIT);
flags.Set(RefreshFlag::WasRefit);
if (!next->IsAutoRefit()) {
this->HandleRefit(next->GetRefitCargo());
} else if (!HasBit(flags, IN_AUTOREFIT)) {
SetBit(flags, IN_AUTOREFIT);
} else if (!flags.Test(RefreshFlag::InAutorefit)) {
flags.Set(RefreshFlag::InAutorefit);
LinkRefresher backup(*this);
for (CargoType cargo = 0; cargo != NUM_CARGO; ++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,
* meaning that either the vehicle was refit at the previous station or
* it wasn't at all refit during the current hop. */
if (HasBit(flags, WAS_REFIT) && (next->IsType(OT_GOTO_STATION) || next->IsType(OT_IMPLICIT))) {
SetBit(flags, RESET_REFIT);
if (flags.Test(RefreshFlag::WasRefit) && (next->IsType(OT_GOTO_STATION) || next->IsType(OT_IMPLICIT))) {
flags.Set(RefreshFlag::ResetRefit);
} else {
ClrBit(flags, RESET_REFIT);
flags.Reset(RefreshFlag::ResetRefit);
}
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. */
ClrBit(flags, USE_NEXT);
flags.Reset(RefreshFlag::UseNext);
/* 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 (HasBit(flags, RESET_REFIT)) {
if (flags.Test(RefreshFlag::ResetRefit)) {
this->ResetRefit();
ClrBit(flags, RESET_REFIT);
ClrBit(flags, WAS_REFIT);
flags.Reset({RefreshFlag::ResetRefit, RefreshFlag::WasRefit});
}
if (cur->IsType(OT_GOTO_STATION) || cur->IsType(OT_IMPLICIT)) {
if (cur->CanLeaveWithCargo(HasBit(flags, HAS_CARGO))) {
SetBit(flags, HAS_CARGO);
if (cur->CanLeaveWithCargo(flags.Test(RefreshFlag::HasCargo))) {
flags.Set(RefreshFlag::HasCargo);
this->RefreshStats(cur, next);
} 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
* an influence on the next one.
*/
enum RefreshFlags : uint8_t {
USE_NEXT, ///< 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).
WAS_REFIT, ///< 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.
IN_AUTOREFIT, ///< Currently doing an autorefit loop. Ignore the first autorefit order.
enum class RefreshFlag : uint8_t {
UseNext, ///< There was a conditional jump. Try to use the given next order when looking for a new one.
HasCargo, ///< Consist could leave the last stop where it could interact with cargo carrying cargo (i.e. not an "unload all" + "no loading" order).
WasRefit, ///< Consist was refit since the last stop where it could interact with cargo.
ResetRefit, ///< Consist had a chance to load since the last refit and the refit capacities can be reset.
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.
*/
@ -90,9 +92,9 @@ protected:
bool HandleRefit(CargoType refit_cargo);
void ResetRefit();
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 */