|
|
|
@ -3445,6 +3445,7 @@ void RerouteCargo(Station *st, CargoID c, StationID avoid, StationID avoid2)
|
|
|
|
|
void DeleteStaleLinks(Station *from)
|
|
|
|
|
{
|
|
|
|
|
for (CargoID c = 0; c < NUM_CARGO; ++c) {
|
|
|
|
|
const bool auto_distributed = (_settings_game.linkgraph.GetDistributionType(c) != DT_MANUAL);
|
|
|
|
|
GoodsEntry &ge = from->goods[c];
|
|
|
|
|
LinkGraph *lg = LinkGraph::GetIfValid(ge.link_graph);
|
|
|
|
|
if (lg == NULL) continue;
|
|
|
|
@ -3457,47 +3458,50 @@ void DeleteStaleLinks(Station *from)
|
|
|
|
|
assert(_date >= edge.LastUpdate());
|
|
|
|
|
uint timeout = LinkGraph::MIN_TIMEOUT_DISTANCE + (DistanceManhattan(from->xy, to->xy) >> 3);
|
|
|
|
|
if ((uint)(_date - edge.LastUpdate()) > timeout) {
|
|
|
|
|
/* Have all vehicles refresh their next hops before deciding to
|
|
|
|
|
* remove the node. */
|
|
|
|
|
OrderList *l;
|
|
|
|
|
SmallVector<Vehicle *, 32> vehicles;
|
|
|
|
|
FOR_ALL_ORDER_LISTS(l) {
|
|
|
|
|
bool found_from = false;
|
|
|
|
|
bool found_to = false;
|
|
|
|
|
for (Order *order = l->GetFirstOrder(); order != NULL; order = order->next) {
|
|
|
|
|
if (!order->IsType(OT_GOTO_STATION) && !order->IsType(OT_IMPLICIT)) continue;
|
|
|
|
|
if (order->GetDestination() == from->index) {
|
|
|
|
|
found_from = true;
|
|
|
|
|
if (found_to) break;
|
|
|
|
|
} else if (order->GetDestination() == to->index) {
|
|
|
|
|
found_to = true;
|
|
|
|
|
if (found_from) break;
|
|
|
|
|
bool updated = false;
|
|
|
|
|
|
|
|
|
|
if (auto_distributed) {
|
|
|
|
|
/* Have all vehicles refresh their next hops before deciding to
|
|
|
|
|
* remove the node. */
|
|
|
|
|
OrderList *l;
|
|
|
|
|
SmallVector<Vehicle *, 32> vehicles;
|
|
|
|
|
FOR_ALL_ORDER_LISTS(l) {
|
|
|
|
|
bool found_from = false;
|
|
|
|
|
bool found_to = false;
|
|
|
|
|
for (Order *order = l->GetFirstOrder(); order != NULL; order = order->next) {
|
|
|
|
|
if (!order->IsType(OT_GOTO_STATION) && !order->IsType(OT_IMPLICIT)) continue;
|
|
|
|
|
if (order->GetDestination() == from->index) {
|
|
|
|
|
found_from = true;
|
|
|
|
|
if (found_to) break;
|
|
|
|
|
} else if (order->GetDestination() == to->index) {
|
|
|
|
|
found_to = true;
|
|
|
|
|
if (found_from) break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!found_to || !found_from) continue;
|
|
|
|
|
*(vehicles.Append()) = l->GetFirstSharedVehicle();
|
|
|
|
|
}
|
|
|
|
|
if (!found_to || !found_from) continue;
|
|
|
|
|
*(vehicles.Append()) = l->GetFirstSharedVehicle();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool updated = false;
|
|
|
|
|
Vehicle **iter = vehicles.Begin();
|
|
|
|
|
while (iter != vehicles.End()) {
|
|
|
|
|
Vehicle *v = *iter;
|
|
|
|
|
|
|
|
|
|
LinkRefresher::Run(v, false); // Don't allow merging. Otherwise lg might get deleted.
|
|
|
|
|
if (edge.LastUpdate() == _date) {
|
|
|
|
|
updated = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
Vehicle **iter = vehicles.Begin();
|
|
|
|
|
while (iter != vehicles.End()) {
|
|
|
|
|
Vehicle *v = *iter;
|
|
|
|
|
|
|
|
|
|
Vehicle *next_shared = v->NextShared();
|
|
|
|
|
if (next_shared) {
|
|
|
|
|
*iter = next_shared;
|
|
|
|
|
++iter;
|
|
|
|
|
} else {
|
|
|
|
|
vehicles.Erase(iter);
|
|
|
|
|
}
|
|
|
|
|
LinkRefresher::Run(v, false); // Don't allow merging. Otherwise lg might get deleted.
|
|
|
|
|
if (edge.LastUpdate() == _date) {
|
|
|
|
|
updated = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (iter == vehicles.End()) iter = vehicles.Begin();
|
|
|
|
|
Vehicle *next_shared = v->NextShared();
|
|
|
|
|
if (next_shared) {
|
|
|
|
|
*iter = next_shared;
|
|
|
|
|
++iter;
|
|
|
|
|
} else {
|
|
|
|
|
vehicles.Erase(iter);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (iter == vehicles.End()) iter = vehicles.Begin();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!updated) {
|
|
|
|
|