1
0
Fork 0

(svn r26889) -Feature: Predict links for station-autorefitting vehicles

release/1.5
fonsinchen 2014-09-21 14:22:32 +00:00
parent 14a599409e
commit 831fb254f6
2 changed files with 26 additions and 16 deletions

View File

@ -81,18 +81,21 @@ LinkRefresher::LinkRefresher(Vehicle *vehicle, HopSet *seen_hops, bool allow_mer
/** /**
* Handle refit orders by updating capacities and refit_capacities. * 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(); RefitList::iterator refit_it = this->refit_capacities.begin();
bool any_refit = false;
for (Vehicle *v = this->vehicle; v != NULL; v = v->Next()) { for (Vehicle *v = this->vehicle; v != NULL; v = v->Next()) {
const Engine *e = Engine::Get(v->engine_type); const Engine *e = Engine::Get(v->engine_type);
if (!HasBit(e->info.refit_mask, this->cargo)) { if (!HasBit(e->info.refit_mask, this->cargo)) {
++refit_it; ++refit_it;
continue; continue;
} }
any_refit = true;
/* Back up the vehicle's cargo type */ /* Back up the vehicle's cargo type */
CargoID temp_cid = v->cargo_type; CargoID temp_cid = v->cargo_type;
@ -130,6 +133,7 @@ void LinkRefresher::HandleRefit(const Order *next)
break; // aircraft have only one vehicle 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) { while (next != NULL) {
/* If the refit cargo is CT_AUTO_REFIT, we're optimistic and assume the if ((next->IsType(OT_GOTO_DEPOT) || next->IsType(OT_GOTO_STATION)) && next->IsRefit()) {
* 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()) {
SetBit(flags, WAS_REFIT); 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, /* Only reset the refit capacities if the "previous" next is a station,

View File

@ -31,10 +31,11 @@ protected:
* an influence on the next one. * an influence on the next one.
*/ */
enum RefreshFlags { enum RefreshFlags {
USE_NEXT, ///< There was a conditional jump. Try to use the given next order when looking for a new one. 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). 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. 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. 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); 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 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 flags, uint num_hops = 0); const Order *PredictNextOrder(const Order *cur, const Order *next, uint8 flags, uint num_hops = 0);