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 "Reflection/BsRTTIType.h"
7#include "Localization/BsStringTable.h"
8
9namespace bs
10{
11 /** @cond RTTI */
12 /** @addtogroup RTTI-Impl-Core
13 * @{
14 */
15
16 class BS_CORE_EXPORT StringTableRTTI : public RTTIType<StringTable, Resource, StringTableRTTI>
17 {
18 private:
19 Language& getActiveLanguage(StringTable* obj) { return obj->mActiveLanguage; }
20 void setActiveLanguage(StringTable* obj, Language& val) { obj->mActiveLanguage = val; }
21
22 LanguageData& getLanguageData(StringTable* obj, UINT32 idx) { return obj->mAllLanguages[idx]; }
23 void setLanguageData(StringTable* obj, UINT32 idx, LanguageData& val) { obj->mAllLanguages[idx] = val; }
24 UINT32 getNumLanguages(StringTable* obj) { return (UINT32)Language::Count; }
25 void setNumLanguages(StringTable* obj, UINT32 val) { /* Do nothing */ }
26
27 UnorderedSet<String>& getIdentifiers(StringTable* obj) { return obj->mIdentifiers; }
28 void setIdentifiers(StringTable* obj, UnorderedSet<String>& val) { obj->mIdentifiers = val; }
29
30 public:
31 StringTableRTTI()
32 {
33 addPlainField("mActiveLanguage", 0, &StringTableRTTI::getActiveLanguage, &StringTableRTTI::setActiveLanguage);
34 addPlainArrayField("mLanguageData", 1, &StringTableRTTI::getLanguageData, &StringTableRTTI::getNumLanguages,
35 &StringTableRTTI::setLanguageData, &StringTableRTTI::setNumLanguages);
36 addPlainField("mIdentifiers", 2, &StringTableRTTI::getIdentifiers, &StringTableRTTI::setIdentifiers);
37 }
38
39 void onDeserializationEnded(IReflectable* obj, SerializationContext* context) override
40 {
41 StringTable* stringTable = static_cast<StringTable*>(obj);
42 stringTable->setActiveLanguage(stringTable->mActiveLanguage);
43 }
44
45 const String& getRTTIName() override
46 {
47 static String name = "StringTable";
48 return name;
49 }
50
51 UINT32 getRTTIId() override
52 {
53 return TID_StringTable;
54 }
55
56 SPtr<IReflectable> newRTTIObject() override
57 {
58 return StringTable::_createPtr();
59 }
60 };
61
62 /**
63 * RTTIPlainType for LanguageData.
64 *
65 * @see RTTIPlainType
66 */
67 template<>
68 struct RTTIPlainType<LanguageData>
69 {
70 enum { id = TID_LanguageData }; enum { hasDynamicSize = 1 };
71
72 /** @copydoc RTTIPlainType::toMemory */
73 static void toMemory(const LanguageData& data, char* memory)
74 {
75 UINT32 size = sizeof(UINT32);
76 char* memoryStart = memory;
77 memory += sizeof(UINT32);
78
79 UINT32 numElements = (UINT32)data.strings.size();
80 memory = rttiWriteElem(numElements, memory, size);
81
82 for (auto& entry : data.strings)
83 {
84 memory = rttiWriteElem(entry.first, memory, size);
85 memory = rttiWriteElem(*entry.second, memory, size);
86 }
87
88 memcpy(memoryStart, &size, sizeof(UINT32));
89 }
90
91 /** @copydoc RTTIPlainType::fromMemory */
92 static UINT32 fromMemory(LanguageData& data, char* memory)
93 {
94 UINT32 size = 0;
95 memory = rttiReadElem(size, memory);
96
97 UINT32 numElements = 0;
98 memory = rttiReadElem(numElements, memory);
99
100 data.strings.clear();
101 for (UINT32 i = 0; i < numElements; i++)
102 {
103 String identifier;
104 memory = rttiReadElem(identifier, memory);
105
106 SPtr<LocalizedStringData> entryData = bs_shared_ptr_new<LocalizedStringData>();
107 memory = rttiReadElem(*entryData, memory);
108
109 data.strings[identifier] = entryData;
110 }
111
112 return size;
113 }
114
115 /** @copydoc RTTIPlainType::getDynamicSize */
116 static UINT32 getDynamicSize(const LanguageData& data)
117 {
118 UINT64 dataSize = sizeof(UINT32) * 2;
119
120 for (auto& entry : data.strings)
121 {
122 dataSize += rttiGetElemSize(entry.first);
123 dataSize += rttiGetElemSize(*entry.second);
124 }
125
126 assert(dataSize <= std::numeric_limits<UINT32>::max());
127
128 return (UINT32)dataSize;
129 }
130 };
131
132 /**
133 * RTTIPlainType for LocalizedStringData.
134 *
135 * @see RTTIPlainType
136 */
137 template<>
138 struct RTTIPlainType<LocalizedStringData>
139 {
140 enum { id = TID_LocalizedStringData }; enum { hasDynamicSize = 1 };
141
142 /** @copydoc RTTIPlainType::toMemory */
143 static void toMemory(const LocalizedStringData& data, char* memory)
144 {
145 UINT32 size = sizeof(UINT32);
146 char* memoryStart = memory;
147 memory += sizeof(UINT32);
148
149 memory = rttiWriteElem(data.string, memory, size);
150 memory = rttiWriteElem(data.numParameters, memory, size);
151
152 for (UINT32 i = 0; i < data.numParameters; i++)
153 memory = rttiWriteElem(data.parameterOffsets[i], memory, size);
154
155 memcpy(memoryStart, &size, sizeof(UINT32));
156 }
157
158 /** @copydoc RTTIPlainType::fromMemory */
159 static UINT32 fromMemory(LocalizedStringData& data, char* memory)
160 {
161 if (data.parameterOffsets != nullptr)
162 bs_deleteN(data.parameterOffsets, data.numParameters);
163
164 UINT32 size = 0;
165 memory = rttiReadElem(size, memory);
166
167 memory = rttiReadElem(data.string, memory);
168 memory = rttiReadElem(data.numParameters, memory);
169
170 data.parameterOffsets = bs_newN<LocalizedStringData::ParamOffset>(data.numParameters);
171 for (UINT32 i = 0; i < data.numParameters; i++)
172 memory = rttiReadElem(data.parameterOffsets[i], memory);
173
174 return size;
175 }
176
177 /** @copydoc RTTIPlainType::getDynamicSize */
178 static UINT32 getDynamicSize(const LocalizedStringData& data)
179 {
180 UINT64 dataSize = sizeof(UINT32);
181
182 dataSize += rttiGetElemSize(data.string);
183 dataSize += rttiGetElemSize(data.numParameters);
184
185 for (UINT32 i = 0; i < data.numParameters; i++)
186 dataSize = rttiGetElemSize(data.parameterOffsets[i]);
187
188 assert(dataSize <= std::numeric_limits<UINT32>::max());
189
190 return (UINT32)dataSize;
191 }
192 };
193
194 BS_ALLOW_MEMCPY_SERIALIZATION(LocalizedStringData::ParamOffset);
195
196 /** @} */
197 /** @endcond */
198}