# HG changeset patch # User Peter Nelson # Date 2024-02-27 20:10:06 # Node ID f131debacb19ad18514307e567898bd9b7153e22 # Parent c4b1236c040b9da8543c99058b40e839d874bd5a Codechange: Use `GetVisibleRangeIterators()` in more places. (#12190) This replaces more first/last index calculation, along with indexed array/vector access, with iterator access instead. diff --git a/src/bridge_gui.cpp b/src/bridge_gui.cpp --- a/src/bridge_gui.cpp +++ b/src/bridge_gui.cpp @@ -231,11 +231,11 @@ public: case WID_BBS_BRIDGE_LIST: { Rect tr = r.WithHeight(this->resize.step_height).Shrink(WidgetDimensions::scaled.matrix); bool rtl = _current_text_dir == TD_RTL; - for (int i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < (int)this->bridges.size(); i++) { - const BuildBridgeData &bridge_data = this->bridges.at(i); - const BridgeSpec *b = bridge_data.spec; + auto [first, last] = this->vscroll->GetVisibleRangeIterators(this->bridges); + for (auto it = first; it != last; ++it) { + const BridgeSpec *b = it->spec; DrawSpriteIgnorePadding(b->sprite, b->pal, tr.WithWidth(this->icon_width, rtl), SA_HOR_CENTER | SA_BOTTOM); - DrawStringMultiLine(tr.Indent(this->icon_width + WidgetDimensions::scaled.hsep_normal, rtl), GetBridgeSelectString(bridge_data)); + DrawStringMultiLine(tr.Indent(this->icon_width + WidgetDimensions::scaled.hsep_normal, rtl), GetBridgeSelectString(*it)); tr = tr.Translate(0, this->resize.step_height); } break; diff --git a/src/fios_gui.cpp b/src/fios_gui.cpp --- a/src/fios_gui.cpp +++ b/src/fios_gui.cpp @@ -441,8 +441,8 @@ public: GfxFillRect(br, PC_BLACK); Rect tr = r.Shrink(WidgetDimensions::scaled.inset).WithHeight(this->resize.step_height); - uint scroll_pos = this->vscroll->GetPosition(); - for (auto it = this->display_list.begin() + scroll_pos; it != this->display_list.end() && tr.top < br.bottom; ++it) { + auto [first, last] = this->vscroll->GetVisibleRangeIterators(this->display_list); + for (auto it = first; it != last; ++it) { const FiosItem *item = *it; if (item == this->selected) { diff --git a/src/graph_gui.cpp b/src/graph_gui.cpp --- a/src/graph_gui.cpp +++ b/src/graph_gui.cpp @@ -1023,13 +1023,11 @@ struct PaymentRatesGraphWindow : BaseGra bool rtl = _current_text_dir == TD_RTL; - int pos = this->vscroll->GetPosition(); - int max = pos + this->vscroll->GetCapacity(); + auto [first, last] = this->vscroll->GetVisibleRangeIterators(_sorted_standard_cargo_specs); Rect line = r.WithHeight(this->line_height); - for (const CargoSpec *cs : _sorted_standard_cargo_specs) { - if (pos-- > 0) continue; - if (--max < 0) break; + for (auto it = first; it != last; ++it) { + const CargoSpec *cs = *it; bool lowered = !HasBit(_legend_excluded_cargo, cs->Index()); diff --git a/src/group_gui.cpp b/src/group_gui.cpp --- a/src/group_gui.cpp +++ b/src/group_gui.cpp @@ -626,9 +626,9 @@ public: if (this->vli.index != ALL_GROUP && this->grouping == GB_NONE) { /* Mark vehicles which are in sub-groups (only if we are not using shared order coalescing) */ Rect mr = r.WithHeight(this->resize.step_height); - size_t max = std::min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), this->vehgroups.size()); - for (size_t i = this->vscroll->GetPosition(); i < max; ++i) { - const Vehicle *v = this->vehgroups[i].GetSingleVehicle(); + auto [first, last] = this->vscroll->GetVisibleRangeIterators(this->vehgroups); + for (auto it = first; it != last; ++it) { + const Vehicle *v = it->GetSingleVehicle(); if (v->group_id != this->vli.index) { GfxFillRect(mr.Shrink(WidgetDimensions::scaled.bevel), GetColourGradient(COLOUR_GREY, SHADE_DARK), FILLRECT_CHECKER); } diff --git a/src/industry_gui.cpp b/src/industry_gui.cpp --- a/src/industry_gui.cpp +++ b/src/industry_gui.cpp @@ -528,8 +528,9 @@ public: icon.top = r.top + (this->resize.step_height - this->legend.height + 1) / 2; icon.bottom = icon.top + this->legend.height - 1; - for (uint16_t i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < this->vscroll->GetCount(); i++) { - IndustryType type = this->list[i]; + auto [first, last] = this->vscroll->GetVisibleRangeIterators(this->list); + for (auto it = first; it != last; ++it) { + IndustryType type = *it; bool selected = this->selected_type == type; const IndustrySpec *indsp = GetIndustrySpec(type); @@ -1699,20 +1700,19 @@ public: DrawString(ir, STR_INDUSTRY_DIRECTORY_NONE); break; } - int n = 0; const CargoID acf_cid = this->accepted_cargo_filter_criteria; - for (uint i = this->vscroll->GetPosition(); i < this->industries.size(); i++) { + auto [first, last] = this->vscroll->GetVisibleRangeIterators(this->industries); + for (auto it = first; it != last; ++it) { TextColour tc = TC_FROMSTRING; if (acf_cid != CargoFilterCriteria::CF_ANY && acf_cid != CargoFilterCriteria::CF_NONE) { - Industry *ind = const_cast(this->industries[i]); + Industry *ind = const_cast(*it); if (IndustryTemporarilyRefusesCargo(ind, acf_cid)) { tc = TC_GREY | TC_FORCED; } } - DrawString(ir, this->GetIndustryString(this->industries[i]), tc); + DrawString(ir, this->GetIndustryString(*it), tc); ir.top += this->resize.step_height; - if (++n == this->vscroll->GetCapacity()) break; // max number of industries in 1 window } break; } diff --git a/src/network/network_content_gui.cpp b/src/network/network_content_gui.cpp --- a/src/network/network_content_gui.cpp +++ b/src/network/network_content_gui.cpp @@ -652,11 +652,8 @@ public: int text_y_offset = (this->resize.step_height - GetCharacterHeight(FS_NORMAL)) / 2; Rect mr = r.WithHeight(this->resize.step_height); - auto iter = this->content.begin() + this->vscroll->GetPosition(); - size_t last = this->vscroll->GetPosition() + this->vscroll->GetCapacity(); - auto end = (last < this->content.size()) ? this->content.begin() + last : this->content.end(); - - for (/**/; iter != end; iter++) { + auto [first, last] = this->vscroll->GetVisibleRangeIterators(this->content); + for (auto iter = first; iter != last; iter++) { const ContentInfo *ci = *iter; if (ci == this->selected) GfxFillRect(mr.Shrink(WidgetDimensions::scaled.bevel), PC_GREY); diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -527,10 +527,9 @@ public: case WID_NG_MATRIX: { uint16_t y = r.top; - const int max = std::min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), (int)this->servers.size()); - - for (int i = this->vscroll->GetPosition(); i < max; ++i) { - const NetworkGameList *ngl = this->servers[i]; + auto [first, last] = this->vscroll->GetVisibleRangeIterators(this->servers); + for (auto it = first; it != last; ++it) { + const NetworkGameList *ngl = *it; this->DrawServerLine(ngl, y, ngl == this->server); y += this->resize.step_height; } diff --git a/src/newgrf_debug_gui.cpp b/src/newgrf_debug_gui.cpp --- a/src/newgrf_debug_gui.cpp +++ b/src/newgrf_debug_gui.cpp @@ -933,13 +933,13 @@ struct SpriteAlignerWindow : Window { const NWidgetBase *nwid = this->GetWidget(widget); int step_size = nwid->resize_y; - std::vector &list = _newgrf_debug_sprite_picker.sprites; - int max = std::min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), (uint)list.size()); + const std::vector &list = _newgrf_debug_sprite_picker.sprites; Rect ir = r.Shrink(WidgetDimensions::scaled.matrix); - for (int i = this->vscroll->GetPosition(); i < max; i++) { - SetDParam(0, list[i]); - DrawString(ir, STR_JUST_COMMA, list[i] == this->current_sprite ? TC_WHITE : TC_BLACK, SA_RIGHT | SA_FORCE); + auto [first, last] = this->vscroll->GetVisibleRangeIterators(list); + for (auto it = first; it != last; ++it) { + SetDParam(0, *it); + DrawString(ir, STR_JUST_COMMA, *it == this->current_sprite ? TC_WHITE : TC_BLACK, SA_RIGHT | SA_FORCE); ir.top += step_size; } break; diff --git a/src/newgrf_gui.cpp b/src/newgrf_gui.cpp --- a/src/newgrf_gui.cpp +++ b/src/newgrf_gui.cpp @@ -909,11 +909,10 @@ struct NewGRFWindow : public Window, New Rect tr = r.Shrink(WidgetDimensions::scaled.framerect); uint step_height = this->GetWidget(WID_NS_AVAIL_LIST)->resize_y; int offset_y = (step_height - GetCharacterHeight(FS_NORMAL)) / 2; - uint min_index = this->vscroll2->GetPosition(); - uint max_index = std::min(min_index + this->vscroll2->GetCapacity(), (uint)this->avails.size()); - for (uint i = min_index; i < max_index; i++) { - const GRFConfig *c = this->avails[i]; + auto [first, last] = this->vscroll2->GetVisibleRangeIterators(this->avails); + for (auto it = first; it != last; ++it) { + const GRFConfig *c = *it; bool h = (c == this->avail_sel); const char *text = c->GetName(); @@ -2127,13 +2126,13 @@ struct SavePresetWindow : public Window uint step_height = this->GetWidget(WID_SVP_PRESET_LIST)->resize_y; int offset_y = (step_height - GetCharacterHeight(FS_NORMAL)) / 2; Rect tr = r.Shrink(WidgetDimensions::scaled.framerect); - uint min_index = this->vscroll->GetPosition(); - uint max_index = std::min(min_index + this->vscroll->GetCapacity(), (uint)this->presets.size()); - for (uint i = min_index; i < max_index; i++) { - if ((int)i == this->selected) GfxFillRect(br.left, tr.top, br.right, tr.top + step_height - 1, PC_DARK_BLUE); + auto [first, last] = this->vscroll->GetVisibleRangeIterators(this->presets); + for (auto it = first; it != last; ++it) { + int row = static_cast(std::distance(std::begin(this->presets), it)); + if (row == this->selected) GfxFillRect(br.left, tr.top, br.right, tr.top + step_height - 1, PC_DARK_BLUE); - DrawString(tr.left, tr.right, tr.top + offset_y, this->presets[i], ((int)i == this->selected) ? TC_WHITE : TC_SILVER); + DrawString(tr.left, tr.right, tr.top + offset_y, *it, (row == this->selected) ? TC_WHITE : TC_SILVER); tr.top += step_height; } break; diff --git a/src/script/script_gui.cpp b/src/script/script_gui.cpp --- a/src/script/script_gui.cpp +++ b/src/script/script_gui.cpp @@ -927,7 +927,7 @@ struct ScriptDebugWindow : public Window { if (this->filter.script_debug_company == INVALID_COMPANY) return; - ScriptLogTypes::LogData &log = this->GetLogData(); + const ScriptLogTypes::LogData &log = this->GetLogData(); if (log.empty()) return; Rect fr = r.Shrink(WidgetDimensions::scaled.framerect); @@ -943,8 +943,9 @@ struct ScriptDebugWindow : public Window fr.left -= this->hscroll->GetPosition(); - for (int i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && (size_t)i < log.size(); i++) { - const ScriptLogTypes::LogLine &line = log[i]; + auto [first, last] = this->vscroll->GetVisibleRangeIterators(log); + for (auto it = first; it != last; ++it) { + const ScriptLogTypes::LogLine &line = *it; TextColour colour; switch (line.type) { @@ -957,7 +958,7 @@ struct ScriptDebugWindow : public Window } /* Check if the current line should be highlighted */ - if (i == this->highlight_row) { + if (std::distance(std::begin(log), it) == this->highlight_row) { fr.bottom = fr.top + this->resize.step_height - 1; GfxFillRect(fr, PC_BLACK); if (colour == TC_BLACK) colour = TC_WHITE; // Make black text readable by inverting it to white. diff --git a/src/signs_gui.cpp b/src/signs_gui.cpp --- a/src/signs_gui.cpp +++ b/src/signs_gui.cpp @@ -211,9 +211,9 @@ struct SignListWindow : Window, SignList tr = tr.Indent(this->text_offset, rtl); /* At least one sign available. */ - for (uint16_t i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < this->vscroll->GetCount(); i++) - { - const Sign *si = this->signs[i]; + auto [first, last] = this->vscroll->GetVisibleRangeIterators(this->signs); + for (auto it = first; it != last; ++it) { + const Sign *si = *it; if (si->owner != OWNER_NONE) DrawCompanyIcon(si->owner, icon_left, tr.top + sprite_offset_y); diff --git a/src/station_gui.cpp b/src/station_gui.cpp --- a/src/station_gui.cpp +++ b/src/station_gui.cpp @@ -455,7 +455,6 @@ public: case WID_STL_LIST: { bool rtl = _current_text_dir == TD_RTL; - size_t max = std::min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), this->stations.size()); Rect tr = r.Shrink(WidgetDimensions::scaled.framerect); uint line_height = this->GetWidget(widget)->resize_y; /* Spacing between station name and first rating graph. */ @@ -463,8 +462,9 @@ public: /* Spacing between additional rating graphs. */ int rating_spacing = WidgetDimensions::scaled.hsep_normal; - for (size_t i = this->vscroll->GetPosition(); i < max; ++i) { // do until max number of stations of owner - const Station *st = this->stations[i]; + auto [first, last] = this->vscroll->GetVisibleRangeIterators(this->stations); + for (auto it = first; it != last; ++it) { + const Station *st = *it; assert(st->xy != INVALID_TILE); /* Do not do the complex check HasStationInUse here, it may be even false @@ -2320,11 +2320,12 @@ struct SelectStationWindow : Window { if (widget != WID_JS_PANEL) return; Rect tr = r.Shrink(WidgetDimensions::scaled.framerect); - for (uint i = this->vscroll->GetPosition(); i < _stations_nearby_list.size(); ++i, tr.top += this->resize.step_height) { - if (_stations_nearby_list[i] == NEW_STATION) { + auto [first, last] = this->vscroll->GetVisibleRangeIterators(_stations_nearby_list); + for (auto it = first; it != last; ++it, tr.top += this->resize.step_height) { + if (*it == NEW_STATION) { DrawString(tr, T::EXPECTED_FACIL == FACIL_WAYPOINT ? STR_JOIN_WAYPOINT_CREATE_SPLITTED_WAYPOINT : STR_JOIN_STATION_CREATE_SPLITTED_STATION); } else { - const T *st = T::Get(_stations_nearby_list[i]); + const T *st = T::Get(*it); SetDParam(0, st->index); SetDParam(1, st->facilities); DrawString(tr, T::EXPECTED_FACIL == FACIL_WAYPOINT ? STR_STATION_LIST_WAYPOINT : STR_STATION_LIST_STATION); diff --git a/src/town_gui.cpp b/src/town_gui.cpp --- a/src/town_gui.cpp +++ b/src/town_gui.cpp @@ -840,7 +840,6 @@ public: break; case WID_TD_LIST: { - int n = 0; Rect tr = r.Shrink(WidgetDimensions::scaled.framerect); if (this->towns.empty()) { // No towns available. DrawString(tr, STR_TOWN_DIRECTORY_NONE); @@ -853,8 +852,9 @@ public: int icon_x = tr.WithWidth(icon_size.width, rtl).left; tr = tr.Indent(icon_size.width + WidgetDimensions::scaled.hsep_normal, rtl); - for (uint i = this->vscroll->GetPosition(); i < this->towns.size(); i++) { - const Town *t = this->towns[i]; + auto [first, last] = this->vscroll->GetVisibleRangeIterators(this->towns); + for (auto it = first; it != last; ++it) { + const Town *t = *it; assert(t->xy != INVALID_TILE); /* Draw rating icon. */ @@ -872,7 +872,6 @@ public: DrawString(tr.left, tr.right, tr.top + (this->resize.step_height - GetCharacterHeight(FS_NORMAL)) / 2, GetTownString(t)); tr.top += this->resize.step_height; - if (++n == this->vscroll->GetCapacity()) break; // max number of towns in 1 window } break; } diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -1704,10 +1704,9 @@ void BaseVehicleListWindow::DrawVehicleL int vehicle_button_x = rtl ? ir.right - profit.width : ir.left; - uint max = static_cast(std::min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), this->vehgroups.size())); - for (uint i = this->vscroll->GetPosition(); i < max; ++i) { - - const GUIVehicleGroup &vehgroup = this->vehgroups[i]; + auto [first, last] = this->vscroll->GetVisibleRangeIterators(this->vehgroups); + for (auto it = first; it != last; ++it) { + const GUIVehicleGroup &vehgroup = *it; SetDParam(0, vehgroup.GetDisplayProfitThisYear()); SetDParam(1, vehgroup.GetDisplayProfitLastYear());