From 831fb254f604309a255ea310bc6647cfa9c3fdc9 Mon Sep 17 00:00:00 2001 From: fonsinchen Date: Sun, 21 Sep 2014 14:22:32 +0000 Subject: (svn r26889) -Feature: Predict links for station-autorefitting vehicles --- src/linkgraph/refresh.cpp | 31 ++++++++++++++++++++----------- src/linkgraph/refresh.h | 11 ++++++----- 2 files changed, 26 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/linkgraph/refresh.cpp b/src/linkgraph/refresh.cpp index d2a3bdda1..02f27f40c 100644 --- a/src/linkgraph/refresh.cpp +++ b/src/linkgraph/refresh.cpp @@ -81,18 +81,21 @@ LinkRefresher::LinkRefresher(Vehicle *vehicle, HopSet *seen_hops, bool allow_mer /** * Handle refit orders by updating capacities and refit_capacities. - * @param next Order to be processed. + * @param refit_cargo Cargo to refit to. + * @return True if any vehicle was refit; false if none was. */ -void LinkRefresher::HandleRefit(const Order *next) +bool LinkRefresher::HandleRefit(CargoID refit_cargo) { - this->cargo = next->GetRefitCargo(); + this->cargo = refit_cargo; RefitList::iterator refit_it = this->refit_capacities.begin(); + bool any_refit = false; for (Vehicle *v = this->vehicle; v != NULL; v = v->Next()) { const Engine *e = Engine::Get(v->engine_type); if (!HasBit(e->info.refit_mask, this->cargo)) { ++refit_it; continue; } + any_refit = true; /* Back up the vehicle's cargo type */ CargoID temp_cid = v->cargo_type; @@ -130,6 +133,7 @@ void LinkRefresher::HandleRefit(const Order *next) break; // aircraft have only one vehicle } } + return any_refit; } /** @@ -253,15 +257,20 @@ void LinkRefresher::RefreshLinks(const Order *cur, const Order *next, uint8 flag { while (next != NULL) { - /* If the refit cargo is CT_AUTO_REFIT, we're optimistic and assume the - * cargo will stay the same. The point of this method is to avoid - * deadlocks due to vehicles waiting for cargo that isn't being routed, - * yet. That situation will not occur if the vehicle is actually - * carrying a different cargo in the end. */ - if ((next->IsType(OT_GOTO_DEPOT) || next->IsType(OT_GOTO_STATION)) && - next->IsRefit() && !next->IsAutoRefit()) { + if ((next->IsType(OT_GOTO_DEPOT) || next->IsType(OT_GOTO_STATION)) && next->IsRefit()) { SetBit(flags, WAS_REFIT); - this->HandleRefit(next); + if (!next->IsAutoRefit()) { + this->HandleRefit(next->GetRefitCargo()); + } else if (!HasBit(flags, IN_AUTOREFIT)) { + SetBit(flags, IN_AUTOREFIT); + LinkRefresher backup(*this); + for (CargoID c = 0; c != NUM_CARGO; ++c) { + if (CargoSpec::Get(c)->IsValid() && this->HandleRefit(c)) { + this->RefreshLinks(cur, next, flags, num_hops); + *this = backup; + } + } + } } /* Only reset the refit capacities if the "previous" next is a station, diff --git a/src/linkgraph/refresh.h b/src/linkgraph/refresh.h index eac34266d..7c221bc22 100644 --- a/src/linkgraph/refresh.h +++ b/src/linkgraph/refresh.h @@ -31,10 +31,11 @@ protected: * an influence on the next one. */ enum RefreshFlags { - 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. + 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. }; /** @@ -92,7 +93,7 @@ protected: LinkRefresher(Vehicle *v, HopSet *seen_hops, bool allow_merge, bool is_full_loading); - void HandleRefit(const Order *next); + bool HandleRefit(CargoID refit_cargo); void ResetRefit(); void RefreshStats(const Order *cur, const Order *next); const Order *PredictNextOrder(const Order *cur, const Order *next, uint8 flags, uint num_hops = 0); -- cgit v1.2.3-70-g09d2