summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfonsinchen <fonsinchen@openttd.org>2013-06-17 20:38:11 +0000
committerfonsinchen <fonsinchen@openttd.org>2013-06-17 20:38:11 +0000
commitf0119308f602c9435c793b95b0fa9af3be3a5296 (patch)
tree63bb3de599615feed1d36dc6c525e32b76476f08
parentb923eb31a8ca78cfc4f7e5be00b5f158edbb7588 (diff)
downloadopenttd-f0119308f602c9435c793b95b0fa9af3be3a5296.tar.xz
(svn r25424) -Fix: keep old flows around in an invalidated state to continue routing cargo if necessary
-rw-r--r--src/linkgraph/linkgraphjob.cpp14
-rw-r--r--src/station_base.h9
-rw-r--r--src/station_cmd.cpp16
3 files changed, 38 insertions, 1 deletions
diff --git a/src/linkgraph/linkgraphjob.cpp b/src/linkgraph/linkgraphjob.cpp
index 2feaa8b92..4f583e04a 100644
--- a/src/linkgraph/linkgraphjob.cpp
+++ b/src/linkgraph/linkgraphjob.cpp
@@ -72,7 +72,19 @@ LinkGraphJob::~LinkGraphJob()
}
}
- ge.flows.swap(flows);
+ /* Swap shares and invalidate ones that are completely deleted. Don't
+ * really delete them as we could then end up with unroutable cargo
+ * somewhere. */
+ for (FlowStatMap::iterator it(ge.flows.begin()); it != ge.flows.end(); ++it) {
+ FlowStatMap::iterator new_it = flows.find(it->first);
+ if (new_it == flows.end()) {
+ it->second.Invalidate();
+ } else {
+ it->second.SwapShares(new_it->second);
+ flows.erase(new_it);
+ }
+ }
+ ge.flows.insert(flows.begin(), flows.end());
InvalidateWindowData(WC_STATION_VIEW, st->index, this->Cargo());
}
}
diff --git a/src/station_base.h b/src/station_base.h
index 1eb5e0422..280df69d7 100644
--- a/src/station_base.h
+++ b/src/station_base.h
@@ -80,6 +80,13 @@ public:
inline const SharesMap *GetShares() const { return &this->shares; }
/**
+ * Swap the shares maps, and thus the content of this FlowStat with the
+ * other one.
+ * @param other FlowStat to swap with.
+ */
+ inline void SwapShares(FlowStat &other) { this->shares.swap(other.shares); }
+
+ /**
* Get a station a package can be routed to. This done by drawing a
* random number between 0 and sum_shares and then looking that up in
* the map with lower_bound. So each share gets selected with a
@@ -94,6 +101,8 @@ public:
StationID GetVia(StationID excluded, StationID excluded2 = INVALID_STATION) const;
+ void Invalidate();
+
private:
SharesMap shares; ///< Shares of flow to be sent via specified station (or consumed locally).
};
diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp
index 44cf45f5a..0ac50d2eb 100644
--- a/src/station_cmd.cpp
+++ b/src/station_cmd.cpp
@@ -4086,7 +4086,23 @@ StationID FlowStat::GetVia(StationID excluded, StationID excluded2) const
}
assert(it3 != this->shares.end());
return it3->second;
+}
+/**
+ * Reduce all flows to minimum capacity so that they don't get in the way of
+ * link usage statistics too much. Keep them around, though, to continue
+ * routing any remaining cargo.
+ */
+void FlowStat::Invalidate()
+{
+ assert(!this->shares.empty());
+ SharesMap new_shares;
+ uint i = 0;
+ for (SharesMap::iterator it(this->shares.begin()); it != this->shares.end(); ++it) {
+ new_shares[++i] = it->second;
+ }
+ this->shares.swap(new_shares);
+ assert(!this->shares.empty());
}
/**