summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorfonsinchen <fonsinchen@openttd.org>2014-09-21 14:22:32 +0000
committerfonsinchen <fonsinchen@openttd.org>2014-09-21 14:22:32 +0000
commit831fb254f604309a255ea310bc6647cfa9c3fdc9 (patch)
tree2893b8190eee553c4f424af8e6852d099dbe174b /src
parent14a599409e2e73b7a31b12f80741baa07fc7502c (diff)
downloadopenttd-831fb254f604309a255ea310bc6647cfa9c3fdc9.tar.xz
(svn r26889) -Feature: Predict links for station-autorefitting vehicles
Diffstat (limited to 'src')
-rw-r--r--src/linkgraph/refresh.cpp31
-rw-r--r--src/linkgraph/refresh.h11
2 files changed, 26 insertions, 16 deletions
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);