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

View File

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

View File

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

View File

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

View File

@ -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()) {