1
0
Fork 0

(svn r16852) -Codechange: use FOR_ALL_CARGOSPECS for iterating over all valid CargoSpecs

release/1.0
smatz 2009-07-16 20:40:06 +00:00
parent 665fa7f9c1
commit 77d13eae61
11 changed files with 100 additions and 86 deletions

View File

@ -46,7 +46,7 @@
{ {
if (!IsValidCargo(cargo_type)) return TE_NONE; 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) /* static */ Money AICargo::GetCargoIncome(CargoID cargo_type, uint32 distance, uint32 days_in_transit)

View File

@ -10,11 +10,9 @@
AICargoList::AICargoList() AICargoList::AICargoList()
{ {
for (byte i = 0; i < NUM_CARGO; i++) { const CargoSpec *cs;
const CargoSpec *c = ::CargoSpec::Get(i); FOR_ALL_CARGOSPECS(cs) {
if (c->IsValid()) { this->AddItem(cs->Index());
this->AddItem(i);
}
} }
} }

View File

@ -820,11 +820,10 @@ struct BuildVehicleWindow : Window {
} }
/* Collect available cargo types for filtering */ /* Collect available cargo types for filtering */
for (CargoID cid = 0; cid < NUM_CARGO; cid++) { const CargoSpec *cargo;
const CargoSpec *cargo = CargoSpec::Get(cid); FOR_ALL_CARGOSPECS(cargo) {
if (!cargo->IsValid()) continue; if (IsCargoInClass(cargo->Index(), CC_SPECIAL)) continue; // exclude fake cargo types
if (IsCargoInClass(cid, CC_SPECIAL)) continue; // exclude fake cargo types this->cargo_filter[filter_items] = cargo->Index();
this->cargo_filter[filter_items] = cid;
this->cargo_filter_texts[filter_items] = cargo->name; this->cargo_filter_texts[filter_items] = cargo->name;
filter_items++; filter_items++;
} }

View File

