123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990 |
- #include "TranslationManager.hxx"
- #include <SDL.h>
- #include <fstream>
- #include <optional>
- #include <regex>
- namespace {
- std::optional<SupportedLanguage> language_from_string(std::string const& lang)
- {
- static std::unordered_map<std::string, SupportedLanguage> const MAPPING{
- {"en", SupportedLanguage::English},
- {"de", SupportedLanguage::German},
- };
- auto const it = MAPPING.find(lang);
- if (it==MAPPING.end())
- return {};
- return it->second;
- }
- SupportedLanguage get_preferred_language()
- {
- auto const locales = SDL_GetPreferredLocales();
- for (auto const* locale = locales; locale->language!=nullptr; ++locale) {
- auto const lang = language_from_string(locale->language);
- if (lang.has_value()) {
- SDL_free(locales);
- return lang.value();
- }
- }
- SDL_free(locales);
- return SupportedLanguage::English;
- }
- std::regex const KEY_REGEX = std::regex{R"(^\[([^\]]*)\]$)"};
- std::regex const VALUE_REGEX = std::regex{R"(^(en|de) = (.+)$)"};
- }
- TranslationManager::TranslationManager() noexcept
- :current_language_{::get_preferred_language()}
- {
- }
- TranslationManager& TranslationManager::instance()
- {
- static TranslationManager tm;
- return tm;
- }
- std::string TranslationManager::get_translation(std::string const& key) const
- {
- auto const it = translations_.find(key);
- if (it==translations_.end())
- return key;
- auto const lang_idx = static_cast<std::size_t>(current_language_);
- if (it->second[lang_idx].empty())
- return key;
- return it->second[lang_idx];
- }
- void TranslationManager::load(std::filesystem::path const& filename)
- {
- std::ifstream input{filename};
- std::string current_key{};
- for (std::string line; std::getline(input, line);) {
- if (std::smatch key_match; std::regex_match(line, key_match, ::KEY_REGEX)) {
- current_key = key_match.str(1);
- }
- else if (std::smatch value_match; std::regex_match(line, value_match, ::VALUE_REGEX)) {
- // hacky, but right now the regex already makes sure we alway get a language back
- auto const lang = ::language_from_string(value_match.str(1)).value();
- auto const value = value_match.str(2);
- if (current_key.empty()) {
- SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Translations without key not loaded! (%s)", value.c_str());
- }
- else {
- translations_[current_key][static_cast<std::size_t>(lang)] = value;
- }
- }
- else if (!line.empty()) {
- SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, "Translation line with unsupported format: %s", line.c_str());
- }
- }
- }
|