From 2f0b52d5b3ff83de8776f22a2b80a24aac80ae1a Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Fri, 17 Jan 2025 19:33:11 +0000 Subject: [PATCH] Codechange: Use sorted vector for NewGRF parameter value names. (#13326) This replaces use of a std::map per GRF-parameter. --- src/newgrf.cpp | 11 ++++------- src/newgrf_config.cpp | 14 +++++++------- src/newgrf_config.h | 3 ++- src/newgrf_gui.cpp | 8 ++++---- 4 files changed, 17 insertions(+), 19 deletions(-) diff --git a/src/newgrf.cpp b/src/newgrf.cpp index 9ace4ba853..eb9065006f 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -8470,14 +8470,11 @@ static bool ChangeGRFParamValueNames(ByteReader &buf) uint8_t langid = buf.ReadByte(); std::string_view name_string = buf.ReadString(); - auto val_name = _cur_parameter->value_names.find(id); - if (val_name != _cur_parameter->value_names.end()) { - AddGRFTextToList(val_name->second, langid, _cur.grfconfig->ident.grfid, false, name_string); - } else { - GRFTextList list; - AddGRFTextToList(list, langid, _cur.grfconfig->ident.grfid, false, name_string); - _cur_parameter->value_names[id] = list; + auto it = std::ranges::lower_bound(_cur_parameter->value_names, id, std::less{}, &GRFParameterInfo::ValueName::first); + if (it == std::end(_cur_parameter->value_names) || it->first != id) { + it = _cur_parameter->value_names.emplace(it, id, GRFTextList{}); } + AddGRFTextToList(it->second, langid, _cur.grfconfig->ident.grfid, false, name_string); type = buf.ReadByte(); } diff --git a/src/newgrf_config.cpp b/src/newgrf_config.cpp index 77364a0ac1..2bc58de1de 100644 --- a/src/newgrf_config.cpp +++ b/src/newgrf_config.cpp @@ -211,13 +211,13 @@ void GRFConfig::SetValue(const GRFParameterInfo &info, uint32_t value) */ void GRFParameterInfo::Finalize() { - this->complete_labels = true; - for (uint32_t value = this->min_value; value <= this->max_value; value++) { - if (this->value_names.count(value) == 0) { - this->complete_labels = false; - break; - } - } + /* Remove value names outside of the permitted range of values. */ + auto it = std::remove_if(std::begin(this->value_names), std::end(this->value_names), + [this](const ValueName &vn) { return vn.first < this->min_value || vn.first > this->max_value; }); + this->value_names.erase(it, std::end(this->value_names)); + + /* Test if the number of named values matches the full ranges of values. -1 because the range is inclusive. */ + this->complete_labels = (this->max_value - this->min_value) == std::size(this->value_names) - 1; } /** diff --git a/src/newgrf_config.h b/src/newgrf_config.h index aae6f03de1..d88bc17174 100644 --- a/src/newgrf_config.h +++ b/src/newgrf_config.h @@ -145,7 +145,8 @@ struct GRFParameterInfo { bool complete_labels = false; ///< True if all values have a label. - std::map value_names = {}; ///< Names for each value. + using ValueName = std::pair; + std::vector value_names; ///< Names for each value. void Finalize(); }; diff --git a/src/newgrf_gui.cpp b/src/newgrf_gui.cpp index 5a12ea51dd..a5d26be301 100644 --- a/src/newgrf_gui.cpp +++ b/src/newgrf_gui.cpp @@ -298,8 +298,8 @@ struct NewGRFParametersWindow : public Window { } SetDParam(2, STR_JUST_INT); SetDParam(3, current_value); - auto it = par_info.value_names.find(current_value); - if (it != par_info.value_names.end()) { + auto it = std::ranges::lower_bound(par_info.value_names, current_value, std::less{}, &GRFParameterInfo::ValueName::first); + if (it != std::end(par_info.value_names) && it->first == current_value) { const char *label = GetGRFStringFromGRFText(it->second); if (label != nullptr) { SetDParam(2, STR_JUST_RAW_STRING); @@ -393,8 +393,8 @@ struct NewGRFParametersWindow : public Window { this->closing_dropdown = false; DropDownList list; - for (uint32_t i = par_info.min_value; i <= par_info.max_value; i++) { - list.push_back(MakeDropDownListStringItem(GetGRFStringFromGRFText(par_info.value_names.find(i)->second), i)); + for (const auto &[value, name] : par_info.value_names) { + list.push_back(MakeDropDownListStringItem(GetGRFStringFromGRFText(name), value)); } ShowDropDownListAt(this, std::move(list), old_val, WID_NP_SETTING_DROPDOWN, wi_rect, COLOUR_ORANGE);