changeset 13586:6093f71745bf draft

(svn r18110) -Codechange [FS#3316]: search for stations nearby only once per producer (instead of once pre produced cargo type) (fonsinchen)
author smatz <smatz@openttd.org>
date Sun, 15 Nov 2009 21:06:13 +0000
parents 2d12e2247813
children f5704f568df1
files src/economy_func.h src/industry_cmd.cpp src/station_cmd.cpp src/station_func.h src/station_type.h src/town_cmd.cpp src/unmovable_cmd.cpp
diffstat 7 files changed, 53 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/src/economy_func.h
+++ b/src/economy_func.h
@@ -21,6 +21,7 @@
 #include "industry_type.h"
 #include "company_type.h"
 #include "station_type.h"
+#include "station_func.h"
 
 void ResetPriceBaseMultipliers();
 void SetPriceBaseMultiplier(Price price, int factor);
@@ -35,7 +36,7 @@
 void StartupIndustryDailyChanges(bool init_counter);
 
 Money GetTransportedGoodsIncome(uint num_pieces, uint dist, byte transit_days, CargoID cargo_type);
-uint MoveGoodsToStation(TileIndex tile, int w, int h, CargoID type, uint amount, SourceType source_type, SourceID source_id);
+uint MoveGoodsToStation(CargoID type, uint amount, SourceType source_type, SourceID source_id, const StationList *all_stations);
 
 void PrepareUnload(Vehicle *front_v);
 void LoadUnloadStation(Station *st);
--- a/src/industry_cmd.cpp
+++ b/src/industry_cmd.cpp
@@ -507,6 +507,8 @@
 	const IndustrySpec *indspec = GetIndustrySpec(i->type);
 	bool moved_cargo = false;
 
+	StationFinder stations(i->xy, i->width, i->height);
+
 	for (uint j = 0; j < lengthof(i->produced_cargo_waiting); j++) {
 		uint cw = min(i->produced_cargo_waiting[j], 255);
 		if (cw > indspec->minimal_cargo && i->produced_cargo[j] != CT_INVALID) {
@@ -517,7 +519,7 @@
 
 			i->this_month_production[j] += cw;
 
-			uint am = MoveGoodsToStation(i->xy, i->width, i->height, i->produced_cargo[j], cw, ST_INDUSTRY, i->index);
+			uint am = MoveGoodsToStation(i->produced_cargo[j], cw, ST_INDUSTRY, i->index, stations.GetStations());
 			i->this_month_transported[j] += am;
 
 			moved_cargo |= (am != 0);
--- a/src/station_cmd.cpp
+++ b/src/station_cmd.cpp
@@ -3009,7 +3009,20 @@
 	}
 }
 
-uint MoveGoodsToStation(TileIndex tile, int w, int h, CargoID type, uint amount, SourceType source_type, SourceID source_id)
+/**
+ * Run a tile loop to find stations around a tile, on demand. Cache the result for further requests
+ * @return pointer to a StationList containing all stations found
+ */
+const StationList *StationFinder::GetStations()
+{
+	if (this->tile != INVALID_TILE) {
+		FindStationsAroundTiles(this->tile, this->x_extent, this->y_extent, &this->stations);
+		this->tile = INVALID_TILE;
+	}
+	return &this->stations;
+}
+
+uint MoveGoodsToStation(CargoID type, uint amount, SourceType source_type, SourceID source_id, const StationList *all_stations)
 {
 	/* Return if nothing to do. Also the rounding below fails for 0. */
 	if (amount == 0) return 0;
@@ -3019,9 +3032,7 @@
 	uint best_rating1 = 0; // rating of st1
 	uint best_rating2 = 0; // rating of st2
 
-	StationList all_stations;
-	FindStationsAroundTiles(tile, w, h, &all_stations);
-	for (Station **st_iter = all_stations.Begin(); st_iter != all_stations.End(); ++st_iter) {
+	for (Station * const *st_iter = all_stations->Begin(); st_iter != all_stations->End(); ++st_iter) {
 		Station *st = *st_iter;
 
 		/* Is the station reserved exclusively for somebody else? */
--- a/src/station_func.h
+++ b/src/station_func.h
@@ -19,11 +19,9 @@
 #include "tile_type.h"
 #include "cargo_type.h"
 #include "vehicle_type.h"
-#include "core/smallvec_type.hpp"
 
 void ModifyStationRatingAround(TileIndex tile, Owner owner, int amount, uint radius);
 
-typedef SmallVector<Station*, 1> StationList;
 void FindStationsAroundTiles(TileIndex tile, int w_prod, int h_prod, StationList *stations);
 
 void ShowStationViewWindow(StationID station);
--- a/src/station_type.h
+++ b/src/station_type.h
@@ -13,6 +13,7 @@
 #define STATION_TYPE_H
 
 #include "core/enum_type.hpp"
+#include "core/smallvec_type.hpp"
 #include "tile_type.h"
 
 typedef uint16 StationID;
@@ -115,4 +116,27 @@
 	uint8 h;        ///< The height of the area
 };
 
+/** List of stations */
+typedef SmallVector<Station *, 2> StationList;
+
+/**
+ * Structure contains cached list of stations nearby. The list
+ * is created upon first call to GetStations()
+ */
+class StationFinder {
+	StationList stations; ///< List of stations nearby
+	TileIndex tile;       ///< Northern tile of producer, INVALID_TILE when # stations is valid
+	int x_extent;         ///< Width of producer
+	int y_extent;         ///< Height of producer
+public:
+	/**
+	 * Constructs StationFinder
+	 * @param t northern tile
+	 * @param dx width of producer
+	 * @param dy height of producer
+	 */
+	StationFinder(TileIndex t, int dx, int dy) : tile(t), x_extent(dx), y_extent(dy) {}
+	const StationList *GetStations();
+};
+
 #endif /* STATION_TYPE_H */
--- a/src/town_cmd.cpp
+++ b/src/town_cmd.cpp
@@ -465,6 +465,8 @@
 	Town *t = Town::GetByTile(tile);
 	uint32 r = Random();
 
+	StationFinder stations(tile, 1, 1);
+
 	if (HasBit(hs->callback_mask, CBM_HOUSE_PRODUCE_CARGO)) {
 		for (uint i = 0; i < 256; i++) {
 			uint16 callback = GetHouseCallback(CBID_HOUSE_PRODUCE_CARGO, i, r, house_id, t, tile);
@@ -477,7 +479,7 @@
 			uint amt = GB(callback, 0, 8);
 			if (amt == 0) continue;
 
-			uint moved = MoveGoodsToStation(tile, 1, 1, cargo, amt, ST_TOWN, t->index);
+			uint moved = MoveGoodsToStation(cargo, amt, ST_TOWN, t->index, stations.GetStations());
 
 			const CargoSpec *cs = CargoSpec::Get(cargo);
 			switch (cs->town_effect) {
@@ -501,7 +503,7 @@
 
 			if (_economy.fluct <= 0) amt = (amt + 1) >> 1;
 			t->new_max_pass += amt;
-			t->new_act_pass += MoveGoodsToStation(tile, 1, 1, CT_PASSENGERS, amt, ST_TOWN, t->index);
+			t->new_act_pass += MoveGoodsToStation(CT_PASSENGERS, amt, ST_TOWN, t->index, stations.GetStations());
 		}
 
 		if (GB(r, 8, 8) < hs->mail_generation) {
@@ -509,7 +511,7 @@
 
 			if (_economy.fluct <= 0) amt = (amt + 1) >> 1;
 			t->new_max_mail += amt;
-			t->new_act_mail += MoveGoodsToStation(tile, 1, 1, CT_MAIL, amt, ST_TOWN, t->index);
+			t->new_act_mail += MoveGoodsToStation(CT_MAIL, amt, ST_TOWN, t->index, stations.GetStations());
 		}
 	}
 
--- a/src/unmovable_cmd.cpp
+++ b/src/unmovable_cmd.cpp
@@ -344,12 +344,14 @@
 	uint level = GetCompanyHQSize(tile) + 1;
 	assert(level < 6);
 
+	StationFinder stations(tile, 2, 2);
+
 	uint r = Random();
 	/* Top town buildings generate 250, so the top HQ type makes 256. */
 	if (GB(r, 0, 8) < (256 / 4 / (6 - level))) {
 		uint amt = GB(r, 0, 8) / 8 / 4 + 1;
 		if (_economy.fluct <= 0) amt = (amt + 1) >> 1;
-		MoveGoodsToStation(tile, 2, 2, CT_PASSENGERS, amt, ST_HEADQUARTERS, GetTileOwner(tile));
+		MoveGoodsToStation(CT_PASSENGERS, amt, ST_HEADQUARTERS, GetTileOwner(tile), stations.GetStations());
 	}
 
 	/* Top town building generates 90, HQ can make up to 196. The
@@ -358,7 +360,7 @@
 	if (GB(r, 8, 8) < (196 / 4 / (6 - level))) {
 		uint amt = GB(r, 8, 8) / 8 / 4 + 1;
 		if (_economy.fluct <= 0) amt = (amt + 1) >> 1;
-		MoveGoodsToStation(tile, 2, 2, CT_MAIL, amt, ST_HEADQUARTERS, GetTileOwner(tile));
+		MoveGoodsToStation(CT_MAIL, amt, ST_HEADQUARTERS, GetTileOwner(tile), stations.GetStations());
 	}
 }