2024-07-20 14:55:17 +02:00
|
|
|
/*
|
|
|
|
* 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
|
2024-09-30 19:07:54 +02:00
|
|
|
std::string translatedText;
|
2024-07-20 14:55:17 +02:00
|
|
|
|
|
|
|
/// ID of mod that created this string
|
2024-09-30 19:07:54 +02:00
|
|
|
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;
|
2024-07-20 14:55:17 +02:00
|
|
|
|
2024-10-26 13:50:08 +02:00
|
|
|
bool overriden = false;
|
|
|
|
|
2024-07-20 14:55:17 +02:00
|
|
|
template <typename Handler>
|
|
|
|
void serialize(Handler & h)
|
|
|
|
{
|
2024-09-30 19:07:54 +02:00
|
|
|
h & translatedText;
|
|
|
|
h & identifierModContext;
|
|
|
|
h & baseStringModContext;
|
2024-07-20 14:55:17 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
/// 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
|
2024-10-26 13:50:08 +02:00
|
|
|
void registerStringOverride(const std::string & modContext, const TextIdentifier & UID, const std::string & localized, const std::string & language);
|
2024-07-20 14:55:17 +02:00
|
|
|
|
|
|
|
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
|
2024-10-26 13:50:08 +02:00
|
|
|
void loadTranslationOverrides(const std::string & modContext, const std::string & language, JsonNode const & file);
|
2024-07-20 14:55:17 +02:00
|
|
|
|
|
|
|
/// add selected string to internal storage
|
2024-09-30 12:21:10 +02:00
|
|
|
void registerString(const std::string & modContext, const TextIdentifier & UID, const JsonNode & localized);
|
2024-07-20 14:55:17 +02:00
|
|
|
void registerString(const std::string & modContext, const TextIdentifier & UID, const std::string & localized);
|
2024-09-30 19:07:54 +02:00
|
|
|
void registerString(const std::string & identifierModContext, const std::string & localizedStringModContext, const TextIdentifier & UID, const std::string & localized);
|
2024-07-20 14:55:17 +02:00
|
|
|
|
|
|
|
/// 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 ...);
|
2024-09-30 19:07:54 +02:00
|
|
|
return translateString(id);
|
2024-07-20 14:55:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/// converts identifier into user-readable string
|
2024-09-30 19:07:54 +02:00
|
|
|
const std::string & translateString(const TextIdentifier & identifier) const;
|
2024-07-20 14:55:17 +02:00
|
|
|
|
|
|
|
/// Debug method, returns all currently stored texts
|
|
|
|
/// Format: [mod ID][string ID] -> human-readable text
|
2024-10-26 13:50:08 +02:00
|
|
|
void exportAllTexts(std::map<std::string, std::map<std::string, std::string>> & storage, bool onlyMissing) const;
|
2024-07-20 14:55:17 +02:00
|
|
|
|
|
|
|
/// 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)
|
|
|
|
{
|
2024-08-12 20:26:30 +02:00
|
|
|
std::lock_guard globalLock(globalTextMutex);
|
2024-07-20 14:55:17 +02:00
|
|
|
|
|
|
|
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)
|
|
|
|
{
|
2024-08-12 20:26:30 +02:00
|
|
|
for(auto & s : stringsLocalizations)
|
2024-07-20 14:55:17 +02:00
|
|
|
{
|
|
|
|
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
|