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

This commit is contained in:
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;
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)

View File

@ -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());
}
}

View File

@ -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++;
}

View File

@ -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 */

View File

@ -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;
}
/**
* 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 @@ 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 */

View File

@ -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;
}

View File

@ -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++;

View File

@ -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;
}
}

View File

@ -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 */

View File

@ -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;
}
}

View File

@ -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);