From 77f27e08049c4428e2ef0d2a5feff5c26bfc4b32 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Tue, 9 Apr 2024 17:54:43 +0100 Subject: [PATCH] Change: Expose NewGRF classes and specs as spans and simplify iteration. This replaces some index-based loops with range loops. --- src/airport_gui.cpp | 20 +++++++++----------- src/newgrf_class.h | 12 ++++++++++++ src/newgrf_roadstop.cpp | 13 ++++++------- src/object_gui.cpp | 7 +++---- src/rail_gui.cpp | 14 +++++--------- src/road_gui.cpp | 14 +++++--------- 6 files changed, 40 insertions(+), 40 deletions(-) diff --git a/src/airport_gui.cpp b/src/airport_gui.cpp index a52b876d7c..2d5378e72f 100644 --- a/src/airport_gui.cpp +++ b/src/airport_gui.cpp @@ -241,8 +241,8 @@ class BuildAirportWindow : public PickerWindowBase { { DropDownList list; - for (uint i = 0; i < AirportClass::GetClassCount(); i++) { - list.push_back(MakeDropDownListStringItem(AirportClass::Get((AirportClassID)i)->name, i)); + for (const auto &cls : AirportClass::Classes()) { + list.push_back(MakeDropDownListStringItem(cls.name, cls.Index())); } return list; @@ -322,8 +322,8 @@ public: switch (widget) { case WID_AP_CLASS_DROPDOWN: { Dimension d = {0, 0}; - for (uint i = 0; i < AirportClass::GetClassCount(); i++) { - d = maxdim(d, GetStringBoundingBox(AirportClass::Get((AirportClassID)i)->name)); + for (const auto &cls : AirportClass::Classes()) { + d = maxdim(d, GetStringBoundingBox(cls.name)); } d.width += padding.width; d.height += padding.height; @@ -546,14 +546,12 @@ public: if (change_class) { /* If that fails, select the first available airport * from the first class where airports are available. */ - for (AirportClassID j = APC_BEGIN; j < AirportClass::GetClassCount(); j++) { - AirportClass *apclass = AirportClass::Get(j); - for (uint i = 0; i < apclass->GetSpecCount(); i++) { - const AirportSpec *as = apclass->GetSpec(i); + for (const auto &cls : AirportClass::Classes()) { + for (const auto &as : cls.Specs()) { if (as->IsAvailable()) { - _selected_airport_class = j; - this->vscroll->SetCount(apclass->GetSpecCount()); - this->SelectOtherAirport(i); + _selected_airport_class = cls.Index(); + this->vscroll->SetCount(cls.GetSpecCount()); + this->SelectOtherAirport(as->GetIndex()); return; } } diff --git a/src/newgrf_class.h b/src/newgrf_class.h index cd80d65410..2097a9eaca 100644 --- a/src/newgrf_class.h +++ b/src/newgrf_class.h @@ -38,6 +38,18 @@ public: /* Public constructor as emplace_back needs access. */ 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 Specs() const { return this->spec; } + + /** + * Get read-only span of all classes of this type. + * @return Read-only span of classes. + */ + static std::span const> Classes() { return NewGRFClass::classes; } + void Insert(Tspec *spec); Tid Index() const { return static_cast(std::distance(&*std::cbegin(NewGRFClass::classes), this)); } diff --git a/src/newgrf_roadstop.cpp b/src/newgrf_roadstop.cpp index 482bce1e6a..f45f051dee 100644 --- a/src/newgrf_roadstop.cpp +++ b/src/newgrf_roadstop.cpp @@ -465,13 +465,12 @@ void TriggerRoadStopRandomisation(Station *st, TileIndex tile, RoadStopRandomTri */ bool GetIfNewStopsByType(RoadStopType rs, RoadType roadtype) { - for (uint i = 0; i < RoadStopClass::GetClassCount(); i++) { + for (const auto &cls : RoadStopClass::Classes()) { /* Ignore the waypoint class. */ - if (i == ROADSTOP_CLASS_WAYP) continue; - const RoadStopClass *roadstopclass = RoadStopClass::Get((RoadStopClassID)i); + if (cls.Index() == ROADSTOP_CLASS_WAYP) continue; /* Ignore the default class with only the default station. */ - if (i == ROADSTOP_CLASS_DFLT && roadstopclass->GetSpecCount() == 1) continue; - if (GetIfClassHasNewStopsByType(roadstopclass, rs, roadtype)) return true; + if (cls.Index() == ROADSTOP_CLASS_DFLT && cls.GetSpecCount() == 1) continue; + if (GetIfClassHasNewStopsByType(&cls, rs, roadtype)) return true; } return false; } @@ -485,8 +484,8 @@ bool GetIfNewStopsByType(RoadStopType rs, RoadType roadtype) */ bool GetIfClassHasNewStopsByType(const RoadStopClass *roadstopclass, RoadStopType rs, RoadType roadtype) { - for (uint j = 0; j < roadstopclass->GetSpecCount(); j++) { - if (GetIfStopIsForType(roadstopclass->GetSpec(j), rs, roadtype)) return true; + for (const auto spec : roadstopclass->Specs()) { + if (GetIfStopIsForType(spec, rs, roadtype)) return true; } return false; } diff --git a/src/object_gui.cpp b/src/object_gui.cpp index 7ea9fd37df..9199c55538 100644 --- a/src/object_gui.cpp +++ b/src/object_gui.cpp @@ -145,10 +145,9 @@ public: this->object_classes.clear(); - for (uint i = 0; i < ObjectClass::GetClassCount(); i++) { - ObjectClass *objclass = ObjectClass::Get((ObjectClassID)i); - if (objclass->GetUISpecCount() == 0) continue; // Is this needed here? - object_classes.push_back((ObjectClassID)i); + for (const auto &cls : ObjectClass::Classes()) { + if (cls.GetUISpecCount() == 0) continue; // Is this needed here? + object_classes.push_back(cls.Index()); } this->object_classes.Filter(this->string_filter); diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index a3ebd0843d..d3dfd94db6 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.cpp @@ -1109,15 +1109,11 @@ public: this->station_classes.clear(); - for (uint i = 0; i < StationClass::GetClassCount(); i++) { - StationClassID station_class_id = (StationClassID)i; - if (station_class_id == StationClassID::STAT_CLASS_WAYP) { - // Skip waypoints. - continue; - } - StationClass *station_class = StationClass::Get(station_class_id); - if (station_class->GetUISpecCount() == 0) continue; - station_classes.push_back(station_class_id); + for (const auto &cls : StationClass::Classes()) { + /* Skip waypoints. */ + if (cls.Index() == STAT_CLASS_WAYP) continue; + if (cls.GetUISpecCount() == 0) continue; + station_classes.push_back(cls.Index()); } if (_railstation.newstations) { diff --git a/src/road_gui.cpp b/src/road_gui.cpp index 6bc38298ce..8637c910f1 100644 --- a/src/road_gui.cpp +++ b/src/road_gui.cpp @@ -1201,7 +1201,7 @@ public: this->FinishInitNested(TRANSPORT_ROAD); 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. * Now, set the default road stops as selected. */ _roadstop_gui_settings.roadstop_class = ROADSTOP_CLASS_DFLT; @@ -1264,14 +1264,10 @@ public: this->roadstop_classes.clear(); - for (uint i = 0; i < RoadStopClass::GetClassCount(); i++) { - RoadStopClassID rs_id = (RoadStopClassID)i; - if (rs_id == ROADSTOP_CLASS_WAYP) { - // Skip waypoints. - continue; - } - RoadStopClass *rs_class = RoadStopClass::Get(rs_id); - if (GetIfClassHasNewStopsByType(rs_class, this->roadStopType, _cur_roadtype)) this->roadstop_classes.push_back(rs_id); + for (const auto &cls : RoadStopClass::Classes()) { + /* Skip waypoints. */ + if (cls.Index() == ROADSTOP_CLASS_WAYP) continue; + if (GetIfClassHasNewStopsByType(&cls, this->roadStopType, _cur_roadtype)) this->roadstop_classes.push_back(cls.Index()); } if (this->ShowNewStops()) {