mirror of https://github.com/OpenTTD/OpenTTD.git
(svn r25883) -Fix: Limit recursion and branching in RefreshNextHopsStats more aggressively.
This commit is contained in:
parent
8fff781ca0
commit
338d9861bc
|
@ -2141,8 +2141,9 @@ void Vehicle::ResetRefitCaps()
|
||||||
* @param has_cargo If the consist could leave the last stop where it could
|
* @param has_cargo If the consist could leave the last stop where it could
|
||||||
* interact with cargo carrying cargo
|
* interact with cargo carrying cargo
|
||||||
* (i.e. not an "unload all" + "no loading" order).
|
* (i.e. not an "unload all" + "no loading" order).
|
||||||
|
* @return Total number of hops used.
|
||||||
*/
|
*/
|
||||||
void Vehicle::RefreshNextHopsStats(CapacitiesMap &capacities,
|
uint Vehicle::RefreshNextHopsStats(CapacitiesMap &capacities,
|
||||||
RefitList &refit_capacities, const Order *first, const Order *cur,
|
RefitList &refit_capacities, const Order *first, const Order *cur,
|
||||||
const Order *next, uint hops, bool was_refit, bool has_cargo)
|
const Order *next, uint hops, bool was_refit, bool has_cargo)
|
||||||
{
|
{
|
||||||
|
@ -2211,20 +2212,13 @@ void Vehicle::RefreshNextHopsStats(CapacitiesMap &capacities,
|
||||||
|
|
||||||
/* Resolve conditionals by recursion. */
|
/* Resolve conditionals by recursion. */
|
||||||
do {
|
do {
|
||||||
|
const Order *skip_to = NULL;
|
||||||
if (next->IsType(OT_CONDITIONAL)) {
|
if (next->IsType(OT_CONDITIONAL)) {
|
||||||
const Order *skip_to = this->orders.list->GetNextDecisionNode(
|
skip_to = this->orders.list->GetNextDecisionNode(
|
||||||
this->orders.list->GetOrderAt(next->GetConditionSkipToOrder()),
|
this->orders.list->GetOrderAt(next->GetConditionSkipToOrder()),
|
||||||
hops / 2);
|
hops / 2);
|
||||||
|
|
||||||
if (skip_to != NULL) {
|
|
||||||
/* Make copies of capacity tracking lists. */
|
|
||||||
CapacitiesMap skip_capacities = capacities;
|
|
||||||
RefitList skip_refit_capacities = refit_capacities;
|
|
||||||
this->RefreshNextHopsStats(skip_capacities,
|
|
||||||
skip_refit_capacities, first, cur, skip_to, hops + 1,
|
|
||||||
was_refit, has_cargo);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (skip_first_inc) {
|
if (skip_first_inc) {
|
||||||
/* First incrementation has to be skipped if a "real" next hop,
|
/* First incrementation has to be skipped if a "real" next hop,
|
||||||
* different from cur, was given. */
|
* different from cur, was given. */
|
||||||
|
@ -2237,6 +2231,19 @@ void Vehicle::RefreshNextHopsStats(CapacitiesMap &capacities,
|
||||||
next = this->orders.list->GetNextDecisionNode(
|
next = this->orders.list->GetNextDecisionNode(
|
||||||
this->orders.list->GetNext(next), hops / 2);
|
this->orders.list->GetNext(next), hops / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (skip_to != NULL) {
|
||||||
|
/* Process the linear succession first. Skip_to is likely to
|
||||||
|
* point back to already seen orders. */
|
||||||
|
|
||||||
|
/* Make copies of capacity tracking lists. */
|
||||||
|
CapacitiesMap next_capacities = capacities;
|
||||||
|
RefitList next_refit_capacities = refit_capacities;
|
||||||
|
hops = this->RefreshNextHopsStats(next_capacities,
|
||||||
|
next_refit_capacities, first, cur, next, hops + 1,
|
||||||
|
was_refit, has_cargo);
|
||||||
|
next = skip_to;
|
||||||
|
}
|
||||||
} while (next != NULL && next->IsType(OT_CONDITIONAL));
|
} while (next != NULL && next->IsType(OT_CONDITIONAL));
|
||||||
if (next == NULL) break;
|
if (next == NULL) break;
|
||||||
|
|
||||||
|
@ -2278,6 +2285,7 @@ void Vehicle::RefreshNextHopsStats(CapacitiesMap &capacities,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return hops;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -150,7 +150,7 @@ private:
|
||||||
Vehicle *next_shared; ///< pointer to the next vehicle that shares the order
|
Vehicle *next_shared; ///< pointer to the next vehicle that shares the order
|
||||||
Vehicle *previous_shared; ///< NOSAVE: pointer to the previous vehicle in the shared order chain
|
Vehicle *previous_shared; ///< NOSAVE: pointer to the previous vehicle in the shared order chain
|
||||||
|
|
||||||
void RefreshNextHopsStats(CapacitiesMap &capacities,
|
uint RefreshNextHopsStats(CapacitiesMap &capacities,
|
||||||
RefitList &refit_capacities, const Order *first, const Order *cur,
|
RefitList &refit_capacities, const Order *first, const Order *cur,
|
||||||
const Order *next, uint hops, bool was_refit, bool has_cargo);
|
const Order *next, uint hops, bool was_refit, bool has_cargo);
|
||||||
public:
|
public:
|
||||||
|
|
Loading…
Reference in New Issue