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/BsIReflectable.h"
7
8namespace bs
9{
10 struct SerializationContext;
11
12 /** @addtogroup Serialization
13 * @{
14 */
15
16 /** Base class for all data types used in intermediate IReflectable object representation. */
17 struct BS_UTILITY_EXPORT SerializedInstance : IReflectable
18 {
19 virtual ~SerializedInstance() = default;
20
21 /**
22 * Performs a deep clone of this object any any potential child objects.
23 *
24 * @param[in] cloneData If true the data contained by the objects will be cloned as well, instead of just
25 * meta-data. If false then both the original and the cloned instances will point to the
26 * same instances of data. The original will retain data ownership and it will go out of
27 * scope when the original does.
28 */
29 virtual SPtr<SerializedInstance> clone(bool cloneData = true) = 0;
30
31 /************************************************************************/
32 /* RTTI */
33 /************************************************************************/
34 public:
35 friend class SerializedInstanceRTTI;
36 static RTTITypeBase* getRTTIStatic();
37 RTTITypeBase* getRTTI() const override;
38 };
39
40 /** Contains data for a single field in a serialized object. */
41 struct BS_UTILITY_EXPORT SerializedEntry : IReflectable
42 {
43 SerializedEntry() = default;
44
45 UINT32 fieldId = 0;
46 SPtr<SerializedInstance> serialized;
47
48 /************************************************************************/
49 /* RTTI */
50 /************************************************************************/
51 public:
52 friend class SerializedEntryRTTI;
53 static RTTITypeBase* getRTTIStatic();
54 RTTITypeBase* getRTTI() const override;
55 };
56
57 /** Contains a sub-set of fields of a SerializedObject for a single class in a class hierarchy. */
58 struct BS_UTILITY_EXPORT SerializedSubObject : IReflectable
59 {
60 SerializedSubObject() = default;
61
62 UINT32 typeId = 0;
63 UnorderedMap<UINT32, SerializedEntry> entries;
64
65 /************************************************************************/
66 /* RTTI */
67 /************************************************************************/
68 public:
69 friend class SerializedSubObjectRTTI;
70 static RTTITypeBase* getRTTIStatic();
71 RTTITypeBase* getRTTI() const override;
72 };
73
74 /**
75 * Represents a serialized version of an IReflectable object. Data for all leaf fields will be serialized into raw
76 * memory but complex objects, their references and fields are available as their own serialized objects and can be
77 * iterated over, viewed, compared or modified. Serialized object can later be decoded back into a IReflectable object.
78 */
79 struct BS_UTILITY_EXPORT SerializedObject : SerializedInstance
80 {
81 /** Returns the RTTI type ID for the most-derived class of this object. */
82 UINT32 getRootTypeId() const;
83
84 /** @copydoc SerializedInstance::clone */
85 SPtr<SerializedInstance> clone(bool cloneData = true) override;
86
87 /**
88 * Decodes the serialized object back into its original IReflectable object form.
89 *
90 * @param[in] context Optional object that will be passed along to all serialized objects through
91 * their serialization callbacks. Can be used for controlling serialization,
92 * maintaining state or sharing information between objects during
93 * serialization.
94 */
95 SPtr<IReflectable> decode(SerializationContext* context = nullptr) const;
96
97 /**
98 * Serializes the provided object and returns its SerializedObject representation.
99 *
100 * @param[in] obj Object to serialize;
101 * @param[in] shallow If true then pointers to other IReflectable objects will not be followed. If false the
102 * entire hierarchy will be serialized.
103 * @param[in] context Optional object that will be passed along to all deserialized objects through
104 * their deserialization callbacks. Can be used for controlling deserialization,
105 * maintaining state or sharing information between objects during
106 * deserialization.
107 * @return Serialized version of @p obj.
108 */
109 static SPtr<SerializedObject> create(IReflectable& obj, bool shallow = false,
110 SerializationContext* context = nullptr);
111
112 Vector<SerializedSubObject> subObjects;
113
114 /************************************************************************/
115 /* RTTI */
116 /************************************************************************/
117 public:
118 friend class SerializedObjectRTTI;
119 static RTTITypeBase* getRTTIStatic();
120 RTTITypeBase* getRTTI() const override;
121 };
122
123 /** Contains data for a serialized value of a specific field or array entry. */
124 struct BS_UTILITY_EXPORT SerializedField : SerializedInstance
125 {
126 SerializedField() = default;
127
128 ~SerializedField()
129 {
130 if (ownsMemory && value != nullptr)
131 bs_free(value);
132 }
133
134 /** @copydoc SerializedInstance::clone */
135 SPtr<SerializedInstance> clone(bool cloneData = true) override;
136
137 UINT8* value = nullptr;
138 UINT32 size = 0;
139 bool ownsMemory = false;
140
141 /************************************************************************/
142 /* RTTI */
143 /************************************************************************/
144 public:
145 friend class SerializedFieldRTTI;
146 static RTTITypeBase* getRTTIStatic();
147 RTTITypeBase* getRTTI() const override;
148 };
149
150 /** Contains data for a serialized value of a data block field. */
151 struct BS_UTILITY_EXPORT SerializedDataBlock : SerializedInstance
152 {
153 SerializedDataBlock() = default;
154
155 /** @copydoc SerializedInstance::clone */
156 SPtr<SerializedInstance> clone(bool cloneData = true) override;
157
158 SPtr<DataStream> stream;
159 UINT32 offset = 0;
160 UINT32 size = 0;
161
162 /************************************************************************/
163 /* RTTI */
164 /************************************************************************/
165 public:
166 friend class SerializedDataBlockRTTI;
167 static RTTITypeBase* getRTTIStatic();
168 RTTITypeBase* getRTTI() const override;
169 };
170
171 /** A serialized value representing a single entry in an array. */
172 struct BS_UTILITY_EXPORT SerializedArrayEntry : IReflectable
173 {
174 SerializedArrayEntry() = default;
175
176 UINT32 index = 0;
177 SPtr<SerializedInstance> serialized;
178
179 /************************************************************************/
180 /* RTTI */
181 /************************************************************************/
182 public:
183 friend class SerializedArrayEntryRTTI;
184 static RTTITypeBase* getRTTIStatic();
185 RTTITypeBase* getRTTI() const override;
186 };
187
188 /** A serialized array containing a list of all its entries. */
189 struct BS_UTILITY_EXPORT SerializedArray : SerializedInstance
190 {
191 SerializedArray() = default;
192
193 /** @copydoc SerializedInstance::clone */
194 SPtr<SerializedInstance> clone(bool cloneData = true) override;
195
196 UnorderedMap<UINT32, SerializedArrayEntry> entries;
197 UINT32 numElements = 0;
198
199 /************************************************************************/
200 /* RTTI */
201 /************************************************************************/
202 public:
203 friend class SerializedArrayRTTI;
204 static RTTITypeBase* getRTTIStatic();
205 RTTITypeBase* getRTTI() const override;
206 };
207
208 /** @} */
209}
210