Change: Expose NewGRF classes and specs as spans and simplify iteration.

This replaces some index-based loops with range loops.
This commit is contained in:
Peter Nelson 2024-04-09 17:54:43 +01:00 committed by Peter Nelson
parent 052f421327
commit 77f27e0804
6 changed files with 40 additions and 40 deletions

View File

@ -241,8 +241,8 @@ class BuildAirportWindow : public PickerWindowBase {
{ {
DropDownList list; DropDownList list;
for (uint i = 0; i < AirportClass::GetClassCount(); i++) { for (const auto &cls : AirportClass::Classes()) {
list.push_back(MakeDropDownListStringItem(AirportClass::Get((AirportClassID)i)->name, i)); list.push_back(MakeDropDownListStringItem(cls.name, cls.Index()));
} }
return list; return list;
@ -322,8 +322,8 @@ public:
switch (widget) { switch (widget) {
case WID_AP_CLASS_DROPDOWN: { case WID_AP_CLASS_DROPDOWN: {
Dimension d = {0, 0}; Dimension d = {0, 0};
for (uint i = 0; i < AirportClass::GetClassCount(); i++) { for (const auto &cls : AirportClass::Classes()) {
d = maxdim(d, GetStringBoundingBox(AirportClass::Get((AirportClassID)i)->name)); d = maxdim(d, GetStringBoundingBox(cls.name));
} }
d.width += padding.width; d.width += padding.width;
d.height += padding.height; d.height += padding.height;
@ -546,14 +546,12 @@ public:
if (change_class) { if (change_class) {
/* If that fails, select the first available airport /* If that fails, select the first available airport
* from the first class where airports are available. */ * from the first class where airports are available. */
for (AirportClassID j = APC_BEGIN; j < AirportClass::GetClassCount(); j++) { for (const auto &cls : AirportClass::Classes()) {
AirportClass *apclass = AirportClass::Get(j); for (const auto &as : cls.Specs()) {
for (uint i = 0; i < apclass->GetSpecCount(); i++) {
const AirportSpec *as = apclass->GetSpec(i);
if (as->IsAvailable()) { if (as->IsAvailable()) {
_selected_airport_class = j; _selected_airport_class = cls.Index();
this->vscroll->SetCount(apclass->GetSpecCount()); this->vscroll->SetCount(cls.GetSpecCount());
this->SelectOtherAirport(i); this->SelectOtherAirport(as->GetIndex());
return; return;
} }
} }

View File

@ -38,6 +38,18 @@ public:
/* Public constructor as emplace_back needs access. */ /* Public constructor as emplace_back needs access. */
NewGRFClass(uint32_t global_id, StringID name) : global_id(global_id), name(name) { } NewGRFClass(uint32_t global_id, StringID name) : global_id(global_id), name(name) { }
/**
* Get read-only span of specs of this class.
* @return Read-only span of specs.
*/
std::span<Tspec * const> Specs() const { return this->spec; }
/**
* Get read-only span of all classes of this type.
* @return Read-only span of classes.
*/
static std::span<NewGRFClass<Tspec, Tid, Tmax> const> Classes() { return NewGRFClass::classes; }
void Insert(Tspec *spec); void Insert(Tspec *spec);
Tid Index() const { return static_cast<Tid>(std::distance(&*std::cbegin(NewGRFClass::classes), this)); } Tid Index() const { return static_cast<Tid>(std::distance(&*std::cbegin(NewGRFClass::classes), this)); }

View File

@ -465,13 +465,12 @@ void TriggerRoadStopRandomisation(Station *st, TileIndex tile, RoadStopRandomTri
*/ */
bool GetIfNewStopsByType(RoadStopType rs, RoadType roadtype) bool GetIfNewStopsByType(RoadStopType rs, RoadType roadtype)
{ {
for (uint i = 0; i < RoadStopClass::GetClassCount(); i++) { for (const auto &cls : RoadStopClass::Classes()) {
/* Ignore the waypoint class. */ /* Ignore the waypoint class. */
if (i == ROADSTOP_CLASS_WAYP) continue; if (cls.Index() == ROADSTOP_CLASS_WAYP) continue;
const RoadStopClass *roadstopclass = RoadStopClass::Get((RoadStopClassID)i);
/* Ignore the default class with only the default station. */ /* Ignore the default class with only the default station. */
if (i == ROADSTOP_CLASS_DFLT && roadstopclass->GetSpecCount() == 1) continue; if (cls.Index() == ROADSTOP_CLASS_DFLT && cls.GetSpecCount() == 1) continue;
if (GetIfClassHasNewStopsByType(roadstopclass, rs, roadtype)) return true; if (GetIfClassHasNewStopsByType(&cls, rs, roadtype)) return true;
} }
return false; return false;
} }
@ -485,8 +484,8 @@ bool GetIfNewStopsByType(RoadStopType rs, RoadType roadtype)
*/ */
bool GetIfClassHasNewStopsByType(const RoadStopClass *roadstopclass, RoadStopType rs, RoadType roadtype) bool GetIfClassHasNewStopsByType(const RoadStopClass *roadstopclass, RoadStopType rs, RoadType roadtype)
{ {
for (uint j = 0; j < roadstopclass->GetSpecCount(); j++) { for (const auto spec : roadstopclass->Specs()) {
if (GetIfStopIsForType(roadstopclass->GetSpec(j), rs, roadtype)) return true; if (GetIfStopIsForType(spec, rs, roadtype)) return true;
} }
return false; return false;
} }

View File

@ -145,10 +145,9 @@ public:
this->object_classes.clear(); this->object_classes.clear();
for (uint i = 0; i < ObjectClass::GetClassCount(); i++) { for (const auto &cls : ObjectClass::Classes()) {
ObjectClass *objclass = ObjectClass::Get((ObjectClassID)i); if (cls.GetUISpecCount() == 0) continue; // Is this needed here?
if (objclass->GetUISpecCount() == 0) continue; // Is this needed here? object_classes.push_back(cls.Index());
object_classes.push_back((ObjectClassID)i);
} }
this->object_classes.Filter(this->string_filter); this->object_classes.Filter(this->string_filter);

View File

@ -1109,15 +1109,11 @@ public:
this->station_classes.clear(); this->station_classes.clear();
for (uint i = 0; i < StationClass::GetClassCount(); i++) { for (const auto &cls : StationClass::Classes()) {
StationClassID station_class_id = (StationClassID)i; /* Skip waypoints. */
if (station_class_id == StationClassID::STAT_CLASS_WAYP) { if (cls.Index() == STAT_CLASS_WAYP) continue;
// Skip waypoints. if (cls.GetUISpecCount() == 0) continue;
continue; station_classes.push_back(cls.Index());
}
StationClass *station_class = StationClass::Get(station_class_id);
if (station_class->GetUISpecCount() == 0) continue;
station_classes.push_back(station_class_id);
} }
if (_railstation.newstations) { if (_railstation.newstations) {

View File

@ -1201,7 +1201,7 @@ public:
this->FinishInitNested(TRANSPORT_ROAD); this->FinishInitNested(TRANSPORT_ROAD);
this->window_class = (rs == ROADSTOP_BUS) ? WC_BUS_STATION : WC_TRUCK_STATION; this->window_class = (rs == ROADSTOP_BUS) ? WC_BUS_STATION : WC_TRUCK_STATION;
if (!newstops || _roadstop_gui_settings.roadstop_class >= (int)RoadStopClass::GetClassCount()) { if (!newstops || _roadstop_gui_settings.roadstop_class >= RoadStopClass::GetClassCount()) {
/* There's no new stops available or the list has reduced in size. /* There's no new stops available or the list has reduced in size.
* Now, set the default road stops as selected. */ * Now, set the default road stops as selected. */
_roadstop_gui_settings.roadstop_class = ROADSTOP_CLASS_DFLT; _roadstop_gui_settings.roadstop_class = ROADSTOP_CLASS_DFLT;
@ -1264,14 +1264,10 @@ public:
this->roadstop_classes.clear(); this->roadstop_classes.clear();
for (uint i = 0; i < RoadStopClass::GetClassCount(); i++) { for (const auto &cls : RoadStopClass::Classes()) {
RoadStopClassID rs_id = (RoadStopClassID)i; /* Skip waypoints. */
if (rs_id == ROADSTOP_CLASS_WAYP) { if (cls.Index() == ROADSTOP_CLASS_WAYP) continue;
// Skip waypoints. if (GetIfClassHasNewStopsByType(&cls, this->roadStopType, _cur_roadtype)) this->roadstop_classes.push_back(cls.Index());
continue;
}
RoadStopClass *rs_class = RoadStopClass::Get(rs_id);
if (GetIfClassHasNewStopsByType(rs_class, this->roadStopType, _cur_roadtype)) this->roadstop_classes.push_back(rs_id);
} }
if (this->ShowNewStops()) { if (this->ShowNewStops()) {