2023-11-21 14:38:01 +01:00
|
|
|
#include <hex/api/content_registry.hpp>
|
|
|
|
#include <hex/api/localization_manager.hpp>
|
2024-01-30 15:50:00 +01:00
|
|
|
#include <hex/helpers/auto_reset.hpp>
|
2023-11-21 14:38:01 +01:00
|
|
|
|
|
|
|
namespace hex {
|
|
|
|
|
|
|
|
namespace LocalizationManager {
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
2024-01-30 11:21:34 +01:00
|
|
|
AutoReset<std::string> s_fallbackLanguage;
|
|
|
|
AutoReset<std::string> s_selectedLanguage;
|
2024-07-27 11:23:21 +02:00
|
|
|
AutoReset<std::map<size_t, std::string>> s_currStrings;
|
2023-11-21 14:38:01 +01:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
namespace impl {
|
|
|
|
|
|
|
|
void resetLanguageStrings() {
|
2024-01-30 11:21:34 +01:00
|
|
|
s_currStrings->clear();
|
|
|
|
s_selectedLanguage->clear();
|
2023-11-21 14:38:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void setFallbackLanguage(const std::string &language) {
|
|
|
|
s_fallbackLanguage = language;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
LanguageDefinition::LanguageDefinition(std::map<std::string, std::string> &&entries) {
|
|
|
|
for (const auto &[key, value] : entries) {
|
|
|
|
if (value.empty())
|
|
|
|
continue;
|
|
|
|
|
2023-12-19 13:10:25 +01:00
|
|
|
m_entries.insert({ key, value });
|
2023-11-21 14:38:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
const std::map<std::string, std::string> &LanguageDefinition::getEntries() const {
|
2023-12-19 13:10:25 +01:00
|
|
|
return m_entries;
|
2023-11-21 14:38:01 +01:00
|
|
|
}
|
|
|
|
|
2024-07-27 11:23:21 +02:00
|
|
|
static void loadLanguageDefinitions(const std::vector<LanguageDefinition> &definitions) {
|
|
|
|
for (const auto &definition : definitions) {
|
|
|
|
const auto &entries = definition.getEntries();
|
|
|
|
if (entries.empty())
|
|
|
|
continue;
|
|
|
|
|
|
|
|
for (const auto &[key, value] : entries) {
|
|
|
|
if (value.empty())
|
|
|
|
continue;
|
|
|
|
|
2024-08-03 11:32:17 +02:00
|
|
|
s_currStrings->emplace(LangConst::hash(key), value);
|
2024-07-27 11:23:21 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-21 14:38:01 +01:00
|
|
|
void loadLanguage(const std::string &language) {
|
|
|
|
auto &definitions = ContentRegistry::Language::impl::getLanguageDefinitions();
|
|
|
|
|
|
|
|
if (!definitions.contains(language))
|
|
|
|
return;
|
|
|
|
|
2024-02-01 10:58:45 +01:00
|
|
|
s_currStrings->clear();
|
|
|
|
|
2024-07-27 11:23:21 +02:00
|
|
|
loadLanguageDefinitions(definitions.at(language));
|
2023-11-21 14:38:01 +01:00
|
|
|
|
|
|
|
const auto& fallbackLanguage = getFallbackLanguage();
|
2024-07-27 11:23:21 +02:00
|
|
|
loadLanguageDefinitions(definitions.at(fallbackLanguage));
|
2023-11-21 14:38:01 +01:00
|
|
|
|
|
|
|
s_selectedLanguage = language;
|
|
|
|
}
|
|
|
|
|
2024-01-30 14:57:36 +01:00
|
|
|
std::string getLocalizedString(const std::string& unlocalizedString, const std::string& language) {
|
|
|
|
if (language.empty())
|
|
|
|
return getLocalizedString(unlocalizedString, getSelectedLanguage());
|
|
|
|
|
|
|
|
auto &languageDefinitions = ContentRegistry::Language::impl::getLanguageDefinitions();
|
|
|
|
if (!languageDefinitions.contains(language))
|
|
|
|
return "";
|
|
|
|
|
|
|
|
std::string localizedString;
|
2024-02-10 23:31:05 +01:00
|
|
|
for (const auto &definition : languageDefinitions.at(language)) {
|
2024-01-30 14:57:36 +01:00
|
|
|
if (definition.getEntries().contains(unlocalizedString)) {
|
|
|
|
localizedString = definition.getEntries().at(unlocalizedString);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (localizedString.empty())
|
|
|
|
return getLocalizedString(unlocalizedString, getFallbackLanguage());
|
|
|
|
|
|
|
|
return localizedString;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2023-11-21 14:38:01 +01:00
|
|
|
const std::map<std::string, std::string> &getSupportedLanguages() {
|
|
|
|
return ContentRegistry::Language::impl::getLanguages();
|
|
|
|
}
|
|
|
|
|
|
|
|
const std::string &getFallbackLanguage() {
|
|
|
|
return s_fallbackLanguage;
|
|
|
|
}
|
|
|
|
|
|
|
|
const std::string &getSelectedLanguage() {
|
|
|
|
return s_selectedLanguage;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2024-08-03 11:32:17 +02:00
|
|
|
Lang::Lang(const char *unlocalizedString) : m_entryHash(LangConst::hash(unlocalizedString)), m_unlocalizedString(unlocalizedString) { }
|
|
|
|
Lang::Lang(const std::string &unlocalizedString) : m_entryHash(LangConst::hash(unlocalizedString)), m_unlocalizedString(unlocalizedString) { }
|
|
|
|
Lang::Lang(const LangConst &localizedString) : m_entryHash(localizedString.m_entryHash), m_unlocalizedString(localizedString.m_unlocalizedString) { }
|
|
|
|
Lang::Lang(const UnlocalizedString &unlocalizedString) : m_entryHash(LangConst::hash(unlocalizedString.get())), m_unlocalizedString(unlocalizedString.get()) { }
|
|
|
|
Lang::Lang(std::string_view unlocalizedString) : m_entryHash(LangConst::hash(unlocalizedString)), m_unlocalizedString(unlocalizedString) { }
|
2024-01-21 18:39:32 +01:00
|
|
|
|
2023-11-21 14:38:01 +01:00
|
|
|
Lang::operator std::string() const {
|
|
|
|
return get();
|
|
|
|
}
|
|
|
|
|
|
|
|
Lang::operator std::string_view() const {
|
|
|
|
return get();
|
|
|
|
}
|
|
|
|
|
|
|
|
Lang::operator const char *() const {
|
2024-07-27 14:09:52 +02:00
|
|
|
return get();
|
2023-11-21 14:38:01 +01:00
|
|
|
}
|
|
|
|
|
2024-07-27 14:09:52 +02:00
|
|
|
const char *Lang::get() const {
|
2024-07-27 11:23:21 +02:00
|
|
|
const auto &lang = *LocalizationManager::s_currStrings;
|
|
|
|
|
2024-08-03 11:32:17 +02:00
|
|
|
const auto it = lang.find(m_entryHash);
|
2024-07-27 11:23:21 +02:00
|
|
|
if (it == lang.end()) {
|
2024-08-03 11:32:17 +02:00
|
|
|
return m_unlocalizedString.c_str();
|
|
|
|
} else {
|
|
|
|
return it->second.c_str();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
LangConst::operator std::string() const {
|
|
|
|
return get();
|
|
|
|
}
|
|
|
|
|
|
|
|
LangConst::operator std::string_view() const {
|
|
|
|
return get();
|
|
|
|
}
|
|
|
|
|
|
|
|
LangConst::operator const char *() const {
|
|
|
|
return get();
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *LangConst::get() const {
|
|
|
|
const auto &lang = *LocalizationManager::s_currStrings;
|
|
|
|
|
|
|
|
const auto it = lang.find(m_entryHash);
|
|
|
|
if (it == lang.end()) {
|
|
|
|
return m_unlocalizedString;
|
2024-07-27 11:23:21 +02:00
|
|
|
} else {
|
2024-07-27 14:09:52 +02:00
|
|
|
return it->second.c_str();
|
2024-07-27 11:23:21 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-21 14:38:01 +01:00
|
|
|
}
|