summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfonsinchen <fonsinchen@openttd.org>2013-11-10 15:18:49 +0000
committerfonsinchen <fonsinchen@openttd.org>2013-11-10 15:18:49 +0000
commit962d6d7e4877b5d1fd8717bb08d79f1d6689a934 (patch)
tree37721d24de5707fdf51ab41017ba94bab6dd30a8
parent9b68e4f8644a2750d537a7cbc474914aea4944ef (diff)
downloadopenttd-962d6d7e4877b5d1fd8717bb08d79f1d6689a934.tar.xz
(svn r25963) -Fix [FS#5758]: Mixtures of old and new flows could create cycles.
-rw-r--r--src/linkgraph/linkgraphjob.cpp6
-rw-r--r--src/station_base.h2
-rw-r--r--src/station_cmd.cpp7
3 files changed, 12 insertions, 3 deletions
diff --git a/src/linkgraph/linkgraphjob.cpp b/src/linkgraph/linkgraphjob.cpp
index b6c1747a2..717a7305d 100644
--- a/src/linkgraph/linkgraphjob.cpp
+++ b/src/linkgraph/linkgraphjob.cpp
@@ -72,7 +72,11 @@ LinkGraphJob::~LinkGraphJob()
st2->goods[this->Cargo()].node != it->first ||
(*lg)[node_id][it->first].LastUpdate() == INVALID_DATE) {
/* Edge has been removed. Delete flows. */
- flows.DeleteFlows(to);
+ StationIDStack erased = flows.DeleteFlows(to);
+ /* Delete old flows for source stations which have been deleted
+ * from the new flows. This avoids flow cycles between old and
+ * new flows. */
+ while (!erased.IsEmpty()) ge.flows.erase(erased.Pop());
} else if ((*lg)[node_id][it->first].LastUnrestrictedUpdate() == INVALID_DATE) {
/* Edge is fully restricted. */
flows.RestrictFlows(to);
diff --git a/src/station_base.h b/src/station_base.h
index 1c3375a26..0e6edc7e0 100644
--- a/src/station_base.h
+++ b/src/station_base.h
@@ -148,7 +148,7 @@ class FlowStatMap : public std::map<StationID, FlowStat> {
public:
void AddFlow(StationID origin, StationID via, uint amount);
void PassOnFlow(StationID origin, StationID via, uint amount);
- void DeleteFlows(StationID via);
+ StationIDStack DeleteFlows(StationID via);
void RestrictFlows(StationID via);
void ReleaseFlows(StationID via);
void FinalizeLocalConsumption(StationID self);
diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp
index 6ed0fbf94..0bed79582 100644
--- a/src/station_cmd.cpp
+++ b/src/station_cmd.cpp
@@ -4352,18 +4352,23 @@ void FlowStatMap::FinalizeLocalConsumption(StationID self)
/**
* Delete all flows at a station for specific cargo and destination.
* @param via Remote station of flows to be deleted.
+ * @return IDs of source stations for which the complete FlowStat, not only a
+ * share, has been erased.
*/
-void FlowStatMap::DeleteFlows(StationID via)
+StationIDStack FlowStatMap::DeleteFlows(StationID via)
{
+ StationIDStack ret;
for (FlowStatMap::iterator f_it = this->begin(); f_it != this->end();) {
FlowStat &s_flows = f_it->second;
s_flows.ChangeShare(via, INT_MIN);
if (s_flows.GetShares()->empty()) {
+ ret.Push(f_it->first);
this->erase(f_it++);
} else {
++f_it;
}
}
+ return ret;
}
/**