From 12bd0ed26d490b1eb506ee5936f127544fc5e141 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Fri, 7 Apr 2023 10:20:00 +0200 Subject: [PATCH] Restore the shared_ptrs --- Common/Data/Text/I18n.cpp | 121 +++++++++++++++++++------------------ Common/Data/Text/I18n.h | 30 ++++----- Core/Config.cpp | 2 +- UI/MiscScreens.cpp | 4 +- UI/NativeApp.cpp | 6 +- Windows/MainWindowMenu.cpp | 2 +- libretro/libretro.cpp | 2 +- 7 files changed, 81 insertions(+), 86 deletions(-) diff --git a/Common/Data/Text/I18n.cpp b/Common/Data/Text/I18n.cpp index 93eb9b3819..a4d894abd5 100644 --- a/Common/Data/Text/I18n.cpp +++ b/Common/Data/Text/I18n.cpp @@ -7,59 +7,64 @@ #include "Common/StringUtils.h" -I18NRepo i18nrepo; +static const char * const g_categoryNames[(size_t)I18NCat::CATEGORY_COUNT] = { + "Audio", + "Controls", + "CwCheats", + "DesktopUI", + "Developer", + "Dialog", + "Error", + "Game", + "Graphics", + "InstallZip", + "KeyMapping", + "MainMenu", + "MainSettings", + "MappableControls", + "Networking", + "Pause", + "PostShaders", + "PSPCredits", + "MemStick", + "RemoteISO", + "Reporting", + "Savedata", + "Screen", + "Search", + "Store", + "SysInfo", + "System", + "TextureShaders", + "Themes", + "UI Elements", + "Upgrade", + "VR", +}; -I18NRepo::~I18NRepo() { - Clear(); -} +I18NRepo g_i18nrepo; std::string I18NRepo::LanguageID() { return languageID_; } I18NRepo::I18NRepo() { - cats_[(size_t)I18NCat::AUDIO].SetName("Audio"); - cats_[(size_t)I18NCat::CONTROLS].SetName("Controls"); - cats_[(size_t)I18NCat::SYSTEM].SetName("System"); - cats_[(size_t)I18NCat::CWCHEATS].SetName("CwCheats"); - cats_[(size_t)I18NCat::DESKTOPUI].SetName("DesktopUI"); - cats_[(size_t)I18NCat::DEVELOPER].SetName("Developer"); - cats_[(size_t)I18NCat::DIALOG].SetName("Dialog"); - cats_[(size_t)I18NCat::ERRORS].SetName("Error"); - cats_[(size_t)I18NCat::GAME].SetName("Game"); - cats_[(size_t)I18NCat::GRAPHICS].SetName("Graphics"); - cats_[(size_t)I18NCat::INSTALLZIP].SetName("InstallZip"); - cats_[(size_t)I18NCat::KEYMAPPING].SetName("KeyMapping"); - cats_[(size_t)I18NCat::MAINMENU].SetName("MainMenu"); - cats_[(size_t)I18NCat::MAINSETTINGS].SetName("MainSettings"); - cats_[(size_t)I18NCat::MAPPABLECONTROLS].SetName("MappableControls"); - cats_[(size_t)I18NCat::NETWORKING].SetName("Networking"); - cats_[(size_t)I18NCat::PAUSE].SetName("Pause"); - cats_[(size_t)I18NCat::POSTSHADERS].SetName("PostShaders"); - cats_[(size_t)I18NCat::PSPCREDITS].SetName("PSPCredits"); - cats_[(size_t)I18NCat::MEMSTICK].SetName("MemStick"); - cats_[(size_t)I18NCat::REMOTEISO].SetName("RemoteISO"); - cats_[(size_t)I18NCat::REPORTING].SetName("Reporting"); - cats_[(size_t)I18NCat::SAVEDATA].SetName("Savedata"); - cats_[(size_t)I18NCat::SCREEN].SetName("Screen"); - cats_[(size_t)I18NCat::SEARCH].SetName("Search"); - cats_[(size_t)I18NCat::STORE].SetName("Store"); - cats_[(size_t)I18NCat::SYSINFO].SetName("SysInfo"); - cats_[(size_t)I18NCat::SYSTEM].SetName("System"); - cats_[(size_t)I18NCat::TEXTURESHADERS].SetName("TextureShaders"); - cats_[(size_t)I18NCat::THEMES].SetName("Themes"); - cats_[(size_t)I18NCat::UI_ELEMENTS].SetName("UI Elements"); - cats_[(size_t)I18NCat::UPGRADE].SetName("Upgrade"); - cats_[(size_t)I18NCat::VR].SetName("VR"); + Clear(); } void I18NRepo::Clear() { std::lock_guard guard(catsLock_); for (auto &iter : cats_) { - iter.Clear(); + // Initialize with empty categories, so that early lookups don't crash. + iter = std::shared_ptr(new I18NCategory()); } } +I18NCategory::I18NCategory(const Section §ion) { + std::map sectionMap = section.ToMap(); + SetMap(sectionMap); +} + void I18NCategory::Clear() { map_.clear(); missedKeyLog_.clear(); @@ -69,6 +74,7 @@ const char *I18NCategory::T(const char *key, const char *def) { if (!key) { return "ERROR"; } + // Replace the \n's with \\n's so that key values with newlines will be found correctly. std::string modifiedKey = key; modifiedKey = ReplaceAll(modifiedKey, "\n", "\\n"); @@ -95,23 +101,14 @@ void I18NCategory::SetMap(const std::map &m) { } } -I18NCategory *I18NRepo::GetCategory(I18NCat category) { +std::shared_ptr I18NRepo::GetCategory(I18NCat category) { std::lock_guard guard(catsLock_); if (category != I18NCat::NONE) - return &cats_[(size_t)category]; + return cats_[(size_t)category]; else return nullptr; } -I18NCategory *I18NRepo::GetCategoryByName(const char *name) { - for (auto &iter : cats_) { - if (!strcmp(iter.GetName(), name)) { - return &iter; - } - } - return nullptr; -} - Path I18NRepo::GetIniPath(const std::string &languageID) const { return Path("lang") / (languageID + ".ini"); } @@ -144,10 +141,11 @@ bool I18NRepo::LoadIni(const std::string &languageID, const Path &overridePath) const std::vector
§ions = ini.Sections(); std::lock_guard guard(catsLock_); - for (auto &iter : sections) { - I18NCategory *cat = GetCategoryByName(iter.name().c_str()); - if (cat) { - cat->LoadSection(iter); + for (auto §ion : sections) { + for (size_t i = 0; i < (size_t)I18NCat::CATEGORY_COUNT; i++) { + if (!strcmp(section.name().c_str(), g_categoryNames[i])) { + cats_[i].reset(new I18NCategory(section)); + } } } @@ -157,14 +155,19 @@ bool I18NRepo::LoadIni(const std::string &languageID, const Path &overridePath) void I18NRepo::LogMissingKeys() const { std::lock_guard guard(catsLock_); - for (auto &cat : cats_) { - for (auto &key : cat.Missed()) { - INFO_LOG(SYSTEM, "Missing translation [%s]: %s (%s)", cat.GetName(), key.first.c_str(), key.second.c_str()); + for (size_t i = 0; i < (size_t)I18NCat::CATEGORY_COUNT; i++) { + auto &cat = cats_[i]; + for (auto &key : cat->Missed()) { + INFO_LOG(SYSTEM, "Missing translation [%s]: %s (%s)", g_categoryNames[i], key.first.c_str(), key.second.c_str()); } } } -void I18NCategory::LoadSection(const Section §ion) { - std::map sectionMap = section.ToMap(); - SetMap(sectionMap); +std::shared_ptr GetI18NCategory(I18NCat category) { + if (category == I18NCat::NONE) { + return std::shared_ptr(); + } + std::shared_ptr cat = g_i18nrepo.GetCategory(category); + _dbg_assert_(cat); + return cat; } diff --git a/Common/Data/Text/I18n.h b/Common/Data/Text/I18n.h index fc22e8eb6f..5c47960212 100644 --- a/Common/Data/Text/I18n.h +++ b/Common/Data/Text/I18n.h @@ -12,6 +12,7 @@ #include #include #include +#include #include "Common/Common.h" #include "Common/File/Path.h" @@ -76,8 +77,8 @@ struct I18NCandidate { class I18NCategory { public: I18NCategory() {} - // NOTE: Name must be a global constant string - it is not copied. - explicit I18NCategory(const char *name) : name_(name) {} + explicit I18NCategory(const Section §ion); + const char *T(const char *key, const char *def = nullptr); const char *T(const std::string &key) { return T(key.c_str(), nullptr); @@ -90,16 +91,11 @@ public: const std::map &GetMap() { return map_; } void ClearMissed() { missedKeyLog_.clear(); } - const char *GetName() const { return name_.c_str(); } void Clear(); private: - I18NCategory(I18NRepo *repo, const char *name) : name_(name) {} - void SetName(const char *name) { name_ = name; } + I18NCategory(I18NRepo *repo, const char *name) {} void SetMap(const std::map &m); - void LoadSection(const Section §ion); - - std::string name_; std::map map_; mutable std::mutex missedKeyLock_; @@ -112,18 +108,16 @@ private: class I18NRepo { public: I18NRepo(); - ~I18NRepo(); - bool IniExists(const std::string &languageID) const; bool LoadIni(const std::string &languageID, const Path &overridePath = Path()); // NOT the filename! std::string LanguageID(); - I18NCategory *GetCategory(I18NCat category); - I18NCategory *GetCategoryByName(const char *name); + std::shared_ptr GetCategory(I18NCat category); + std::shared_ptr GetCategoryByName(const char *name); const char *T(I18NCat category, const char *key, const char *def = nullptr) { - return cats_[(size_t)category].T(key, def); + return cats_[(size_t)category]->T(key, def); } void LogMissingKeys() const; @@ -133,19 +127,17 @@ private: void Clear(); mutable std::mutex catsLock_; - I18NCategory cats_[(size_t)I18NCat::CATEGORY_COUNT]; + std::shared_ptr cats_[(size_t)I18NCat::CATEGORY_COUNT]; std::string languageID_; }; -extern I18NRepo i18nrepo; +extern I18NRepo g_i18nrepo; // These are simply talking to the one global instance of I18NRepo. -inline I18NCategory *GetI18NCategory(I18NCat cat) { - return i18nrepo.GetCategory(cat); -} +std::shared_ptr GetI18NCategory(I18NCat cat); inline const char *T(I18NCat category, const char *key, const char *def = nullptr) { - return i18nrepo.T(category, key, def); + return g_i18nrepo.T(category, key, def); } diff --git a/Core/Config.cpp b/Core/Config.cpp index fe8c88f32e..13f1de313e 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -432,7 +432,7 @@ const char *DefaultLangRegion() { // Unfortunate default. There's no need to use bFirstRun, since this is only a default. static std::string defaultLangRegion = "en_US"; std::string langRegion = System_GetProperty(SYSPROP_LANGREGION); - if (i18nrepo.IniExists(langRegion)) { + if (g_i18nrepo.IniExists(langRegion)) { defaultLangRegion = langRegion; } else if (langRegion.length() >= 3) { // Don't give up. Let's try a fuzzy match - so nl_BE can match nl_NL. diff --git a/UI/MiscScreens.cpp b/UI/MiscScreens.cpp index 78c0e16d14..80c36d7d5a 100644 --- a/UI/MiscScreens.cpp +++ b/UI/MiscScreens.cpp @@ -661,9 +661,9 @@ void NewLanguageScreen::OnCompleted(DialogResult result) { // If we run into the unlikely case that "lang" is actually a file, just use the built-in translations. if (!File::Exists(langOverridePath) || !File::IsDirectory(langOverridePath)) - iniLoadedSuccessfully = i18nrepo.LoadIni(g_Config.sLanguageIni); + iniLoadedSuccessfully = g_i18nrepo.LoadIni(g_Config.sLanguageIni); else - iniLoadedSuccessfully = i18nrepo.LoadIni(g_Config.sLanguageIni, langOverridePath); + iniLoadedSuccessfully = g_i18nrepo.LoadIni(g_Config.sLanguageIni, langOverridePath); if (iniLoadedSuccessfully) { // Dunno what else to do here. diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index 01f7f3f436..e1f858c2c3 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -282,9 +282,9 @@ void PostLoadConfig() { // If we run into the unlikely case that "lang" is actually a file, just use the built-in translations. if (!File::Exists(langOverridePath) || !File::IsDirectory(langOverridePath)) - i18nrepo.LoadIni(g_Config.sLanguageIni); + g_i18nrepo.LoadIni(g_Config.sLanguageIni); else - i18nrepo.LoadIni(g_Config.sLanguageIni, langOverridePath); + g_i18nrepo.LoadIni(g_Config.sLanguageIni, langOverridePath); #if PPSSPP_PLATFORM(ANDROID) CreateDirectoriesAndroid(); @@ -1381,7 +1381,7 @@ void NativeShutdown() { INFO_LOG(SYSTEM, "NativeShutdown called"); - i18nrepo.LogMissingKeys(); + g_i18nrepo.LogMissingKeys(); ShutdownWebServer(); diff --git a/Windows/MainWindowMenu.cpp b/Windows/MainWindowMenu.cpp index 10e17623d2..ce2c83dcf3 100644 --- a/Windows/MainWindowMenu.cpp +++ b/Windows/MainWindowMenu.cpp @@ -291,7 +291,7 @@ namespace MainWindow { void TranslateMenus(HWND hWnd, HMENU menu) { bool changed = false; - const std::string curLanguageID = i18nrepo.LanguageID(); + const std::string curLanguageID = g_i18nrepo.LanguageID(); if (curLanguageID != menuLanguageID || KeyMap::HasChanged(menuKeymapGeneration)) { DoTranslateMenus(hWnd, menu); menuLanguageID = curLanguageID; diff --git a/libretro/libretro.cpp b/libretro/libretro.cpp index ae39c8c7d6..e60c073709 100644 --- a/libretro/libretro.cpp +++ b/libretro/libretro.cpp @@ -983,7 +983,7 @@ static void check_variables(CoreParameter &coreParam) g_Config.iLanguage = get_language_auto(); g_Config.sLanguageIni = map_psp_language_to_i18n_locale(g_Config.iLanguage); - i18nrepo.LoadIni(g_Config.sLanguageIni); + g_i18nrepo.LoadIni(g_Config.sLanguageIni); // Cannot detect refresh rate changes if: // > Frame skipping is enabled