diff --git a/src/error.h b/src/error.h index 0f1964fb80..f9480745f4 100644 --- a/src/error.h +++ b/src/error.h @@ -31,7 +31,7 @@ enum WarningLevel { class ErrorMessageData { protected: bool is_critical; ///< Whether the error message is critical. - std::vector params; ///< Backup of parameters of the message strings. + std::vector params; ///< Backup of parameters of the message strings. const GRFFile *textref_stack_grffile; ///< NewGRF that filled the #TextRefStack for the error message. uint textref_stack_size; ///< Number of uint32_t values to put on the #TextRefStack for the error message. uint32_t textref_stack[16]; ///< Values to put on the #TextRefStack for the error message. diff --git a/src/misc_gui.cpp b/src/misc_gui.cpp index cb97d7c8c3..f77caa42e0 100644 --- a/src/misc_gui.cpp +++ b/src/misc_gui.cpp @@ -668,7 +668,7 @@ static WindowDesc _tool_tips_desc( struct TooltipsWindow : public Window { StringID string_id; ///< String to display as tooltip. - std::vector params; ///< The string parameters. + std::vector params; ///< The string parameters. TooltipCloseCondition close_cond; ///< Condition for closing the window. TooltipsWindow(Window *parent, StringID str, uint paramcount, TooltipCloseCondition close_tooltip) : Window(_tool_tips_desc) @@ -1089,7 +1089,7 @@ void ShowQueryString(StringID str, StringID caption, uint maxsize, Window *paren */ struct QueryWindow : public Window { QueryCallbackProc *proc; ///< callback function executed on closing of popup. Window* points to parent, bool is true if 'yes' clicked, false otherwise - std::vector params; ///< local copy of #_global_string_params + std::vector params; ///< local copy of #_global_string_params StringID message; ///< message shown for query window QueryWindow(WindowDesc &desc, StringID caption, StringID message, Window *parent, QueryCallbackProc *callback) : Window(desc) diff --git a/src/news_gui.cpp b/src/news_gui.cpp index c5aedecbf6..3ba464b0e5 100644 --- a/src/news_gui.cpp +++ b/src/news_gui.cpp @@ -296,7 +296,7 @@ struct NewsWindow : Window { this->CreateNestedTree(); /* For company news with a face we have a separate headline in param[0] */ - if (&desc == &_company_news_desc) this->GetWidget(WID_N_TITLE)->widget_data = this->ni->params[0].data; + if (&desc == &_company_news_desc) this->GetWidget(WID_N_TITLE)->widget_data = std::get(this->ni->params[0]); NWidgetCore *nwid = this->GetWidget(WID_N_SHOW_GROUP); if (ni->reftype1 == NR_VEHICLE && nwid != nullptr) { @@ -603,7 +603,7 @@ private: { /* Company news with a face have a separate headline, so the normal message is shifted by two params */ CopyInDParam(std::span(this->ni->params.data() + 2, this->ni->params.size() - 2)); - return this->ni->params[1].data; + return std::get(this->ni->params[1]); } StringID GetNewVehicleMessageString(WidgetID widget) const @@ -986,7 +986,7 @@ void ChangeVehicleNews(VehicleID from_index, VehicleID to_index) for (auto &ni : _news) { if (ni.reftype1 == NR_VEHICLE && ni.ref1 == from_index) ni.ref1 = to_index; if (ni.reftype2 == NR_VEHICLE && ni.ref2 == from_index) ni.ref2 = to_index; - if (ni.flags & NF_VEHICLE_PARAM0 && ni.params[0].data == from_index) ni.params[0] = to_index; + if (ni.flags & NF_VEHICLE_PARAM0 && std::get(ni.params[0]) == from_index) ni.params[0] = to_index; } } diff --git a/src/news_type.h b/src/news_type.h index cbafbef1ce..a83402f382 100644 --- a/src/news_type.h +++ b/src/news_type.h @@ -139,7 +139,7 @@ struct NewsItem { std::unique_ptr data; ///< Custom data for the news item that will be deallocated (deleted) when the news item has reached its end. - std::vector params; ///< Parameters for string resolving. + std::vector params; ///< Parameters for string resolving. NewsItem(StringID string_id, NewsType type, NewsFlag flags, NewsReferenceType reftype1, uint32_t ref1, NewsReferenceType reftype2, uint32_t ref2, const NewsAllocatedData *data); }; diff --git a/src/strings.cpp b/src/strings.cpp index 207cd883ff..0b0947db2a 100644 --- a/src/strings.cpp +++ b/src/strings.cpp @@ -113,7 +113,7 @@ void SetDParam(size_t n, uint64_t v) */ uint64_t GetDParam(size_t n) { - return _global_string_params.GetParam(n); + return std::get(_global_string_params.GetParam(n)); } /** @@ -156,15 +156,10 @@ void SetDParamMaxDigits(size_t n, uint count, FontSize size) * Copy the parameters from the backup into the global string parameter array. * @param backup The backup to copy from. */ -void CopyInDParam(const std::span backup) +void CopyInDParam(const std::span backup) { for (size_t i = 0; i < backup.size(); i++) { - auto &value = backup[i]; - if (value.string.has_value()) { - _global_string_params.SetParam(i, value.string.value()); - } else { - _global_string_params.SetParam(i, value.data); - } + _global_string_params.SetParam(i, backup[i]); } } @@ -173,16 +168,11 @@ void CopyInDParam(const std::span backup) * @param backup The backup to write to. * @param num Number of string parameters to copy. */ -void CopyOutDParam(std::vector &backup, size_t num) +void CopyOutDParam(std::vector &backup, size_t num) { backup.resize(num); for (size_t i = 0; i < backup.size(); i++) { - const char *str = _global_string_params.GetParamStr(i); - if (str != nullptr) { - backup[i] = str; - } else { - backup[i] = _global_string_params.GetParam(i); - } + backup[i] = _global_string_params.GetParam(i); } } @@ -191,20 +181,12 @@ void CopyOutDParam(std::vector &backup, size_t num) * @param backup The backup to check against. * @return True when the parameters have changed, otherwise false. */ -bool HaveDParamChanged(const std::span backup) +bool HaveDParamChanged(const std::span backup) { - bool changed = false; - for (size_t i = 0; !changed && i < backup.size(); i++) { - bool global_has_string = _global_string_params.GetParamStr(i) != nullptr; - if (global_has_string != backup[i].string.has_value()) return true; - - if (global_has_string) { - changed = backup[i].string.value() != _global_string_params.GetParamStr(i); - } else { - changed = backup[i].data != _global_string_params.GetParam(i); - } + for (size_t i = 0; i < backup.size(); i++) { + if (backup[i] != _global_string_params.GetParam(i)) return true; } - return changed; + return false; } static void StationGetSpecialString(StringBuilder &builder, StationFacility x); @@ -1106,7 +1088,7 @@ static void FormatString(StringBuilder &builder, const char *str_arg, StringPara case SCC_PLURAL_LIST: { // {P} int plural_form = *str++; // contains the plural form for this string size_t offset = orig_offset + (uint8_t)*str++; - int64_t v = args.GetParam(offset); // contains the number that determines plural + int64_t v = std::get(args.GetParam(offset)); // contains the number that determines plural str = ParseStringChoice(str, DeterminePluralForm(v, plural_form), builder); break; } diff --git a/src/strings_func.h b/src/strings_func.h index 60da2a7b55..3ee91a0af5 100644 --- a/src/strings_func.h +++ b/src/strings_func.h @@ -98,9 +98,9 @@ void SetDParamStr(size_t n, const char *str); void SetDParamStr(size_t n, const std::string &str); void SetDParamStr(size_t n, std::string &&str); -void CopyInDParam(const std::span backup); -void CopyOutDParam(std::vector &backup, size_t num); -bool HaveDParamChanged(const std::span backup); +void CopyInDParam(const std::span backup); +void CopyOutDParam(std::vector &backup, size_t num); +bool HaveDParamChanged(const std::span backup); uint64_t GetDParam(size_t n); diff --git a/src/strings_internal.h b/src/strings_internal.h index 1ef5a4a6a8..64a20587fd 100644 --- a/src/strings_internal.h +++ b/src/strings_internal.h @@ -15,8 +15,7 @@ /** The data required to format and validate a single parameter of a string. */ struct StringParameter { - uint64_t data; ///< The data of the parameter. - std::unique_ptr string; ///< Copied string value, if it has any. + StringParameterData data; ///< The data of the parameter. char32_t type; ///< The #StringControlCode to interpret this data with when it's the first parameter, otherwise '\0'. }; @@ -93,7 +92,9 @@ public: T GetNextParameter() { const auto ¶m = GetNextParameterReference(); - return static_cast(param.data); + const uint64_t *data = std::get_if(¶m.data); + if (data != nullptr) return static_cast(*data); + return T{}; } /** @@ -105,7 +106,9 @@ public: const char *GetNextParameterString() { const auto ¶m = GetNextParameterReference(); - return param.string != nullptr ? param.string->c_str() : nullptr; + const std::string *data = std::get_if(¶m.data); + if (data != nullptr) return data->c_str(); + return nullptr; } /** @@ -146,11 +149,16 @@ public: return this->parameters[offset].type; } + void SetParam(size_t n, const StringParameterData &v) + { + assert(n < this->parameters.size()); + this->parameters[n].data = v; + } + void SetParam(size_t n, uint64_t v) { assert(n < this->parameters.size()); this->parameters[n].data = v; - this->parameters[n].string.reset(); } template ::value, int> = 0> @@ -162,8 +170,7 @@ public: void SetParam(size_t n, const char *str) { assert(n < this->parameters.size()); - this->parameters[n].data = 0; - this->parameters[n].string = std::make_unique(str); + this->parameters[n].data = str; } void SetParam(size_t n, const std::string &str) { this->SetParam(n, str.c_str()); } @@ -171,28 +178,14 @@ public: void SetParam(size_t n, std::string &&str) { assert(n < this->parameters.size()); - this->parameters[n].data = 0; - this->parameters[n].string = std::make_unique(std::move(str)); + this->parameters[n].data = std::move(str); } - uint64_t GetParam(size_t n) const + const StringParameterData &GetParam(size_t n) const { assert(n < this->parameters.size()); - assert(this->parameters[n].string == nullptr); return this->parameters[n].data; } - - /** - * Get the stored string of the parameter, or \c nullptr when there is none. - * @param n The index into the parameters. - * @return The stored string. - */ - const char *GetParamStr(size_t n) const - { - assert(n < this->parameters.size()); - auto ¶m = this->parameters[n]; - return param.string != nullptr ? param.string->c_str() : nullptr; - } }; /** diff --git a/src/strings_type.h b/src/strings_type.h index 5e6d715b63..49a0965d59 100644 --- a/src/strings_type.h +++ b/src/strings_type.h @@ -88,34 +88,6 @@ enum SpecialStrings { SPECSTR_PRESIDENT_NAME = 0x70E7, }; -/** Data that is to be stored when backing up StringParameters. */ -struct StringParameterBackup { - uint64_t data; ///< The data field; valid *when* string has no value. - std::optional string; ///< The string value. - - /** - * Assign the numeric data with the given value, while clearing the stored string. - * @param data The new value of the data field. - * @return This object. - */ - StringParameterBackup &operator=(uint64_t data) - { - this->string.reset(); - this->data = data; - return *this; - } - - /** - * Assign a copy of the given string to the string field, while clearing the data field. - * @param string The new value of the string. - * @return This object. - */ - StringParameterBackup &operator=(const std::string_view string) - { - this->data = 0; - this->string.emplace(string); - return *this; - } -}; +using StringParameterData = std::variant; #endif /* STRINGS_TYPE_H */ diff --git a/src/tests/strings_func.cpp b/src/tests/strings_func.cpp index dd70b0a365..f82cdd92be 100644 --- a/src/tests/strings_func.cpp +++ b/src/tests/strings_func.cpp @@ -18,7 +18,7 @@ TEST_CASE("HaveDParamChanged") SetDParam(0, 0); SetDParamStr(1, "some string"); - std::vector backup; + std::vector backup; CopyOutDParam(backup, 2); CHECK(HaveDParamChanged(backup) == false); diff --git a/src/texteff.cpp b/src/texteff.cpp index 10b276232e..fbec86d04f 100644 --- a/src/texteff.cpp +++ b/src/texteff.cpp @@ -21,7 +21,7 @@ /** Container for all information about a text effect */ struct TextEffect : public ViewportSign { - std::vector params; ///< Backup of string parameters + std::vector params; ///< Backup of string parameters StringID string_id; ///< String to draw for the text effect, if INVALID_STRING_ID then it's not valid uint8_t duration; ///< How long the text effect should stay, in ticks (applies only when mode == TE_RISING) TextEffectMode mode; ///< Type of text effect