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 "Prerequisites/BsPrerequisitesUtil.h" |
6 | #include "Reflection/BsRTTIType.h" |
7 | #include "Serialization/BsSerializedObject.h" |
8 | #include "FileSystem/BsDataStream.h" |
9 | |
10 | namespace bs |
11 | { |
12 | /** @cond RTTI */ |
13 | /** @addtogroup RTTI-Impl-Utility |
14 | * @{ |
15 | */ |
16 | |
17 | class BS_UTILITY_EXPORT SerializedInstanceRTTI : public RTTIType <SerializedInstance, IReflectable, SerializedInstanceRTTI> |
18 | { |
19 | public: |
20 | const String& getRTTIName() override |
21 | { |
22 | static String name = "SerializedInstance" ; |
23 | return name; |
24 | } |
25 | |
26 | UINT32 getRTTIId() override |
27 | { |
28 | return TID_SerializedInstance; |
29 | } |
30 | |
31 | SPtr<IReflectable> newRTTIObject() override |
32 | { |
33 | return nullptr; |
34 | } |
35 | }; |
36 | |
37 | class BS_UTILITY_EXPORT SerializedFieldRTTI : public RTTIType <SerializedField, SerializedInstance, SerializedFieldRTTI> |
38 | { |
39 | private: |
40 | SPtr<DataStream> getData(SerializedField* obj, UINT32& size) |
41 | { |
42 | size = obj->size; |
43 | |
44 | return bs_shared_ptr_new<MemoryDataStream>(obj->value, obj->size, false); |
45 | } |
46 | |
47 | void setData(SerializedField* obj, const SPtr<DataStream>& value, UINT32 size) |
48 | { |
49 | obj->value = (UINT8*)bs_alloc(size); |
50 | obj->size = size; |
51 | obj->ownsMemory = true; |
52 | |
53 | value->read(obj->value, size); |
54 | } |
55 | |
56 | public: |
57 | SerializedFieldRTTI() |
58 | { |
59 | addDataBlockField("data" , 0, &SerializedFieldRTTI::getData, &SerializedFieldRTTI::setData); |
60 | } |
61 | |
62 | const String& getRTTIName() override |
63 | { |
64 | static String name = "SerializedField" ; |
65 | return name; |
66 | } |
67 | |
68 | UINT32 getRTTIId() override |
69 | { |
70 | return TID_SerializedField; |
71 | } |
72 | |
73 | SPtr<IReflectable> newRTTIObject() override |
74 | { |
75 | return bs_shared_ptr_new<SerializedField>(); |
76 | } |
77 | }; |
78 | |
79 | class BS_UTILITY_EXPORT SerializedDataBlockRTTI : public RTTIType <SerializedDataBlock, SerializedInstance, SerializedDataBlockRTTI> |
80 | { |
81 | private: |
82 | SPtr<DataStream> getData(SerializedDataBlock* obj, UINT32& size) |
83 | { |
84 | size = obj->size; |
85 | obj->stream->seek(obj->offset); |
86 | |
87 | return obj->stream; |
88 | } |
89 | |
90 | void setData(SerializedDataBlock* obj, const SPtr<DataStream>& value, UINT32 size) |
91 | { |
92 | UINT8* data = (UINT8*)bs_alloc(size); |
93 | SPtr<MemoryDataStream> memStream = bs_shared_ptr_new<MemoryDataStream>(data, size); |
94 | value->read(data, size); |
95 | |
96 | obj->stream = memStream; |
97 | obj->size = size; |
98 | obj->offset = 0; |
99 | } |
100 | public: |
101 | SerializedDataBlockRTTI() |
102 | { |
103 | addDataBlockField("data" , 0, &SerializedDataBlockRTTI::getData, &SerializedDataBlockRTTI::setData); |
104 | } |
105 | |
106 | const String& getRTTIName() override |
107 | { |
108 | static String name = "SerializedDataBlock" ; |
109 | return name; |
110 | } |
111 | |
112 | UINT32 getRTTIId() override |
113 | { |
114 | return TID_SerializedDataBlock; |
115 | } |
116 | |
117 | SPtr<IReflectable> newRTTIObject() override |
118 | { |
119 | return bs_shared_ptr_new<SerializedDataBlock>(); |
120 | } |
121 | }; |
122 | |
123 | class BS_UTILITY_EXPORT SerializedObjectRTTI : public RTTIType <SerializedObject, SerializedInstance, SerializedObjectRTTI> |
124 | { |
125 | private: |
126 | SerializedSubObject& getEntry(SerializedObject* obj, UINT32 arrayIdx) |
127 | { |
128 | return obj->subObjects[arrayIdx]; |
129 | } |
130 | |
131 | void setEntry(SerializedObject* obj, UINT32 arrayIdx, SerializedSubObject& val) |
132 | { |
133 | obj->subObjects[arrayIdx] = val; |
134 | } |
135 | |
136 | UINT32 getNumEntries(SerializedObject* obj) |
137 | { |
138 | return (UINT32)obj->subObjects.size(); |
139 | } |
140 | |
141 | void setNumEntries(SerializedObject* obj, UINT32 numEntries) |
142 | { |
143 | obj->subObjects = Vector<SerializedSubObject>(numEntries); |
144 | } |
145 | public: |
146 | SerializedObjectRTTI() |
147 | { |
148 | addReflectableArrayField("entries" , 1, &SerializedObjectRTTI::getEntry, &SerializedObjectRTTI::getNumEntries, |
149 | &SerializedObjectRTTI::setEntry, &SerializedObjectRTTI::setNumEntries); |
150 | } |
151 | |
152 | const String& getRTTIName() override |
153 | { |
154 | static String name = "SerializedObject" ; |
155 | return name; |
156 | } |
157 | |
158 | UINT32 getRTTIId() override |
159 | { |
160 | return TID_SerializedObject; |
161 | } |
162 | |
163 | SPtr<IReflectable> newRTTIObject() override |
164 | { |
165 | return bs_shared_ptr_new<SerializedObject>(); |
166 | } |
167 | }; |
168 | |
169 | class BS_UTILITY_EXPORT SerializedArrayRTTI : public RTTIType <SerializedArray, SerializedInstance, SerializedArrayRTTI> |
170 | { |
171 | private: |
172 | UINT32& getNumElements(SerializedArray* obj) |
173 | { |
174 | return obj->numElements; |
175 | } |
176 | |
177 | void setNumElements(SerializedArray* obj, UINT32& val) |
178 | { |
179 | obj->numElements = val; |
180 | } |
181 | |
182 | SerializedArrayEntry& getEntry(SerializedArray* obj, UINT32 arrayIdx) |
183 | { |
184 | return mSequentialEntries[arrayIdx]; |
185 | } |
186 | |
187 | void setEntry(SerializedArray* obj, UINT32 arrayIdx, SerializedArrayEntry& val) |
188 | { |
189 | obj->entries[val.index] = val; |
190 | } |
191 | |
192 | UINT32 getNumEntries(SerializedArray* obj) |
193 | { |
194 | return (UINT32)mSequentialEntries.size(); |
195 | } |
196 | |
197 | void setNumEntries(SerializedArray* obj, UINT32 numEntries) |
198 | { |
199 | obj->entries = UnorderedMap<UINT32, SerializedArrayEntry>(); |
200 | } |
201 | public: |
202 | SerializedArrayRTTI() |
203 | { |
204 | addPlainField("numElements" , 0, &SerializedArrayRTTI::getNumElements, &SerializedArrayRTTI::setNumElements); |
205 | addReflectableArrayField("entries" , 1, &SerializedArrayRTTI::getEntry, &SerializedArrayRTTI::getNumEntries, |
206 | &SerializedArrayRTTI::setEntry, &SerializedArrayRTTI::setNumEntries); |
207 | } |
208 | |
209 | void onSerializationStarted(IReflectable* obj, SerializationContext* context) override |
210 | { |
211 | SerializedArray* serializedArray = static_cast<SerializedArray*>(obj); |
212 | |
213 | for (auto& entry : serializedArray->entries) |
214 | mSequentialEntries.push_back(entry.second); |
215 | } |
216 | |
217 | const String& getRTTIName() override |
218 | { |
219 | static String name = "SerializedArray" ; |
220 | return name; |
221 | } |
222 | |
223 | UINT32 getRTTIId() override |
224 | { |
225 | return TID_SerializedArray; |
226 | } |
227 | |
228 | SPtr<IReflectable> newRTTIObject() override |
229 | { |
230 | return bs_shared_ptr_new<SerializedArray>(); |
231 | } |
232 | |
233 | private: |
234 | Vector<SerializedArrayEntry> mSequentialEntries; |
235 | }; |
236 | |
237 | class BS_UTILITY_EXPORT SerializedSubObjectRTTI : public RTTIType <SerializedSubObject, IReflectable, SerializedSubObjectRTTI> |
238 | { |
239 | private: |
240 | UINT32& getTypeId(SerializedSubObject* obj) |
241 | { |
242 | return obj->typeId; |
243 | } |
244 | |
245 | void setTypeId(SerializedSubObject* obj, UINT32& val) |
246 | { |
247 | obj->typeId = val; |
248 | } |
249 | |
250 | SerializedEntry& getEntry(SerializedSubObject* obj, UINT32 arrayIdx) |
251 | { |
252 | return mSequentialEntries[arrayIdx]; |
253 | } |
254 | |
255 | void setEntry(SerializedSubObject* obj, UINT32 arrayIdx, SerializedEntry& val) |
256 | { |
257 | obj->entries[val.fieldId] = val; |
258 | } |
259 | |
260 | UINT32 getNumEntries(SerializedSubObject* obj) |
261 | { |
262 | return (UINT32)mSequentialEntries.size(); |
263 | } |
264 | |
265 | void setNumEntries(SerializedSubObject* obj, UINT32 numEntries) |
266 | { |
267 | obj->entries = UnorderedMap<UINT32, SerializedEntry>(); |
268 | } |
269 | public: |
270 | SerializedSubObjectRTTI() |
271 | { |
272 | addPlainField("typeId" , 0, &SerializedSubObjectRTTI::getTypeId, &SerializedSubObjectRTTI::setTypeId); |
273 | addReflectableArrayField("entries" , 1, &SerializedSubObjectRTTI::getEntry, &SerializedSubObjectRTTI::getNumEntries, |
274 | &SerializedSubObjectRTTI::setEntry, &SerializedSubObjectRTTI::setNumEntries); |
275 | } |
276 | |
277 | void onSerializationStarted(IReflectable* obj, SerializationContext* context) override |
278 | { |
279 | SerializedSubObject* serializableObject = static_cast<SerializedSubObject*>(obj); |
280 | |
281 | for (auto& entry : serializableObject->entries) |
282 | mSequentialEntries.push_back(entry.second); |
283 | } |
284 | |
285 | const String& getRTTIName() override |
286 | { |
287 | static String name = "SerializedSubObject" ; |
288 | return name; |
289 | } |
290 | |
291 | UINT32 getRTTIId() override |
292 | { |
293 | return TID_SerializedSubObject; |
294 | } |
295 | |
296 | SPtr<IReflectable> newRTTIObject() override |
297 | { |
298 | return bs_shared_ptr_new<SerializedSubObject>(); |
299 | } |
300 | |
301 | private: |
302 | Vector<SerializedEntry> mSequentialEntries; |
303 | }; |
304 | |
305 | class BS_UTILITY_EXPORT SerializedEntryRTTI : public RTTIType <SerializedEntry, IReflectable, SerializedEntryRTTI> |
306 | { |
307 | private: |
308 | UINT32& getFieldId(SerializedEntry* obj) |
309 | { |
310 | return obj->fieldId; |
311 | } |
312 | |
313 | void setFieldId(SerializedEntry* obj, UINT32& val) |
314 | { |
315 | obj->fieldId = val; |
316 | } |
317 | |
318 | SPtr<SerializedInstance> getSerialized(SerializedEntry* obj) |
319 | { |
320 | return obj->serialized; |
321 | } |
322 | |
323 | void setSerialized(SerializedEntry* obj, SPtr<SerializedInstance> val) |
324 | { |
325 | obj->serialized = val; |
326 | } |
327 | |
328 | public: |
329 | SerializedEntryRTTI() |
330 | { |
331 | addPlainField("fieldId" , 0, &SerializedEntryRTTI::getFieldId, &SerializedEntryRTTI::setFieldId); |
332 | addReflectablePtrField("serialized" , 1, &SerializedEntryRTTI::getSerialized, &SerializedEntryRTTI::setSerialized); |
333 | } |
334 | |
335 | const String& getRTTIName() override |
336 | { |
337 | static String name = "SerializedEntry" ; |
338 | return name; |
339 | } |
340 | |
341 | UINT32 getRTTIId() override |
342 | { |
343 | return TID_SerializedEntry; |
344 | } |
345 | |
346 | SPtr<IReflectable> newRTTIObject() override |
347 | { |
348 | return bs_shared_ptr_new<SerializedEntry>(); |
349 | } |
350 | }; |
351 | |
352 | class BS_UTILITY_EXPORT SerializedArrayEntryRTTI : public RTTIType <SerializedArrayEntry, IReflectable, SerializedArrayEntryRTTI> |
353 | { |
354 | private: |
355 | UINT32& getArrayIdx(SerializedArrayEntry* obj) |
356 | { |
357 | return obj->index; |
358 | } |
359 | |
360 | void setArrayIdx(SerializedArrayEntry* obj, UINT32& val) |
361 | { |
362 | obj->index = val; |
363 | } |
364 | |
365 | SPtr<SerializedInstance> getSerialized(SerializedArrayEntry* obj) |
366 | { |
367 | return obj->serialized; |
368 | } |
369 | |
370 | void setSerialized(SerializedArrayEntry* obj, SPtr<SerializedInstance> val) |
371 | { |
372 | obj->serialized = val; |
373 | } |
374 | |
375 | public: |
376 | SerializedArrayEntryRTTI() |
377 | { |
378 | addPlainField("index" , 0, &SerializedArrayEntryRTTI::getArrayIdx, &SerializedArrayEntryRTTI::setArrayIdx); |
379 | addReflectablePtrField("serialized" , 1, &SerializedArrayEntryRTTI::getSerialized, &SerializedArrayEntryRTTI::setSerialized); |
380 | } |
381 | |
382 | const String& getRTTIName() override |
383 | { |
384 | static String name = "SerializedArrayEntry" ; |
385 | return name; |
386 | } |
387 | |
388 | UINT32 getRTTIId() override |
389 | { |
390 | return TID_SerializedArrayEntry; |
391 | } |
392 | |
393 | SPtr<IReflectable> newRTTIObject() override |
394 | { |
395 | return bs_shared_ptr_new<SerializedArrayEntry>(); |
396 | } |
397 | }; |
398 | |
399 | /** @} */ |
400 | /** @endcond */ |
401 | } |
402 | |