summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ai/api/ai_cargo.cpp2
-rw-r--r--src/ai/api/ai_cargolist.cpp8
-rw-r--r--src/build_vehicle_gui.cpp9
-rw-r--r--src/cargotype.cpp18
-rw-r--r--src/cargotype.h43
-rw-r--r--src/economy.cpp7
-rw-r--r--src/graph_gui.cpp12
-rw-r--r--src/misc.cpp9
-rw-r--r--src/newgrf.cpp26
-rw-r--r--src/newgrf_station.cpp10
-rw-r--r--src/station_gui.cpp40
11 files changed, 99 insertions, 85 deletions
diff --git a/src/ai/api/ai_cargo.cpp b/src/ai/api/ai_cargo.cpp
index 4b1593d26..cf9868e2f 100644
--- 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)
diff --git a/src/ai/api/ai_cargolist.cpp b/src/ai/api/ai_cargolist.cpp
index ebf664dee..b5b04c3ea 100644
--- 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());
}
}
diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp
index 07443475b..bad9aa049 100644
--- a/src/build_vehicle_gui.cpp
+++ b/src/build_vehicle_gui.cpp
@@ -820,11 +820,10 @@ struct BuildVehicleWindow : Window {
}
/* 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++;
}
diff --git a/src/cargotype.cpp b/src/cargotype.cpp
index cf1acb45e..b239b9362 100644
--- 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 @@ void SetupCargoForClimate(LandscapeID l)
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 @@ void SetupCargoForClimate(LandscapeID l)
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 @@ CargoID GetCargoIDByBitnum(uint8 bitnum)
{
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 */
diff --git a/src/cargotype.h b/src/cargotype.h
index d7e1b507c..b6649658f 100644
--- a/src/cargotype.h
+++ b/src/cargotype.h
@@ -50,28 +50,49 @@ struct CargoSpec {
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;
}
/**
+ * Total number of subsidies, both valid and invalid
+ * @return length of Subsidy::array
+ */
+ static FORCEINLINE size_t GetArraySize()
+ {
+ return lengthof(CargoSpec::array);
+ }
+
+ /**
* Retrieve cargo details for the given cargo ID
- * @param c ID of cargo
- * @pre c is a valid cargo ID
+ * @param index ID of cargo
+ * @pre index is a valid cargo ID
*/
- static CargoSpec *Get(CargoID c)
+ static FORCEINLINE CargoSpec *Get(size_t index)
{
- assert(c < lengthof(CargoSpec::cargo));
- return &CargoSpec::cargo[c];
+ 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 @@ static inline bool IsCargoInClass(CargoID c, uint16 cc)
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 */
diff --git a/src/economy.cpp b/src/economy.cpp
index bcd678f31..22425bd22 100644
--- a/src/economy.cpp
+++ b/src/economy.cpp
@@ -832,10 +832,9 @@ void ResetEconomy()
/* 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;
}
diff --git a/src/graph_gui.cpp b/src/graph_gui.cpp
index 19a7713c4..cda256195 100644
--- a/src/graph_gui.cpp
+++ b/src/graph_gui.cpp
@@ -736,8 +736,9 @@ struct PaymentRatesGraphWindow : BaseGraphWindow {
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 @@ struct PaymentRatesGraphWindow : BaseGraphWindow {
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 @@ struct PaymentRatesGraphWindow : BaseGraphWindow {
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++;
diff --git a/src/misc.cpp b/src/misc.cpp
index a211ba4a1..6d010c87f 100644
--- a/src/misc.cpp
+++ b/src/misc.cpp
@@ -132,8 +132,11 @@ void InitializeLandscapeVariables(bool only_constants)
{
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;
}
}
diff --git a/src/newgrf.cpp b/src/newgrf.cpp
index 9fd96ca40..df745c634 100644
--- a/src/newgrf.cpp
+++ b/src/newgrf.cpp
@@ -2994,13 +2994,11 @@ static CargoID TranslateCargo(uint8 feature, uint8 ctype)
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 @@ static void CalculateRefitMasks()
}
} 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 */
diff --git a/src/newgrf_station.cpp b/src/newgrf_station.cpp
index 9b91d83eb..483bf28c3 100644
--- a/src/newgrf_station.cpp
+++ b/src/newgrf_station.cpp
@@ -610,11 +610,11 @@ static const SpriteGroup *ResolveStation(ResolverObject *object)
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;
}
}
diff --git a/src/station_gui.cpp b/src/station_gui.cpp
index 310e2b0dd..f1cfb5b49 100644
--- a/src/station_gui.cpp
+++ b/src/station_gui.cpp
@@ -257,8 +257,9 @@ public:
/* 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 @@ public:
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 @@ public:
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 @@ public:
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 @@ public:
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 @@ public:
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 @@ public:
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 @@ struct StationViewWindow : public Window {
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);