@ -11,7 +11,7 @@
#include "table/strings.h" #include "table/strings.h"
#include "table/cargo_const.h" #include "table/cargo_const.h"
CargoSpec CargoSpec::cargo[NUM_CARGO]; CargoSpec CargoSpec::array[NUM_CARGO];
/* Bitmask of cargo types available */ /* Bitmask of cargo types available */
uint32 _cargo_mask; uint32 _cargo_mask;
@ -22,8 +22,8 @@ void SetupCargoForClimate(LandscapeID l)
assert(l < lengthof(_default_climate_cargo)); assert(l < lengthof(_default_climate_cargo));
/* Reset and disable all cargo types */ /* Reset and disable all cargo types */
memset(CargoSpec::cargo, 0, sizeof(CargoSpec::cargo)); memset(CargoSpec::array, 0, sizeof(CargoSpec::array));
for (CargoID i = 0; i < lengthof(CargoSpec::cargo); i++) CargoSpec::Get(i)->bitnum = INVALID_CARGO; for (CargoID i = 0; i < lengthof(CargoSpec::array); i++) CargoSpec::Get(i)->bitnum = INVALID_CARGO;
_cargo_mask = 0; _cargo_mask = 0;
@ -56,10 +56,9 @@ void SetupCargoForClimate(LandscapeID l)
CargoID GetCargoIDByLabel(CargoLabel cl) CargoID GetCargoIDByLabel(CargoLabel cl)
{ {
for (CargoID c = 0; c < lengthof(CargoSpec::cargo); c++) { CargoSpec *cs;
CargoSpec *cargo = CargoSpec::Get(c); FOR_ALL_CARGOSPECS(cs) {
if (cargo->bitnum == INVALID_CARGO) continue; if (cs->label == cl) return cs->Index();
if (cargo->label == cl) return c;
} }
/* No matching label was found, so it is invalid */ /* No matching label was found, so it is invalid */
@ -75,8 +74,9 @@ CargoID GetCargoIDByBitnum(uint8 bitnum)
{ {
if (bitnum == INVALID_CARGO) return CT_INVALID; if (bitnum == INVALID_CARGO) return CT_INVALID;
for (CargoID c = 0; c < lengthof(CargoSpec::cargo); c++) { CargoSpec *cs;
if (CargoSpec::Get(c)->bitnum == bitnum) return c; FOR_ALL_CARGOSPECS(cs) {
if (cs->bitnum == bitnum) return cs->Index();
} }
/* No matching label was found, so it is invalid */ /* No matching label was found, so it is invalid */

View File

@ -50,28 +50,49 @@ struct CargoSpec {
const struct GRFFile *grffile; ///< NewGRF where 'group' belongs to const struct GRFFile *grffile; ///< NewGRF where 'group' belongs to
const struct SpriteGroup *group; 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; return this->bitnum != INVALID_CARGO;
} }
/** /**
* Retrieve cargo details for the given cargo ID * Total number of subsidies, both valid and invalid
* @param c ID of cargo * @return length of Subsidy::array
* @pre c is a valid cargo ID
*/ */
static CargoSpec *Get(CargoID c) static FORCEINLINE size_t GetArraySize()
{ {
assert(c < lengthof(CargoSpec::cargo)); return lengthof(CargoSpec::array);
return &CargoSpec::cargo[c]; }
/**
* 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: private:
static CargoSpec cargo[NUM_CARGO]; static CargoSpec array[NUM_CARGO];
friend void SetupCargoForClimate(LandscapeID l); friend void SetupCargoForClimate(LandscapeID l);
friend CargoID GetCargoIDByLabel(CargoLabel cl);
friend CargoID GetCargoIDByBitnum(uint8 bitnum);
}; };
extern uint32 _cargo_mask; extern uint32 _cargo_mask;
@ -89,4 +110,8 @@ static inline bool IsCargoInClass(CargoID c, uint16 cc)
return (CargoSpec::Get(c)->classes & cc) != 0; 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 */ #endif /* CARGOTYPE_H */

View File

@ -832,10 +832,9 @@ void ResetEconomy()
/* Test if resetting the economy is needed. */ /* Test if resetting the economy is needed. */
bool needed = false; bool needed = false;
for (CargoID c = 0; c < NUM_CARGO; c++) { const CargoSpec *cs;
const CargoSpec *cs = CargoSpec::Get(c); FOR_ALL_CARGOSPECS(cs) {
if (!cs->IsValid()) continue; if (_cargo_payment_rates[cs->Index()] == 0) {
if (_cargo_payment_rates[c] == 0) {
needed = true; needed = true;
break; break;
} }

View File

@ -736,8 +736,9 @@ struct PaymentRatesGraphWindow : BaseGraphWindow {
BaseGraphWindow(desc, window_number, 2, 24, 200, false, STR_CURRCOMPACT) BaseGraphWindow(desc, window_number, 2, 24, 200, false, STR_CURRCOMPACT)
{ {
uint num_active = 0; uint num_active = 0;
for (CargoID c = 0; c < NUM_CARGO; c++) { const CargoSpec *cs;
if (CargoSpec::Get(c)->IsValid()) num_active++; FOR_ALL_CARGOSPECS(cs) {
num_active++;
} }
/* Resize the window to fit the cargo types */ /* Resize the window to fit the cargo types */
@ -786,10 +787,9 @@ struct PaymentRatesGraphWindow : BaseGraphWindow {
int y = 24; int y = 24;
uint i = 0; 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 /* Only draw labels for widgets that exist. If the widget doesn't
* exist then the local company has used the climate cheat or * exist then the local company has used the climate cheat or
* changed the NewGRF configuration with this window open. */ * changed the NewGRF configuration with this window open. */
@ -809,7 +809,7 @@ struct PaymentRatesGraphWindow : BaseGraphWindow {
this->colours[i] = cs->legend_colour; this->colours[i] = cs->legend_colour;
for (uint j = 0; j != 20; j++) { 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++; i++;

View File

@ -132,8 +132,11 @@ void InitializeLandscapeVariables(bool only_constants)
{ {
if (only_constants) return; if (only_constants) return;
for (CargoID i = 0; i < NUM_CARGO; i++) { memset(_cargo_payment_rates, 0, sizeof(_cargo_payment_rates));
_cargo_payment_rates[i] = CargoSpec::Get(i)->initial_payment; memset(_cargo_payment_rates_frac, 0, sizeof(_cargo_payment_rates_frac));
_cargo_payment_rates_frac[i] = 0;
const CargoSpec *cs;
FOR_ALL_CARGOSPECS(cs) {
_cargo_payment_rates[cs->Index()] = cs->initial_payment;
} }
} }

View File

@ -2994,13 +2994,11 @@ static CargoID TranslateCargo(uint8 feature, uint8 ctype)
return CT_INVALID; return CT_INVALID;
} }
for (CargoID c = 0; c < NUM_CARGO; c++) { const CargoSpec *cs;
const CargoSpec *cs = CargoSpec::Get(c); FOR_ALL_CARGOSPECS(cs) {
if (!cs->IsValid()) continue;
if (cs->bitnum == ctype) { if (cs->bitnum == ctype) {
grfmsg(6, "TranslateCargo: Cargo bitnum %d mapped to cargo type %d.", ctype, c); grfmsg(6, "TranslateCargo: Cargo bitnum %d mapped to cargo type %d.", ctype, cs->Index());
return c; return cs->Index();
} }
} }
@ -5698,21 +5696,19 @@ static void CalculateRefitMasks()
} }
} else { } else {
/* No cargo table, so use the cargo bitnum values */ /* No cargo table, so use the cargo bitnum values */
for (CargoID c = 0; c < NUM_CARGO; c++) { const CargoSpec *cs;
const CargoSpec *cs = CargoSpec::Get(c); FOR_ALL_CARGOSPECS(cs) {
if (!cs->IsValid()) continue; if (HasBit(ei->refit_mask, cs->bitnum)) SetBit(xor_mask, cs->Index());
if (HasBit(ei->refit_mask, cs->bitnum)) SetBit(xor_mask, c);
} }
} }
} }
if (_gted[engine].cargo_allowed != 0) { if (_gted[engine].cargo_allowed != 0) {
/* Build up the list of cargo types from the set cargo classes. */ /* Build up the list of cargo types from the set cargo classes. */
for (CargoID i = 0; i < NUM_CARGO; i++) { const CargoSpec *cs;
const CargoSpec *cs = CargoSpec::Get(i); FOR_ALL_CARGOSPECS(cs) {
if (_gted[engine].cargo_allowed & cs->classes) SetBit(mask, i); if (_gted[engine].cargo_allowed & cs->classes) SetBit(mask, cs->Index());
if (_gted[engine].cargo_disallowed & cs->classes) SetBit(not_mask, i); if (_gted[engine].cargo_disallowed & cs->classes) SetBit(not_mask, cs->Index());
} }
} else if (xor_mask == 0) { } else if (xor_mask == 0) {
/* Don't apply default refit mask to wagons or engines with no capacity */ /* Don't apply default refit mask to wagons or engines with no capacity */

View File

@ -610,11 +610,11 @@ static const SpriteGroup *ResolveStation(ResolverObject *object)
ctype = CT_PURCHASE; ctype = CT_PURCHASE;
} else { } else {
/* Pick the first cargo that we have waiting */ /* Pick the first cargo that we have waiting */
for (CargoID cargo = 0; cargo < NUM_CARGO; cargo++) { const CargoSpec *cs;
const CargoSpec *cs = CargoSpec::Get(cargo); FOR_ALL_CARGOSPECS(cs) {
if (cs->IsValid() && object->u.station.statspec->spritegroup[cargo] != NULL && if (object->u.station.statspec->spritegroup[cs->Index()] != NULL &&
!object->u.station.st->goods[cargo].cargo.Empty()) { !object->u.station.st->goods[cs->Index()].cargo.Empty()) {
ctype = cargo; ctype = cs->Index();
break; break;
} }
} }

View File

@ -257,8 +257,9 @@ public:
/* Add cargo filter buttons */ /* Add cargo filter buttons */
uint num_active = 0; uint num_active = 0;
for (CargoID c = 0; c < NUM_CARGO; c++) { const CargoSpec *cs;
if (CargoSpec::Get(c)->IsValid()) num_active++; FOR_ALL_CARGOSPECS(cs) {
num_active++;
} }
this->widget_count += num_active; this->widget_count += num_active;
@ -266,9 +267,7 @@ public:
this->widget[this->widget_count].type = WWT_LAST; this->widget[this->widget_count].type = WWT_LAST;
uint i = 0; uint i = 0;
for (CargoID c = 0; c < NUM_CARGO; c++) { FOR_ALL_CARGOSPECS(cs) {
if (!CargoSpec::Get(c)->IsValid()) continue;
Widget *wi = &this->widget[SLW_CARGOSTART + i]; Widget *wi = &this->widget[SLW_CARGOSTART + i];
wi->type = WWT_PANEL; wi->type = WWT_PANEL;
wi->display_flags = RESIZE_NONE; wi->display_flags = RESIZE_NONE;
@ -280,7 +279,7 @@ public:
wi->data = 0; wi->data = 0;
wi->tooltips = STR_USE_CTRL_TO_SELECT_MORE; 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++; i++;
} }
@ -345,11 +344,9 @@ public:
int xb = 2; ///< offset from left of widget int xb = 2; ///< offset from left of widget
uint i = 0; uint i = 0;
for (CargoID c = 0; c < NUM_CARGO; c++) { const CargoSpec *cs;
const CargoSpec *cs = CargoSpec::Get(c); FOR_ALL_CARGOSPECS(cs) {
if (!cs->IsValid()) continue; cg_ofst = HasBit(this->cargo_filter, cs->Index()) ? 2 : 1;
cg_ofst = HasBit(this->cargo_filter, c) ? 2 : 1;
GfxFillRect(x + cg_ofst, y + cg_ofst, x + cg_ofst + 10 , y + cg_ofst + 7, cs->rating_colour); 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); DrawString(x + cg_ofst, x + 12 + cg_ofst, y + cg_ofst, cs->abbrev, TC_BLACK, SA_CENTER);
x += 14; x += 14;
@ -456,8 +453,8 @@ public:
case SLW_CARGOALL: { case SLW_CARGOALL: {
uint i = 0; uint i = 0;
for (CargoID c = 0; c < NUM_CARGO; c++) { const CargoSpec *cs;
if (!CargoSpec::Get(c)->IsValid()) continue; FOR_ALL_CARGOSPECS(cs) {
this->LowerWidget(i + SLW_CARGOSTART); this->LowerWidget(i + SLW_CARGOSTART);
i++; i++;
} }
@ -504,16 +501,15 @@ public:
default: default:
if (widget >= SLW_CARGOSTART) { // change cargo_filter if (widget >= SLW_CARGOSTART) { // change cargo_filter
/* Determine the selected cargo type */ /* Determine the selected cargo type */
CargoID c;
int i = 0; int i = 0;
for (c = 0; c < NUM_CARGO; c++) { const CargoSpec *cs;
if (!CargoSpec::Get(c)->IsValid()) continue; FOR_ALL_CARGOSPECS(cs) {
if (widget - SLW_CARGOSTART == i) break; if (widget - SLW_CARGOSTART == i) break;
i++; i++;
} }
if (_ctrl_pressed) { if (_ctrl_pressed) {
ToggleBit(this->cargo_filter, c); ToggleBit(this->cargo_filter, cs->Index());
this->ToggleWidgetLoweredState(widget); this->ToggleWidgetLoweredState(widget);
} else { } else {
for (uint i = SLW_CARGOSTART; i < this->widget_count; i++) { for (uint i = SLW_CARGOSTART; i < this->widget_count; i++) {
@ -524,7 +520,7 @@ public:
this->cargo_filter = 0; this->cargo_filter = 0;
this->include_empty = false; this->include_empty = false;
SetBit(this->cargo_filter, c); SetBit(this->cargo_filter, cs->Index());
this->LowerWidget(widget); this->LowerWidget(widget);
} }
this->SetWidgetLoweredState(SLW_CARGOALL, this->cargo_filter == _cargo_mask && this->include_empty); 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); DrawString(this->widget[SVW_ACCEPTLIST].left + 2, this->widget[SVW_ACCEPTLIST].right - 2, y, STR_STATION_VIEW_CARGO_RATINGS_TITLE);
y += 10; y += 10;
for (CargoID i = 0; i < NUM_CARGO; i++) { const CargoSpec *cs;
const CargoSpec *cs = CargoSpec::Get(i); FOR_ALL_CARGOSPECS(cs) {
if (!cs->IsValid()) continue; const GoodsEntry *ge = &st->goods[cs->Index()];
const GoodsEntry *ge = &st->goods[i];
if (!HasBit(ge->acceptance_pickup, GoodsEntry::PICKUP)) continue; if (!HasBit(ge->acceptance_pickup, GoodsEntry::PICKUP)) continue;
SetDParam(0, cs->name); SetDParam(0, cs->name);