1//************************************ bs::framework - Copyright 2018 Marko Pintera **************************************//
2//*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********//
3#pragma once
4
5#include "BsCorePrerequisites.h"
6#include "Resources/BsResource.h"
7
8namespace bs
9{
10 /** @addtogroup Localization
11 * @{
12 */
13
14 /**
15 * A set of all languages that localized strings can be translated to. Loosely based on ISO 639-1 two letter language
16 * codes.
17 */
18 enum class BS_SCRIPT_EXPORT(m:Localization) Language
19 {
20 Afar,
21 Abkhazian,
22 Avestan,
23 Afrikaans,
24 Akan,
25 Amharic,
26 Aragonese,
27 Arabic,
28 Assamese,
29 Avaric,
30 Aymara,
31 Azerbaijani,
32 Bashkir,
33 Belarusian,
34 Bulgarian,
35 Bihari,
36 Bislama,
37 Bambara,
38 Bengali,
39 Tibetan,
40 Breton,
41 Bosnian,
42 Catalan,
43 Chechen,
44 Chamorro,
45 Corsican,
46 Cree,
47 Czech,
48 ChurchSlavic,
49 Chuvash,
50 Welsh,
51 Danish,
52 German,
53 Maldivian,
54 Bhutani,
55 Ewe,
56 Greek,
57 EnglishUK,
58 EnglishUS,
59 Esperanto,
60 Spanish,
61 Estonian,
62 Basque,
63 Persian,
64 Fulah,
65 Finnish,
66 Fijian,
67 Faroese,
68 French,
69 WesternFrisian,
70 Irish,
71 ScottishGaelic,
72 Galician,
73 Guarani,
74 Gujarati,
75 Manx,
76 Hausa,
77 Hebrew,
78 Hindi,
79 HiriMotu,
80 Croatian,
81 Haitian,
82 Hungarian,
83 Armenian,
84 Herero,
85 Interlingua,
86 Indonesian,
87 Interlingue,
88 Igbo,
89 SichuanYi,
90 Inupiak,
91 Ido,
92 Icelandic,
93 Italian,
94 Inuktitut,
95 Japanese,
96 Javanese,
97 Georgian,
98 Kongo,
99 Kikuyu,
100 Kuanyama,
101 Kazakh,
102 Kalaallisut,
103 Cambodian,
104 Kannada,
105 Korean,
106 Kanuri,
107 Kashmiri,
108 Kurdish,
109 Komi,
110 Cornish,
111 Kirghiz,
112 Latin,
113 Luxembourgish,
114 Ganda,
115 Limburgish,
116 Lingala,
117 Laotian,
118 Lithuanian,
119 LubaKatanga,
120 Latvian,
121 Malagasy,
122 Marshallese,
123 Maori,
124 Macedonian,
125 Malayalam,
126 Mongolian,
127 Moldavian,
128 Marathi,
129 Malay,
130 Maltese,
131 Burmese,
132 Nauru,
133 NorwegianBokmal,
134 Ndebele,
135 Nepali,
136 Ndonga,
137 Dutch,
138 NorwegianNynorsk,
139 Norwegian,
140 Navaho,
141 Nyanja,
142 Provencal,
143 Ojibwa,
144 Oromo,
145 Oriya,
146 Ossetic,
147 Punjabi,
148 Pali,
149 Polish,
150 Pushto,
151 Portuguese,
152 Quechua,
153 Romansh,
154 Kirundi,
155 Romanian,
156 Russian,
157 Kinyarwanda,
158 Sanskrit,
159 Sardinian,
160 Sindhi,
161 NorthernSami,
162 Sangro,
163 Sinhalese,
164 Slovak,
165 Slovenian,
166 Samoan,
167 Shona,
168 Somali,
169 Albanian,
170 Serbian,
171 Swati,
172 Sesotho,
173 Sundanese,
174 Swedish,
175 Swahili,
176 Tamil,
177 Telugu,
178 Tajik,
179 Thai,
180 Tigrinya,
181 Turkmen,
182 Tagalog,
183 Setswana,
184 Tonga,
185 Turkish,
186 Tsonga,
187 Tatar,
188 Twi,
189 Tahitian,
190 Uighur,
191 Ukrainian,
192 Urdu,
193 Uzbek,
194 Venda,
195 Vietnamese,
196 Volapuk,
197 Walloon,
198 Wolof,
199 Xhosa,
200 Yiddish,
201 Yoruba,
202 Zhuang,
203 Chinese,
204 Zulu,
205 Count // Number of entries
206 };
207
208 /** @} */
209 /** @addtogroup Localization-Internal
210 * @{
211 */
212
213 /**
214 * Internal data used for representing a localized string instance. for example a specific instance of a localized
215 * string using specific parameters.
216 */
217 struct LocalizedStringData
218 {
219 struct ParamOffset
220 {
221 ParamOffset() = default;
222
223 ParamOffset(UINT32 _paramIdx, UINT32 _location)
224 :paramIdx(_paramIdx), location(_location)
225 { }
226
227 UINT32 paramIdx = 0;
228 UINT32 location = 0;
229 };
230
231 LocalizedStringData() = default;
232 ~LocalizedStringData();
233
234 String string;
235 UINT32 numParameters = 0;
236 ParamOffset* parameterOffsets = nullptr;
237
238 void concatenateString(String& outputString, String* parameters, UINT32 numParameterValues) const;
239 void updateString(const String& string);
240 };
241
242 /** Data for a single language in the string table. */
243 struct LanguageData
244 {
245 UnorderedMap<String, SPtr<LocalizedStringData>> strings;
246 };
247
248 /** @} */
249 /** @addtogroup Localization
250 * @{
251 */
252
253 /** Used for string localization. Stores strings and their translations in various languages. */
254 class BS_CORE_EXPORT BS_SCRIPT_EXPORT(m:Localization) StringTable : public Resource
255 {
256 // TODO - When editing string table I will need to ensure that all languages of the same string have the same number of parameters
257
258 public:
259 StringTable();
260 ~StringTable();
261
262 /**
263 * Checks does the string table contain the provided identifier.
264 *
265 * @param[in] identifier Identifier to look for.
266 * @return True if the identifier exists in the table, false otherwise.
267 */
268 BS_SCRIPT_EXPORT()
269 bool contains(const String& identifier);
270
271 /** Returns a total number of strings in the table. */
272 BS_SCRIPT_EXPORT(n:NumStrings,pr:getter)
273 UINT32 getNumStrings() const { return (UINT32)mIdentifiers.size(); }
274
275 /** Returns all identifiers that the string table contains localized strings for. */
276 BS_SCRIPT_EXPORT(n:Identifiers,pr:getter)
277 Vector<String> getIdentifiers() const;
278
279 /** Adds or modifies string translation for the specified language. */
280 BS_SCRIPT_EXPORT()
281 void setString(const String& identifier, Language language, const String& value);
282
283 /** Returns a string translation for the specified language. Returns the identifier itself if one doesn't exist. */
284 BS_SCRIPT_EXPORT()
285 String getString(const String& identifier, Language language);
286
287 /** Removes the string described by identifier, from all languages. */
288 BS_SCRIPT_EXPORT()
289 void removeString(const String& identifier);
290
291 /**
292 * Gets a string data for the specified string identifier and currently active language.
293 *
294 * @param[in] identifier Unique string identifier.
295 * @param[in] insertIfNonExisting If true, a new string data for the specified identifier and language will be
296 * added to the table if data doesn't already exist. The data will use the
297 * identifier as the translation string.
298 * @return The string data. Don't store reference to this data as it may get deleted.
299 */
300 SPtr<LocalizedStringData> getStringData(const String& identifier, bool insertIfNonExisting = true);
301
302 /**
303 * Gets a string data for the specified string identifier and language.
304 *
305 * @param[in] identifier Unique string identifier.
306 * @param[in] language Language.
307 * @param[in] insertIfNonExisting If true, a new string data for the specified identifier and language will be
308 * added to the table if data doesn't already exist. The data will use the
309 * identifier as the translation string.
310 * @return The string data. Don't store reference to this data as it may get deleted.
311 */
312 SPtr<LocalizedStringData> getStringData(const String& identifier, Language language, bool insertIfNonExisting = true);
313
314 /** Creates a new empty string table resource. */
315 BS_SCRIPT_EXPORT(ec:StringTable)
316 static HStringTable create();
317
318 static const Language DEFAULT_LANGUAGE;
319 public: // ***** INTERNAL ******
320 /** @name Internal
321 * @{
322 */
323
324 /**
325 * Creates a new empty string table resource.
326 *
327 * @note Internal method. Use create() for normal use.
328 */
329 static SPtr<StringTable> _createPtr();
330
331 /** @} */
332 private:
333 friend class HString;
334 friend class StringTableManager;
335
336 /** Gets the currently active language. */
337 Language getActiveLanguage() const { return mActiveLanguage; }
338
339 /** Changes the currently active language. Any newly created strings will use this value. */
340 void setActiveLanguage(Language language);
341
342 Language mActiveLanguage;
343 LanguageData* mActiveLanguageData;
344 LanguageData* mDefaultLanguageData;
345
346 LanguageData* mAllLanguages;
347
348 UnorderedSet<String> mIdentifiers;
349
350 /************************************************************************/
351 /* SERIALIZATION */
352 /************************************************************************/
353 public:
354 friend class StringTableRTTI;
355 static RTTITypeBase* getRTTIStatic();
356 RTTITypeBase* getRTTI() const override;
357 };
358
359 /** @} */
360}