Allow passing sub strings with parameters as a parameter

wip-string
Jonathan G Rennison 4 months ago
parent 4baf2fcf59
commit c0ec1a2dcc

@ -331,6 +331,16 @@ void SetDParamStr(size_t n, std::string str)
_global_string_params.SetParam(n, std::move(str));
}
/**
* This function is used to "bind" the SubStringWithParameters to a OpenTTD dparam slot.
* @param n slot of the string
* @param sub_string SubStringWithParameters to bind
*/
void SetDParamSubString(size_t n, const SubStringWithParameters &sub_string)
{
_global_string_params.SetParam(n, sub_string);
}
/**
* Format a number into a string.
* @param buff the buffer to write to
@ -1119,6 +1129,18 @@ static char *FormatString(char *buff, const char *str_arg, StringParameters &arg
continue;
}
auto handle_substring = [&]() -> bool {
if (!args.HasNextParameterSubString()) return false;
const SubStringWithParameters &sub_string = args.GetNextParameterSubString();
if (game_script && GetStringTab(sub_string.string_id) != TEXT_TAB_GAMESCRIPT_START) return true;
StringParameters sub_args(sub_string);
buff = GetStringWithArgs(buff, sub_string.string_id, sub_args, last, next_substr_case_index, game_script);
next_substr_case_index = 0;
return true;
};
args.SetTypeOfNextParameter(b);
switch (b) {
case SCC_ENCODED: {
@ -1313,6 +1335,7 @@ static char *FormatString(char *buff, const char *str_arg, StringParameters &arg
}
case SCC_STRING: {// {STRING}
if (handle_substring()) break;
StringID string_id = args.GetNextParameter<StringID>();
if (game_script && GetStringTab(string_id) != TEXT_TAB_GAMESCRIPT_START) break;
/* It's prohibited for the included string to consume any arguments. */
@ -1330,6 +1353,7 @@ static char *FormatString(char *buff, const char *str_arg, StringParameters &arg
case SCC_STRING6:
case SCC_STRING7:
case SCC_STRING8: { // {STRING1..8}
if (handle_substring()) break;
/* Strings that consume arguments */
StringID string_id = args.GetNextParameter<StringID>();
if (game_script && GetStringTab(string_id) != TEXT_TAB_GAMESCRIPT_START) break;

@ -105,6 +105,8 @@ void SetDParamMaxDigits(size_t n, uint count, FontSize size = FS_NORMAL);
void SetDParamStr(size_t n, const char *str);
void SetDParamStr(size_t n, std::string str);
void SetDParamSubString(size_t n, const SubStringWithParameters &sub_string);
void CopyInDParam(const span<const StringParameterBackup> backup, uint offset = 0);
void CopyOutDParam(std::vector<StringParameterBackup> &backup, size_t num);
bool HaveDParamChanged(const std::vector<StringParameterBackup> &backup);

@ -20,9 +20,17 @@
struct StringParameter;
/** The data representing a string ID with associated parameters, which can be used as a string parameter. */
struct SubStringWithParameters {
StringID string_id;
span<StringParameter> parameters;
SubStringWithParameters(StringID string_id, span<StringParameter> parameters) : string_id(string_id), parameters(parameters) {}
};
/** The data required to format and validate a single parameter of a string. */
struct StringParameter {
std::variant<uint64_t, const char *, std::unique_ptr<std::string>> data; ///< The data of the parameter, non-owning string value, or owned string value.
std::variant<uint64_t, const char *, std::unique_ptr<std::string>, std::unique_ptr<SubStringWithParameters>> data; ///< The data of the parameter, non-owning string value, owned string value, or nested parameter span.
char32_t type; ///< The #StringControlCode to interpret this data with when it's the first parameter, otherwise '\0'.
};
@ -50,6 +58,15 @@ public:
parameters(parent.parameters.subspan(parent.offset, size))
{}
StringParameters(const SubStringWithParameters &sub_string) :
parameters(sub_string.parameters)
{}
SubStringWithParameters AsSubStringWithParameters(StringID string_id) const
{
return SubStringWithParameters(string_id, this->parameters);
}
void PrepareForNextRun();
void SetTypeOfNextParameter(char32_t type) { this->next_type = type; }
@ -122,6 +139,16 @@ public:
}
}
const SubStringWithParameters &GetNextParameterSubString()
{
return *std::get<std::unique_ptr<SubStringWithParameters>>(GetNextParameterPointer()->data);
}
bool HasNextParameterSubString() const
{
return this->offset < this->parameters.size() && std::holds_alternative<std::unique_ptr<SubStringWithParameters>>(this->parameters[this->offset].data);
}
/**
* Get a new instance of StringParameters that is a "range" into the
* remaining existing parameters. Upon destruction the offset in the parent
@ -184,10 +211,10 @@ public:
this->parameters[n].data = std::make_unique<std::string>(std::move(str));
}
void SetParam(size_t n, span<StringParameter> params)
void SetParam(size_t n, const SubStringWithParameters &sub_string)
{
assert(n < this->parameters.size());
this->parameters[n].data = params;
this->parameters[n].data = std::make_unique<SubStringWithParameters>(sub_string);;
}
uint64_t GetParam(size_t n) const

Loading…
Cancel
Save