changeset 12418:0d8340a4c70e draft

(svn r16852) -Codechange: use FOR_ALL_CARGOSPECS for iterating over all valid CargoSpecs
author smatz <smatz@openttd.org>
date Thu, 16 Jul 2009 20:40:06 +0000
parents be6a9106cca1
children 2ffd2f301bf5
files src/ai/api/ai_cargo.cpp src/ai/api/ai_cargolist.cpp src/build_vehicle_gui.cpp src/cargotype.cpp src/cargotype.h src/economy.cpp src/graph_gui.cpp src/misc.cpp src/newgrf.cpp src/newgrf_station.cpp src/station_gui.cpp
diffstat 11 files changed, 100 insertions(+), 86 deletions(-) [+]
line wrap: on
line diff
--- a/src/ai/api/ai_cargo.cpp
+++ b/src/ai/api/ai_cargo.cpp
@@ -46,7 +46,7 @@
 {
 	if (!IsValidCargo(cargo_type)) return TE_NONE;
 
-	return (AICargo::TownEffect)CargoSpec::Get(cargo_type)->town_effect;
+	return (AICargo::TownEffect)::CargoSpec::Get(cargo_type)->town_effect;
 }
 
 /* static */ Money AICargo::GetCargoIncome(CargoID cargo_type, uint32 distance, uint32 days_in_transit)
--- a/src/ai/api/ai_cargolist.cpp
+++ b/src/ai/api/ai_cargolist.cpp
@@ -10,11 +10,9 @@
 
 AICargoList::AICargoList()
 {
-	for (byte i = 0; i < NUM_CARGO; i++) {
-		const CargoSpec *c = ::CargoSpec::Get(i);
-		if (c->IsValid()) {
-			this->AddItem(i);
-		}
+	const CargoSpec *cs;
+	FOR_ALL_CARGOSPECS(cs) {
+		this->AddItem(cs->Index());
 	}
 }
 
--- a/src/build_vehicle_gui.cpp
+++ b/src/build_vehicle_gui.cpp
@@ -820,11 +820,10 @@
 		}
 
 		/* Collect available cargo types for filtering */
