summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorfonsinchen <fonsinchen@openttd.org>2013-10-22 18:34:10 +0000
committerfonsinchen <fonsinchen@openttd.org>2013-10-22 18:34:10 +0000
commit6e1cc8092696eb73a1932d63c561abd7246eee8e (patch)
tree01407638a8a368de0291732d87e662730e879ac0 /src
parente0f547e694978adc34f3a04e860663f908c486b5 (diff)
downloadopenttd-6e1cc8092696eb73a1932d63c561abd7246eee8e.tar.xz
(svn r25903) -Codechange: Refactor RefreshNextHopsStats into an own class LinkRefresher.
Diffstat (limited to 'src')
-rw-r--r--src/economy.cpp3
-rw-r--r--src/station_cmd.cpp3
-rw-r--r--src/vehicle.cpp200
-rw-r--r--src/vehicle_base.h5
4 files changed, 6 insertions, 205 deletions
diff --git a/src/economy.cpp b/src/economy.cpp
index 270cedc67..076cdbae4 100644
--- a/src/economy.cpp
+++ b/src/economy.cpp
@@ -48,6 +48,7 @@
#include "cargomonitor.h"
#include "goal_base.h"
#include "story_base.h"
+#include "linkgraph/refresh.h"
#include "table/strings.h"
#include "table/pricebase.h"
@@ -1657,7 +1658,7 @@ static void LoadUnloadVehicle(Vehicle *front)
* along them. Otherwise the vehicle could wait for cargo
* indefinitely if it hasn't visited the other links yet, or if the
* links die while it's loading. */
- if (!finished_loading) front->RefreshNextHopsStats();
+ if (!finished_loading) LinkRefresher::Run(front);
}
unloading_time = 20;
diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp
index 9542ea131..423907a8f 100644
--- a/src/station_cmd.cpp
+++ b/src/station_cmd.cpp
@@ -51,6 +51,7 @@
#include "newgrf_house.h"
#include "company_gui.h"
#include "linkgraph/linkgraph_base.h"
+#include "linkgraph/refresh.h"
#include "widgets/station_widget.h"
#include "table/strings.h"
@@ -3446,7 +3447,7 @@ void DeleteStaleLinks(Station *from)
* - We could try to figure out if we've seen a consist with the same cargo on the
* same list already and if the consist can actually carry the cargo we're looking
* for. With conditional and refit orders this is not quite trivial, though. */
- v->RefreshNextHopsStats();
+ LinkRefresher::Run(v);
if (edge.LastUpdate() == _date) updated = true;
}
if (updated) break;
diff --git a/src/vehicle.cpp b/src/vehicle.cpp
index 0abe6689d..9b509404e 100644
--- a/src/vehicle.cpp
+++ b/src/vehicle.cpp
@@ -51,6 +51,7 @@
#include "depot_map.h"
#include "gamelog.h"
#include "linkgraph/linkgraph.h"
+#include "linkgraph/refresh.h"
#include "table/strings.h"
@@ -2087,7 +2088,7 @@ void Vehicle::LeaveStation()
* during the stop and that refit_cap == cargo_cap for each vehicle in
* the consist. */
this->ResetRefitCaps();
- this->RefreshNextHopsStats();
+ LinkRefresher::Run(this);
/* if the vehicle could load here or could stop with cargo loaded set the last loading station */
this->last_loading_station = this->last_station_visited;
@@ -2125,203 +2126,6 @@ void Vehicle::ResetRefitCaps()
}
/**
- * Predict a vehicle's course from its current state and refresh all links it
- * will visit.
- * @param capacities Current added capacities per cargo ID in the consist.
- * @param refit_capacities Current state of capacity remaining from previous
- * refits versus overall capacity per vehicle in the consist.
- * @param first Order that was checked first in the overall run. If this is
- * encountered again the refreshing is considered finished.
- * @param cur Last stop where the consist could interact with cargo.
- * @param next Next order to be checked. This can be the same as \a cur, the
- * next order will then be calculated from \a cur.
- * @param hops Number of hops already used up. If more than two times the
- * number of orders in the list have been checked refreshing is stopped.
- * @param was_refit If the consist was refit since the last stop where it could
- * interact with cargo.
- * @param has_cargo If the consist could leave the last stop where it could
- * interact with cargo carrying cargo
- * (i.e. not an "unload all" + "no loading" order).
- * @return Total number of hops used.
- */
-uint Vehicle::RefreshNextHopsStats(CapacitiesMap &capacities,
- RefitList &refit_capacities, const Order *first, const Order *cur,
- const Order *next, uint hops, bool was_refit, bool has_cargo)
-{
- bool skip_first_inc = (cur != next);
- while (next != NULL) {
-
- /* If the refit cargo is CT_AUTO_REFIT, we're optimistic and assume the
- * cargo will stay the same. The point of this method is to avoid
- * deadlocks due to vehicles waiting for cargo that isn't being routed,
- * yet. That situation will not occur if the vehicle is actually
- * carrying a different cargo in the end. */
- if ((next->IsType(OT_GOTO_DEPOT) || next->IsType(OT_GOTO_STATION)) &&
- next->IsRefit() && !next->IsAutoRefit()) {
- was_refit = true;
- CargoID new_cid = next->GetRefitCargo();
- RefitList::iterator refit_it = refit_capacities.begin();
- for (Vehicle *v = this; v != NULL; v = v->Next()) {
- const Engine *e = Engine::Get(v->engine_type);
- if (!HasBit(e->info.refit_mask, new_cid)) {
- ++refit_it;
- continue;
- }
-
- /* Back up the vehicle's cargo type */
- CargoID temp_cid = v->cargo_type;
- byte temp_subtype = v->cargo_subtype;
- v->cargo_type = new_cid;
- v->cargo_subtype = GetBestFittingSubType(v, v, new_cid);
-
- uint16 mail_capacity = 0;
- uint amount = e->DetermineCapacity(v, &mail_capacity);
-
- /* Restore the original cargo type */
- v->cargo_type = temp_cid;
- v->cargo_subtype = temp_subtype;
-
- /* Skip on next refit. */
- if (new_cid != refit_it->cargo && refit_it->remaining > 0) {
- capacities[refit_it->cargo] -= refit_it->remaining;
- refit_it->remaining = 0;
- } else if (amount < refit_it->remaining) {
- capacities[refit_it->cargo] -= refit_it->remaining - amount;
- refit_it->remaining = amount;
- }
- refit_it->capacity = amount;
- refit_it->cargo = new_cid;
-
- ++refit_it;
-
- /* Special case for aircraft with mail. */
- if (v->type == VEH_AIRCRAFT) {
- if (mail_capacity < refit_it->remaining) {
- capacities[refit_it->cargo] -= refit_it->remaining - mail_capacity;
- refit_it->remaining = mail_capacity;
- }
- refit_it->capacity = mail_capacity;
- break; // aircraft have only one vehicle
- }
- }
- }
-
- /* Only reset the refit capacities if the "previous" next is a station,
- * meaning that either the vehicle was refit at the previous station or
- * it wasn't at all refit during the current hop. */
- bool reset_refit = was_refit && (next->IsType(OT_GOTO_STATION) || next->IsType(OT_IMPLICIT));
-
- /* Resolve conditionals by recursion. */
- do {
- const Order *skip_to = NULL;
- if (next->IsType(OT_CONDITIONAL)) {
- skip_to = this->orders.list->GetNextDecisionNode(
- this->orders.list->GetOrderAt(next->GetConditionSkipToOrder()),
- hops / 2);
- }
-
- if (skip_first_inc) {
- /* First incrementation has to be skipped if a "real" next hop,
- * different from cur, was given. */
- skip_first_inc = false;
- } else {
- ++hops;
- /* Reassign next with the following stop. This can be a station or a
- * depot. Allow the order list to be walked twice so that we can
- * reassign "first" below without afterwards terminating early here. */
- next = this->orders.list->GetNextDecisionNode(
- 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));
- if (next == NULL) break;
-
- if (next->IsType(OT_GOTO_STATION) || next->IsType(OT_IMPLICIT)) {
- if (reset_refit) {
- /* Restore remaining capacities as vehicle might have been able to load now. */
- for (RefitList::iterator it(refit_capacities.begin()); it != refit_capacities.end(); ++it) {
- if (it->remaining == it->capacity) continue;
- capacities[it->cargo] += it->capacity - it->remaining;
- it->remaining = it->capacity;
- }
- reset_refit = false;
- was_refit = false;
- }
-
- if (cur->IsType(OT_GOTO_STATION) || cur->IsType(OT_IMPLICIT)) {
- has_cargo = cur->CanLeaveWithCargo(has_cargo);
- if (has_cargo) {
- StationID next_station = next->GetDestination();
- Station *st = Station::GetIfValid(cur->GetDestination());
- if (st != NULL && next_station != INVALID_STATION && next_station != st->index) {
- for (CapacitiesMap::const_iterator i = capacities.begin(); i != capacities.end(); ++i) {
- /* Refresh the link and give it a minimum capacity. */
- if (i->second > 0) {
- /* A link is at least partly restricted if a
- * vehicle can't load at its source. */
- IncreaseStats(st, i->first, next_station, i->second,
- (cur->GetLoadType() & OLFB_NO_LOAD) == 0 ? LinkGraph::REFRESH_UNRESTRICTED : LinkGraph::REFRESH_RESTRICTED);
- }
- }
- }
- }
- }
-
- /* "cur" is only assigned here if the stop is a station so that
- * whenever stats are to be increased two stations can be found.
- * However, "first" can be a depot stop. If that is the case
- * reassign it to make sure we end up with a station for the last
- * link. */
- cur = next;
- if (cur == first) break;
- if (!first->IsType(OT_GOTO_STATION) && !first->IsType(OT_IMPLICIT)) {
- first = cur;
- }
- }
- }
- return hops;
-}
-
-/**
- * Predict a vehicle's course from its current state and refresh all links it
- * will visit.
- */
-void Vehicle::RefreshNextHopsStats()
-{
- /* Assemble list of capacities and set last loading stations to 0. */
- CapacitiesMap capacities;
- RefitList refit_capacities;
- for (Vehicle *v = this; v != NULL; v = v->Next()) {
- refit_capacities.push_back(RefitDesc(v->cargo_type, v->cargo_cap, v->refit_cap));
- if (v->refit_cap > 0) capacities[v->cargo_type] += v->refit_cap;
- }
-
- /* If orders were deleted while loading, we're done here.*/
- if (this->orders.list == NULL) return;
-
- const Order *first = this->GetOrder(this->cur_implicit_order_index);
-
- /* Make sure the first order is a useful order. */
- first = this->orders.list->GetNextDecisionNode(first, 0);
- if (first == NULL) return;
-
- this->RefreshNextHopsStats(capacities, refit_capacities, first, first,
- first, 0, false, this->last_loading_station != INVALID_STATION);
-}
-
-/**
* Handle the loading of the vehicle; when not it skips through dummy
* orders and does nothing in all other cases.
* @param mode is the non-first call for this vehicle in this tick?
diff --git a/src/vehicle_base.h b/src/vehicle_base.h
index ddd74cec1..4c37847d9 100644
--- a/src/vehicle_base.h
+++ b/src/vehicle_base.h
@@ -150,9 +150,6 @@ private:
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
- uint RefreshNextHopsStats(CapacitiesMap &capacities,
- RefitList &refit_capacities, const Order *first, const Order *cur,
- const Order *next, uint hops, bool was_refit, bool has_cargo);
public:
friend const SaveLoad *GetVehicleDescription(VehicleType vt); ///< So we can use private/protected variables in the saveload code
friend void FixOldVehicles();
@@ -635,8 +632,6 @@ public:
void ResetRefitCaps();
- void RefreshNextHopsStats();
-
/**
* Copy certain configurations and statistics of a vehicle after successful autoreplace/renew
* The function shall copy everything that cannot be copied by a command (like orders / group etc),