diff options
-rw-r--r-- | src/ai/api/ai_cargo.cpp | 2 | ||||
-rw-r--r-- | src/ai/api/ai_cargolist.cpp | 8 | ||||
-rw-r--r-- | src/build_vehicle_gui.cpp | 9 | ||||
-rw-r--r-- | src/cargotype.cpp | 18 | ||||
-rw-r--r-- | src/cargotype.h | 43 | ||||
-rw-r--r-- | src/economy.cpp | 7 | ||||
-rw-r--r-- | src/graph_gui.cpp | 12 | ||||
-rw-r--r-- | src/misc.cpp | 9 | ||||
-rw-r--r-- | src/newgrf.cpp | 26 | ||||
-rw-r--r-- | src/newgrf_station.cpp | 10 | ||||
-rw-r--r-- | src/station_gui.cpp | 40 |
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); |