#pragma once #include "Utils/Sigslot.hpp" #include "Utils/fwd.hpp" #include #include #include #include #include #include #include class I18n { public: static inline Signal<> OnLanguageChange{}; static inline Signal<> OnUnload{}; static void Init(); static void Shutdown(); /// Discard in-memory mapping from key to locale entries. /// When any of the entry accessors are invoked, unloaded entries will be reloaded. static void Unload(); static std::string_view GetLanguage(); static bool SetLanguage(std::string_view lang); /* Entry accessors */ /// Find the localized entry with the given key, return \c std::nullopt if does not exist. Reloads locale entries if they are currently unloaded. static std::optional Lookup(std::string_view key); /// Find the localized entry with the given key, throw an exception if does not exist. EnsureLoaded locale entries if they are currently unloaded. static std::string_view LookupUnwrap(std::string_view key); /// Query the localized name of a locale, e.g. "en_US" -> "English - United States". /// If the queried locale does not exist, an empty string will be returned (existing locales can never have an empty localized name). static std::string_view LookupLanguage(std::string_view lang); }; struct StringArgument { std::string Value; }; struct IntArgument { int Value; }; struct FloatArgument { double Value; }; class BasicTranslation { private: std::string mContent; public: BasicTranslation(std::string_view key); const std::string& GetString() const; const char* Get() const; }; class FormattedTranslation { public: using Element = std::variant; using Argument = std::string; private: std::vector mParsedElements; size_t mNumArguments; size_t mMinimumResultLen; public: FormattedTranslation(std::string_view key); std::string Format(std::span args); }; class NumericTranslation { public: // TODO };