File: TextLocalizationContainer.h

package info (click to toggle)
vcmi 1.6.5%2Bdfsg-2
  • links: PTS, VCS
  • area: contrib
  • in suites: forky, sid, trixie
  • size: 32,060 kB
  • sloc: cpp: 238,971; python: 265; sh: 224; xml: 157; ansic: 78; objc: 61; makefile: 49
file content (150 lines) | stat: -rw-r--r-- 4,329 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
/*
 * 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