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
10namespace 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