changeset 20464:857d79b9a5f5 draft

(svn r25424) -Fix: keep old flows around in an invalidated state to continue routing cargo if necessary
author fonsinchen <fonsinchen@openttd.org>
date Mon, 17 Jun 2013 20:38:11 +0000
parents 21a58226882c
children 4778c08d8be1
files src/linkgraph/linkgraphjob.cpp src/station_base.h src/station_cmd.cpp
diffstat 3 files changed, 39 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/linkgraph/linkgraphjob.cpp
+++ b/src/linkgraph/linkgraphjob.cpp
@@ -72,7 +72,19 @@
 			}
 		}
 
-		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());
 	}
 }
--- a/src/station_base.h
+++ b/src/station_base.h
@@ -80,6 +80,13 @@
 	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 @@
 
 	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).
 };
--- a/src/station_cmd.cpp
+++ b/src/station_cmd.cpp
@@ -4086,7 +4086,23 @@
 	}
 	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());
 }
 
 /**