/* * TextLocalizationContainer.h, part of VCMI engine * * Authors: listed in file AUTHORS in main folder * * License: GNU General Public License v2.0 or later * Full text of license available in license.txt file, in main folder * */ #pragma once #include "TextIdentifier.h" VCMI_LIB_NAMESPACE_BEGIN class JsonNode; class DLL_LINKAGE TextLocalizationContainer { protected: static std::recursive_mutex globalTextMutex; struct StringState { /// Human-readable string that was added on registration std::string translatedText; /// ID of mod that created this string std::string identifierModContext; /// ID of mod that provides original, untranslated version of this string /// Different from identifierModContext if mod has modified object from another mod (e.g. rebalance mods) std::string baseStringModContext; bool overriden = false; template void serialize(Handler & h) { h & translatedText; h & identifierModContext; h & baseStringModContext; } }; /// map identifier -> localization std::unordered_map stringsLocalizations; std::vector subContainers; /// add selected string to internal storage as high-priority strings void registerStringOverride(const std::string & modContext, const TextIdentifier & UID, const std::string & localized, const std::string & language); std::string getModLanguage(const std::string & modContext); // returns true if identifier with such name was registered, even if not translated to current language bool identifierExists(const TextIdentifier & UID) const; public: /// Loads translation from provided json /// Any entries loaded by this will have priority over texts registered normally void loadTranslationOverrides(const std::string & modContext, const std::string & language, JsonNode const & file); /// add selected string to internal storage void registerString(const std::string & modContext, const TextIdentifier & UID, const JsonNode & localized); void registerString(const std::string & modContext, const TextIdentifier & UID, const std::string & localized); void registerString(const std::string & identifierModContext, const std::string & localizedStringModContext, const TextIdentifier & UID, const std::string & localized); /// returns translated version of a string that can be displayed to user template std::string translate(std::string arg1, Args ... args) const { TextIdentifier id(arg1, args ...); return translateString(id); } /// converts identifier into user-readable string const std::string & translateString(const TextIdentifier & identifier) const; /// Debug method, returns all currently stored texts /// Format: [mod ID][string ID] -> human-readable text void exportAllTexts(std::map> & storage, bool onlyMissing) const; /// Add or override subcontainer which can store identifiers void addSubContainer(const TextLocalizationContainer & container); /// Remove subcontainer with give name void removeSubContainer(const TextLocalizationContainer & container); void jsonSerialize(JsonNode & dest) const; template void serialize(Handler & h) { std::lock_guard globalLock(globalTextMutex); if (h.version >= Handler::Version::SIMPLE_TEXT_CONTAINER_SERIALIZATION) { h & stringsLocalizations; } else { std::string key; int64_t sz = stringsLocalizations.size(); if (h.version >= Handler::Version::REMOVE_TEXT_CONTAINER_SIZE_T) { int64_t size = sz; h & size; sz = size; } else { h & sz; } if(h.saving) { for(auto & s : stringsLocalizations) { key = s.first; h & key; h & s.second; } } else { for(size_t i = 0; i < sz; ++i) { h & key; h & stringsLocalizations[key]; } } } } }; class DLL_LINKAGE TextContainerRegistrable : public TextLocalizationContainer { public: TextContainerRegistrable(); ~TextContainerRegistrable(); TextContainerRegistrable(const TextContainerRegistrable & other); TextContainerRegistrable(TextContainerRegistrable && other) noexcept; TextContainerRegistrable& operator=(const TextContainerRegistrable & b) = default; }; VCMI_LIB_NAMESPACE_END