TextLocalizationContainer.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. /*
  2. * TextLocalizationContainer.h, part of VCMI engine
  3. *
  4. * Authors: listed in file AUTHORS in main folder
  5. *
  6. * License: GNU General Public License v2.0 or later
  7. * Full text of license available in license.txt file, in main folder
  8. *
  9. */
  10. #pragma once
  11. #include "TextIdentifier.h"
  12. VCMI_LIB_NAMESPACE_BEGIN
  13. class JsonNode;
  14. class DLL_LINKAGE TextLocalizationContainer
  15. {
  16. protected:
  17. static std::recursive_mutex globalTextMutex;
  18. struct StringState
  19. {
  20. /// Human-readable string that was added on registration
  21. std::string baseValue;
  22. /// Language of base string
  23. std::string baseLanguage;
  24. /// Translated human-readable string
  25. std::string overrideValue;
  26. /// Language of the override string
  27. std::string overrideLanguage;
  28. /// ID of mod that created this string
  29. std::string modContext;
  30. template <typename Handler>
  31. void serialize(Handler & h)
  32. {
  33. h & baseValue;
  34. h & baseLanguage;
  35. h & modContext;
  36. }
  37. };
  38. /// map identifier -> localization
  39. std::unordered_map<std::string, StringState> stringsLocalizations;
  40. std::vector<const TextLocalizationContainer *> subContainers;
  41. /// add selected string to internal storage as high-priority strings
  42. void registerStringOverride(const std::string & modContext, const std::string & language, const TextIdentifier & UID, const std::string & localized);
  43. std::string getModLanguage(const std::string & modContext);
  44. // returns true if identifier with such name was registered, even if not translated to current language
  45. bool identifierExists(const TextIdentifier & UID) const;
  46. public:
  47. /// validates translation of specified language for specified mod
  48. /// returns true if localization is valid and complete
  49. /// any error messages will be written to log file
  50. bool validateTranslation(const std::string & language, const std::string & modContext, JsonNode const & file) const;
  51. /// Loads translation from provided json
  52. /// Any entries loaded by this will have priority over texts registered normally
  53. void loadTranslationOverrides(const std::string & language, const std::string & modContext, JsonNode const & file);
  54. /// add selected string to internal storage
  55. void registerString(const std::string & modContext, const TextIdentifier & UID, const std::string & localized);
  56. void registerString(const std::string & modContext, const TextIdentifier & UID, const std::string & localized, const std::string & language);
  57. /// returns translated version of a string that can be displayed to user
  58. template<typename ... Args>
  59. std::string translate(std::string arg1, Args ... args) const
  60. {
  61. TextIdentifier id(arg1, args ...);
  62. return deserialize(id);
  63. }
  64. /// converts identifier into user-readable string
  65. const std::string & deserialize(const TextIdentifier & identifier) const;
  66. /// Debug method, returns all currently stored texts
  67. /// Format: [mod ID][string ID] -> human-readable text
  68. void exportAllTexts(std::map<std::string, std::map<std::string, std::string>> & storage) const;
  69. /// Add or override subcontainer which can store identifiers
  70. void addSubContainer(const TextLocalizationContainer & container);
  71. /// Remove subcontainer with give name
  72. void removeSubContainer(const TextLocalizationContainer & container);
  73. void jsonSerialize(JsonNode & dest) const;
  74. template <typename Handler>
  75. void serialize(Handler & h)
  76. {
  77. std::lock_guard globalLock(globalTextMutex);
  78. if (h.version >= Handler::Version::SIMPLE_TEXT_CONTAINER_SERIALIZATION)
  79. {
  80. h & stringsLocalizations;
  81. }
  82. else
  83. {
  84. std::string key;
  85. int64_t sz = stringsLocalizations.size();
  86. if (h.version >= Handler::Version::REMOVE_TEXT_CONTAINER_SIZE_T)
  87. {
  88. int64_t size = sz;
  89. h & size;
  90. sz = size;
  91. }
  92. else
  93. {
  94. h & sz;
  95. }
  96. if(h.saving)
  97. {
  98. for(auto & s : stringsLocalizations)
  99. {
  100. key = s.first;
  101. h & key;
  102. h & s.second;
  103. }
  104. }
  105. else
  106. {
  107. for(size_t i = 0; i < sz; ++i)
  108. {
  109. h & key;
  110. h & stringsLocalizations[key];
  111. }
  112. }
  113. }
  114. }
  115. };
  116. class DLL_LINKAGE TextContainerRegistrable : public TextLocalizationContainer
  117. {
  118. public:
  119. TextContainerRegistrable();
  120. ~TextContainerRegistrable();
  121. TextContainerRegistrable(const TextContainerRegistrable & other);
  122. TextContainerRegistrable(TextContainerRegistrable && other) noexcept;
  123. TextContainerRegistrable& operator=(const TextContainerRegistrable & b) = default;
  124. };
  125. VCMI_LIB_NAMESPACE_END