1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-14 10:12:59 +02:00
vcmi/lib/texts/TextLocalizationContainer.h
2024-10-26 12:54:35 +00:00

151 lines
4.2 KiB
C++

/*
* 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 <typename Handler>
void serialize(Handler & h)
{
h & translatedText;
h & identifierModContext;
h & baseStringModContext;
}
};
/// map identifier -> localization
std::unordered_map<std::string, StringState> stringsLocalizations;
std::vector<const TextLocalizationContainer *> 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<typename ... Args>
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<std::string, std::map<std::string, std::string>> & 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 <typename Handler>
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