-		for (CargoID cid = 0; cid < NUM_CARGO; cid++) {
-			const CargoSpec *cargo = CargoSpec::Get(cid);
-			if (!cargo->IsValid()) continue;
-			if (IsCargoInClass(cid, CC_SPECIAL)) continue; // exclude fake cargo types
-			this->cargo_filter[filter_items] = cid;
+		const CargoSpec *cargo;
+		FOR_ALL_CARGOSPECS(cargo) {
+			if (IsCargoInClass(cargo->Index(), CC_SPECIAL)) continue; // exclude fake cargo types
+			this->cargo_filter[filter_items] = cargo->Index();
 			this->cargo_filter_texts[filter_items] = cargo->name;
 			filter_items++;
 		}
--- a/src/cargotype.cpp
+++ b/src/cargotype.cpp
@@ -11,7 +11,7 @@
 #include "table/strings.h"
 #include "table/cargo_const.h"
 
-CargoSpec CargoSpec::cargo[NUM_CARGO];
+CargoSpec CargoSpec::array[NUM_CARGO];
 
 /* Bitmask of cargo types available */
 uint32 _cargo_mask;
@@ -22,8 +22,8 @@
 	assert(l < lengthof(_default_climate_cargo));
 
 	/* Reset and disable all cargo types */
-	memset(CargoSpec::cargo, 0, sizeof(CargoSpec::cargo));
-	for (CargoID i = 0; i < lengthof(CargoSpec::cargo); i++) CargoSpec::Get(i)->bitnum = INVALID_CARGO;
+	memset(CargoSpec::array, 0, sizeof(CargoSpec::array));
+	for (CargoID i = 0; i < lengthof(CargoSpec::array); i++) CargoSpec::Get(i)->bitnum = INVALID_CARGO;
 
 	_cargo_mask = 0;
 
@@ -56,10 +56,9 @@
 
 CargoID GetCargoIDByLabel(CargoLabel cl)
 {
-	for (CargoID c = 0; c < lengthof(CargoSpec::cargo); c++) {
-		CargoSpec *cargo = CargoSpec::Get(c);
-		if (cargo->bitnum == INVALID_CARGO) continue;
-		if (cargo->label == cl) return c;
+	CargoSpec *cs;
+	FOR_ALL_CARGOSPECS(cs) {
+		if (cs->label == cl) return cs->Index();
 	}
 
 	/* No matching label was found, so it is invalid */
@@ -75,8 +74,9 @@
 {
 	if (bitnum == INVALID_CARGO) return CT_INVALID;
 
-	for (CargoID c = 0; c < lengthof(CargoSpec::cargo); c++) {
-		if (CargoSpec::Get(c)->bitnum == bitnum) return c;
+	CargoSpec *cs;
+	FOR_ALL_CARGOSPECS(cs) {
+		if (cs->bitnum == bitnum) return cs->Index();
 	}
 
 	/* No matching label was found, so it is invalid */
--- a/src/cargotype.h
+++ b/src/cargotype.h
@@ -50,28 +50,49 @@
 	const struct GRFFile *grffile;   ///< NewGRF where 'group' belongs to
 	const struct SpriteGroup *group;
 
-	bool IsValid() const
+	/**
+	 * Determines index of this cargospec
+	 * @return index (in the CargoSpec::array array)
+	 */
+	FORCEINLINE CargoID Index() const
+	{
+		return this - CargoSpec::array;
+	}
+
+	/**
+	 * Tests for validity of this cargospec
+	 * @return is this cargospec valid?
+	 * @note assert(cs->IsValid()) can be triggered when GRF config is modified
+	 */
+	FORCEINLINE bool IsValid() const
 	{
 		return this->bitnum != INVALID_CARGO;
 	}
 
 	/**
-	 * Retrieve cargo details for the given cargo ID
-	 * @param c ID of cargo
-	 * @pre c is a valid cargo ID
+	 * Total number of subsidies, both valid and invalid
+	 * @return length of Subsidy::array
 	 */
-	static CargoSpec *Get(CargoID c)
+	static FORCEINLINE size_t GetArraySize()
 	{
-		assert(c < lengthof(CargoSpec::cargo));
-		return &CargoSpec::cargo[c];
+		return lengthof(CargoSpec::array);
+	}
+
+	/**
+	 * Retrieve cargo details for the given cargo ID
+	 * @param index ID of cargo
+	 * @pre index is a valid cargo ID
+	 */
+	static FORCEINLINE CargoSpec *Get(size_t index)
+	{
+		assert(index < lengthof(CargoSpec::array));
+		return &CargoSpec::array[index];
 	}
 
 private:
-	static CargoSpec cargo[NUM_CARGO];
+	static CargoSpec array[NUM_CARGO];
 
 	friend void SetupCargoForClimate(LandscapeID l);
-	friend CargoID GetCargoIDByLabel(CargoLabel cl);
-	friend CargoID GetCargoIDByBitnum(uint8 bitnum);
 };
 
 extern uint32 _cargo_mask;
@@ -89,4 +110,8 @@
 	return (CargoSpec::Get(c)->classes & cc) != 0;
 }
 
+#define FOR_ALL_CARGOSPECS_FROM(var, start) for (size_t cargospec_index = start; var = NULL, cargospec_index < CargoSpec::GetArraySize(); cargospec_index++) \
+		if ((var = CargoSpec::Get(cargospec_index))->IsValid())
+#define FOR_ALL_CARGOSPECS(var) FOR_ALL_CARGOSPECS_FROM(var, 0)
+
 #endif /* CARGOTYPE_H */
--- a/src/economy.cpp
+++ b/src/economy.cpp
@@ -832,10 +832,9 @@
 	/* Test if resetting the economy is needed. */
 	bool needed = false;
 
-	for (CargoID c = 0; c < NUM_CARGO; c++) {
-		const CargoSpec *cs = CargoSpec::Get(c);
-		if (!cs->IsValid()) continue;
-		if (_cargo_payment_rates[c] == 0) {
+	const CargoSpec *cs;
+	FOR_ALL_CARGOSPECS(cs) {
+		if (_cargo_payment_rates[cs->Index()] == 0) {
 			needed = true;
 			break;
 		}
--- a/src/graph_gui.cpp
+++ b/src/graph_gui.cpp
@@ -736,8 +736,9 @@
 			BaseGraphWindow(desc, window_number, 2, 24, 200, false, STR_CURRCOMPACT)
 	{
 		uint num_active = 0;
-		for (CargoID c = 0; c < NUM_CARGO; c++) {
-			if (CargoSpec::Get(c)->IsValid()) num_active++;
+		const CargoSpec *cs;
+		FOR_ALL_CARGOSPECS(cs) {
+			num_active++;
 		}
 
 		/* Resize the window to fit the cargo types */
@@ -786,10 +787,9 @@
 		int y = 24;
 
 		uint i = 0;
-		for (CargoID c = 0; c < NUM_CARGO; c++) {
-			const CargoSpec *cs = CargoSpec::Get(c);
-			if (!cs->IsValid()) continue;
 
+		const CargoSpec *cs;
+		FOR_ALL_CARGOSPECS(cs) {
 			/* Only draw labels for widgets that exist. If the widget doesn't
 			 * exist then the local company has used the climate cheat or
 			 * changed the NewGRF configuration with this window open. */
@@ -809,7 +809,7 @@
 
 			this->colours[i] = cs->legend_colour;
 			for (uint j = 0; j != 20; j++) {
-				this->cost[i][j] = GetTransportedGoodsIncome(10, 20, j * 4 + 4, c);
+				this->cost[i][j] = GetTransportedGoodsIncome(10, 20, j * 4 + 4, cs->Index());
 			}
 
 			i++;
--- a/src/misc.cpp
+++ b/src/misc.cpp
@@ -132,8 +132,11 @@
 {
 	if (only_constants) return;
 
-	for (CargoID i = 0; i < NUM_CARGO; i++) {
-		_cargo_payment_rates[i] = CargoSpec::Get(i)->initial_payment;
-		_cargo_payment_rates_frac[i] = 0;
+	memset(_cargo_payment_rates, 0, sizeof(_cargo_payment_rates));
+	memset(_cargo_payment_rates_frac, 0, sizeof(_cargo_payment_rates_frac));
+
+	const CargoSpec *cs;
+	FOR_ALL_CARGOSPECS(cs) {
+		_cargo_payment_rates[cs->Index()] = cs->initial_payment;
 	}
 }
--- a/src/newgrf.cpp
+++ b/src/newgrf.cpp
@@ -2994,13 +2994,11 @@
 			return CT_INVALID;
 		}
 
-		for (CargoID c = 0; c < NUM_CARGO; c++) {
-			const CargoSpec *cs = CargoSpec::Get(c);
-			if (!cs->IsValid()) continue;
-
+		const CargoSpec *cs;
+		FOR_ALL_CARGOSPECS(cs) {
 			if (cs->bitnum == ctype) {
-				grfmsg(6, "TranslateCargo: Cargo bitnum %d mapped to cargo type %d.", ctype, c);
-				return c;
+				grfmsg(6, "TranslateCargo: Cargo bitnum %d mapped to cargo type %d.", ctype, cs->Index());
+				return cs->Index();
 			}
 		}
 
@@ -5698,21 +5696,19 @@
 				}
 			} else {
 				/* No cargo table, so use the cargo bitnum values */
-				for (CargoID c = 0; c < NUM_CARGO; c++) {
-					const CargoSpec *cs = CargoSpec::Get(c);
-					if (!cs->IsValid()) continue;
-
-					if (HasBit(ei->refit_mask, cs->bitnum)) SetBit(xor_mask, c);
+				const CargoSpec *cs;
+				FOR_ALL_CARGOSPECS(cs) {
+					if (HasBit(ei->refit_mask, cs->bitnum)) SetBit(xor_mask, cs->Index());
 				}
 			}
 		}
 
 		if (_gted[engine].cargo_allowed != 0) {
 			/* Build up the list of cargo types from the set cargo classes. */
-			for (CargoID i = 0; i < NUM_CARGO; i++) {
-				const CargoSpec *cs = CargoSpec::Get(i);
-				if (_gted[engine].cargo_allowed    & cs->classes) SetBit(mask,     i);
-				if (_gted[engine].cargo_disallowed & cs->classes) SetBit(not_mask, i);
+			const CargoSpec *cs;
+			FOR_ALL_CARGOSPECS(cs) {
+				if (_gted[engine].cargo_allowed    & cs->classes) SetBit(mask,     cs->Index());
+				if (_gted[engine].cargo_disallowed & cs->classes) SetBit(not_mask, cs->Index());
 			}
 		} else if (xor_mask == 0) {
 			/* Don't apply default refit mask to wagons or engines with no capacity */
--- a/src/newgrf_station.cpp
+++ b/src/newgrf_station.cpp
@@ -610,11 +610,11 @@
 		ctype = CT_PURCHASE;
 	} else {
 		/* Pick the first cargo that we have waiting */
-		for (CargoID cargo = 0; cargo < NUM_CARGO; cargo++) {
-			const CargoSpec *cs = CargoSpec::Get(cargo);
-			if (cs->IsValid() && object->u.station.statspec->spritegroup[cargo] != NULL &&
-					!object->u.station.st->goods[cargo].cargo.Empty()) {
-				ctype = cargo;
+		const CargoSpec *cs;
+		FOR_ALL_CARGOSPECS(cs) {
+			if (object->u.station.statspec->spritegroup[cs->Index()] != NULL &&
+					!object->u.station.st->goods[cs->Index()].cargo.Empty()) {
+				ctype = cs->Index();
 				break;
 			}
 		}
--- a/src/station_gui.cpp
+++ b/src/station_gui.cpp
@@ -257,8 +257,9 @@
 
 		/* Add cargo filter buttons */
 		uint num_active = 0;
-		for (CargoID c = 0; c < NUM_CARGO; c++) {
-			if (CargoSpec::Get(c)->IsValid()) num_active++;
+		const CargoSpec *cs;
+		FOR_ALL_CARGOSPECS(cs) {
+			num_active++;
 		}
 
 		this->widget_count += num_active;
@@ -266,9 +267,7 @@
 		this->widget[this->widget_count].type = WWT_LAST;
 
 		uint i = 0;
-		for (CargoID c = 0; c < NUM_CARGO; c++) {
-			if (!CargoSpec::Get(c)->IsValid()) continue;
-
+		FOR_ALL_CARGOSPECS(cs) {
 			Widget *wi = &this->widget[SLW_CARGOSTART + i];
 			wi->type     = WWT_PANEL;
 			wi->display_flags = RESIZE_NONE;
@@ -280,7 +279,7 @@
 			wi->data     = 0;
 			wi->tooltips = STR_USE_CTRL_TO_SELECT_MORE;
 
-			if (HasBit(this->cargo_filter, c)) this->LowerWidget(SLW_CARGOSTART + i);
+			if (HasBit(this->cargo_filter, cs->Index())) this->LowerWidget(SLW_CARGOSTART + i);
 			i++;
 		}
 
@@ -345,11 +344,9 @@
 		int xb = 2; ///< offset from left of widget
 
 		uint i = 0;
-		for (CargoID c = 0; c < NUM_CARGO; c++) {
-			const CargoSpec *cs = CargoSpec::Get(c);
-			if (!cs->IsValid()) continue;
-
-			cg_ofst = HasBit(this->cargo_filter, c) ? 2 : 1;
+		const CargoSpec *cs;
+		FOR_ALL_CARGOSPECS(cs) {
+			cg_ofst = HasBit(this->cargo_filter, cs->Index()) ? 2 : 1;
 			GfxFillRect(x + cg_ofst, y + cg_ofst, x + cg_ofst + 10 , y + cg_ofst + 7, cs->rating_colour);
 			DrawString(x + cg_ofst, x + 12 + cg_ofst, y + cg_ofst, cs->abbrev, TC_BLACK, SA_CENTER);
 			x += 14;
@@ -456,8 +453,8 @@
 
 			case SLW_CARGOALL: {
 				uint i = 0;
-				for (CargoID c = 0; c < NUM_CARGO; c++) {
-					if (!CargoSpec::Get(c)->IsValid()) continue;
+				const CargoSpec *cs;
+				FOR_ALL_CARGOSPECS(cs) {
 					this->LowerWidget(i + SLW_CARGOSTART);
 					i++;
 				}
@@ -504,16 +501,15 @@
 			default:
 				if (widget >= SLW_CARGOSTART) { // change cargo_filter
 					/* Determine the selected cargo type */
-					CargoID c;
 					int i = 0;
-					for (c = 0; c < NUM_CARGO; c++) {
-						if (!CargoSpec::Get(c)->IsValid()) continue;
+					const CargoSpec *cs;
+					FOR_ALL_CARGOSPECS(cs) {
 						if (widget - SLW_CARGOSTART == i) break;
 						i++;
 					}
 
 					if (_ctrl_pressed) {
-						ToggleBit(this->cargo_filter, c);
+						ToggleBit(this->cargo_filter, cs->Index());
 						this->ToggleWidgetLoweredState(widget);
 					} else {
 						for (uint i = SLW_CARGOSTART; i < this->widget_count; i++) {
@@ -524,7 +520,7 @@
 						this->cargo_filter = 0;
 						this->include_empty = false;
 
-						SetBit(this->cargo_filter, c);
+						SetBit(this->cargo_filter, cs->Index());
 						this->LowerWidget(widget);
 					}
 					this->SetWidgetLoweredState(SLW_CARGOALL, this->cargo_filter == _cargo_mask && this->include_empty);
@@ -944,11 +940,9 @@
 			DrawString(this->widget[SVW_ACCEPTLIST].left + 2, this->widget[SVW_ACCEPTLIST].right - 2, y, STR_STATION_VIEW_CARGO_RATINGS_TITLE);
 			y += 10;
 
-			for (CargoID i = 0; i < NUM_CARGO; i++) {
-				const CargoSpec *cs = CargoSpec::Get(i);
-				if (!cs->IsValid()) continue;
-
-				const GoodsEntry *ge = &st->goods[i];
+			const CargoSpec *cs;
+			FOR_ALL_CARGOSPECS(cs) {
+				const GoodsEntry *ge = &st->goods[cs->Index()];
 				if (!HasBit(ge->acceptance_pickup, GoodsEntry::PICKUP)) continue;
 
 				SetDParam(0, cs->name);