Codechange: make the StringIndex (within a StringTab) a strong type

This commit is contained in:
Rubidium 2025-01-02 09:03:38 +01:00 committed by rubidium42
parent 2d372fa516
commit fd7a883cbd
10 changed files with 44 additions and 37 deletions

View File

@ -315,10 +315,10 @@ GameStrings *_current_data = nullptr;
* @param id The ID of the game string.
* @return The encoded string.
*/
const char *GetGameStringPtr(uint id)
const char *GetGameStringPtr(StringIndexInTab id)
{
if (_current_data == nullptr || _current_data->cur_language == nullptr || id >= _current_data->cur_language->lines.size()) return GetStringPtr(STR_UNDEFINED);
return _current_data->cur_language->lines[id].c_str();
if (_current_data == nullptr || _current_data->cur_language == nullptr || id.base() >= _current_data->cur_language->lines.size()) return GetStringPtr(STR_UNDEFINED);
return _current_data->cur_language->lines[id.base()].c_str();
}
/**
@ -326,13 +326,13 @@ const char *GetGameStringPtr(uint id)
* @param id The ID of the game string.
* @return The string parameters.
*/
const StringParams &GetGameStringParams(uint id)
const StringParams &GetGameStringParams(StringIndexInTab id)
{
/* An empty result for STR_UNDEFINED. */
static StringParams empty;
if (id >= _current_data->string_params.size()) return empty;
return _current_data->string_params[id];
if (id.base() >= _current_data->string_params.size()) return empty;
return _current_data->string_params[id.base()];
}
/**
@ -340,13 +340,13 @@ const StringParams &GetGameStringParams(uint id)
* @param id The ID of the game string.
* @return The name of the string.
*/
const std::string &GetGameStringName(uint id)
const std::string &GetGameStringName(StringIndexInTab id)
{
/* The name for STR_UNDEFINED. */
static const std::string undefined = "STR_UNDEFINED";
if (id >= _current_data->string_names.size()) return undefined;
return _current_data->string_names[id];
if (id.base() >= _current_data->string_names.size()) return undefined;
return _current_data->string_names[id.base()];
}
/**

View File

@ -10,6 +10,8 @@
#ifndef GAME_TEXT_HPP
#define GAME_TEXT_HPP
#include "../strings_type.h"
struct StringParam {
enum ParamType {
UNUSED,
@ -27,9 +29,9 @@ struct StringParam {
using StringParams = std::vector<StringParam>;
using StringParamsList = std::vector<StringParams>;
const char *GetGameStringPtr(uint id);
const StringParams &GetGameStringParams(uint id);
const std::string &GetGameStringName(uint id);
const char *GetGameStringPtr(StringIndexInTab id);
const StringParams &GetGameStringParams(StringIndexInTab id);
const std::string &GetGameStringName(StringIndexInTab id);
void RegisterGameTranslation(class Squirrel *engine);
void ReconsiderGameScriptLanguage();

View File

@ -571,7 +571,7 @@ StringID AddGRFString(uint32_t grfid, GRFStringID stringid, uint8_t langid_to_ad
it->stringid = stringid;
it->def_string = def_string;
}
uint id = static_cast<uint>(it - std::begin(_grf_text));
StringIndexInTab id(it - std::begin(_grf_text));
std::string newtext = TranslateTTDPatchCodes(grfid, langid_to_add, allow_newlines, text_to_add);
AddGRFTextToList(it->textholder, langid_to_add, newtext);
@ -588,7 +588,7 @@ StringID GetGRFStringID(uint32_t grfid, GRFStringID stringid)
{
auto it = std::ranges::find_if(_grf_text, [&grfid, &stringid](const GRFTextEntry &grf_text) { return grf_text.grfid == grfid && grf_text.stringid == stringid; });
if (it != std::end(_grf_text)) {
uint id = static_cast<uint>(it - std::begin(_grf_text));
StringIndexInTab id(it - std::begin(_grf_text));
return MakeStringID(TEXT_TAB_NEWGRF_START, id);
}
@ -636,16 +636,16 @@ const char *GetGRFStringFromGRFText(const GRFTextWrapper &text)
/**
* Get a C-string from a stringid set by a newgrf.
*/
const char *GetGRFStringPtr(uint32_t stringid)
const char *GetGRFStringPtr(StringIndexInTab stringid)
{
assert(stringid < _grf_text.size());
assert(_grf_text[stringid].grfid != 0);
assert(stringid.base() < _grf_text.size());
assert(_grf_text[stringid.base()].grfid != 0);
const char *str = GetGRFStringFromGRFText(_grf_text[stringid].textholder);
const char *str = GetGRFStringFromGRFText(_grf_text[stringid.base()].textholder);
if (str != nullptr) return str;
/* Use the default string ID if the fallback string isn't available */
return GetStringPtr(_grf_text[stringid].def_string);
return GetStringPtr(_grf_text[stringid.base()].def_string);
}
/**

View File

@ -18,7 +18,7 @@ StringID AddGRFString(uint32_t grfid, GRFStringID stringid, uint8_t langid, bool
StringID GetGRFStringID(uint32_t grfid, GRFStringID stringid);
const char *GetGRFStringFromGRFText(const GRFTextList &text_list);
const char *GetGRFStringFromGRFText(const GRFTextWrapper &text);
const char *GetGRFStringPtr(uint32_t stringid);
const char *GetGRFStringPtr(StringIndexInTab stringid);
void CleanUpStrings();
void SetCurrentGrfLangID(uint8_t language_id);
std::string TranslateTTDPatchCodes(uint32_t grfid, uint8_t language_id, bool allow_newlines, std::string_view str, StringControlCode byte80 = SCC_NEWGRF_PRINT_WORD_STRING_ID);

View File

@ -30,7 +30,7 @@ ScriptError::ScriptErrorMapString ScriptError::error_map_string = ScriptError::S
/* static */ ScriptErrorType ScriptError::StringToError(StringID internal_string_id)
{
uint index = GetStringIndex(internal_string_id);
StringIndexInTab index = GetStringIndex(internal_string_id);
switch (GetStringTab(internal_string_id)) {
case TEXT_TAB_NEWGRF_START:
case TEXT_TAB_GAMESCRIPT_START:

View File

@ -33,7 +33,7 @@ ScriptText::ScriptText(HSQUIRRELVM vm)
if (SQ_FAILED(sq_getinteger(vm, 2, &sqstring))) {
throw sq_throwerror(vm, "First argument must be a valid StringID");
}
this->string = sqstring;
this->string = StringIndexInTab(sqstring);
/* The rest of the parameters must be arguments. */
for (int i = 0; i < nparam - 1; i++) {
@ -185,7 +185,7 @@ void ScriptText::_FillParamList(ParamList &params, ScriptTextList &seen_texts)
static Param dummy = 0;
int nb_extra = SCRIPT_TEXT_MAX_PARAMETERS - (int)params.size();
for (int i = 0; i < nb_extra; i++)
params.emplace_back(-1, i, &dummy);
params.emplace_back(StringIndexInTab(-1), i, &dummy);
}
}

View File

@ -132,13 +132,13 @@ private:
using Param = std::variant<SQInteger, std::string, ScriptTextRef>;
struct ParamCheck {
StringID owner;
StringIndexInTab owner;
int idx;
Param *param;
bool used = false;
const char *cmd = nullptr;
ParamCheck(StringID owner, int idx, Param *param) : owner(owner), idx(idx), param(param) {}
ParamCheck(StringIndexInTab owner, int idx, Param *param) : owner(owner), idx(idx), param(param) {}
void Encode(std::back_insert_iterator<std::string> &output, const char *cmd);
};
@ -146,7 +146,7 @@ private:
using ParamList = std::vector<ParamCheck>;
using ParamSpan = std::span<ParamCheck>;
StringID string;
StringIndexInTab string;
std::array<Param, SCRIPT_TEXT_MAX_PARAMETERS> param = {};
int paramc = 0;

View File

@ -239,7 +239,7 @@ const char *GetStringPtr(StringID string)
case TEXT_TAB_OLD_NEWGRF: NOT_REACHED();
case TEXT_TAB_NEWGRF_START: return GetGRFStringPtr(GetStringIndex(string));
default: {
const uint offset = _langpack.langtab_start[GetStringTab(string)] + GetStringIndex(string);
const size_t offset = _langpack.langtab_start[GetStringTab(string)] + GetStringIndex(string).base();
if (offset < _langpack.offsets.size()) return _langpack.offsets[offset];
return nullptr;
}
@ -261,14 +261,14 @@ void GetStringWithArgs(StringBuilder &builder, StringID string, StringParameters
return;
}
uint index = GetStringIndex(string);
StringIndexInTab index = GetStringIndex(string);
StringTab tab = GetStringTab(string);
switch (tab) {
case TEXT_TAB_TOWN:
if (index >= 0xC0 && !game_script) {
try {
GetSpecialTownNameString(builder, index - 0xC0, args.GetNextParameter<uint32_t>());
GetSpecialTownNameString(builder, index.base() - 0xC0, args.GetNextParameter<uint32_t>());
} catch (const std::runtime_error &e) {
Debug(misc, 0, "GetStringWithArgs: {}", e.what());
builder += "(invalid string parameter)";
@ -280,7 +280,7 @@ void GetStringWithArgs(StringBuilder &builder, StringID string, StringParameters
case TEXT_TAB_SPECIAL:
if (index >= 0xE4 && !game_script) {
try {
GetSpecialNameString(builder, index - 0xE4, args);
GetSpecialNameString(builder, index.base() - 0xE4, args);
} catch (const std::runtime_error &e) {
Debug(misc, 0, "GetStringWithArgs: {}", e.what());
builder += "(invalid string parameter)";
@ -987,7 +987,7 @@ static void FormatString(StringBuilder &builder, const char *str_arg, StringPara
ArrayStringParameters<20> sub_args;
char *p;
uint32_t stringid = std::strtoul(str, &p, 16);
StringIndexInTab stringid(std::strtoul(str, &p, 16));
if (*p != ':' && *p != '\0') {
while (*p != '\0') p++;
str = p;
@ -1048,7 +1048,7 @@ static void FormatString(StringBuilder &builder, const char *str_arg, StringPara
builder += "(invalid sub-StringID)";
break;
}
param = MakeStringID(TEXT_TAB_GAMESCRIPT_START, param);
param = MakeStringID(TEXT_TAB_GAMESCRIPT_START, StringIndexInTab(param));
}
sub_args.SetParam(i++, param);

View File

@ -35,18 +35,18 @@ inline StringTab GetStringTab(StringID str)
* @param str String identifier
* @return StringIndex from \a str
*/
inline uint GetStringIndex(StringID str)
inline StringIndexInTab GetStringIndex(StringID str)
{
return str - (GetStringTab(str) << TAB_SIZE_BITS);
return StringIndexInTab{str - (GetStringTab(str) << TAB_SIZE_BITS)};
}
/**
* Create a StringID
* @param tab StringTab
* @param index StringIndex
* @param index Index of the string within the given tab.
* @return StringID composed from \a tab and \a index
*/
inline StringID MakeStringID(StringTab tab, uint index)
inline StringID MakeStringID(StringTab tab, StringIndexInTab index)
{
if (tab == TEXT_TAB_NEWGRF_START) {
assert(index < TAB_SIZE_NEWGRF);
@ -56,7 +56,7 @@ inline StringID MakeStringID(StringTab tab, uint index)
assert(tab < TEXT_TAB_END);
assert(index < TAB_SIZE);
}
return (tab << TAB_SIZE_BITS) + index;
return (tab << TAB_SIZE_BITS) + index.base();
}
std::string GetString(StringID string);

View File

@ -10,6 +10,8 @@
#ifndef STRINGS_TYPE_H
#define STRINGS_TYPE_H
#include "core/strong_typedef_type.hpp"
/**
* Numeric value that represents a string, independent of the selected language.
*/
@ -40,6 +42,9 @@ enum StringTab {
TEXT_TAB_NEWGRF_START = 64, ///< Start of NewGRF supplied strings.
};
/** The index/offset of a string within a #StringTab. */
using StringIndexInTab = StrongType::Typedef<uint32_t, struct StringIndexInTabTag, StrongType::Compare, StrongType::Integer>;
/** Number of bits for the StringIndex within a StringTab */
static const uint TAB_SIZE_BITS = 11;
/** Number of strings per StringTab */