Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/jolt_physics/Jolt/ObjectStream/ObjectStream.h
21075 views
1
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
2
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
3
// SPDX-License-Identifier: MIT
4
5
#pragma once
6
7
#include <Jolt/Core/StaticArray.h>
8
#include <Jolt/Core/Reference.h>
9
#include <Jolt/Core/RTTI.h>
10
#include <Jolt/Core/NonCopyable.h>
11
#include <Jolt/ObjectStream/SerializableAttribute.h>
12
13
#ifdef JPH_OBJECT_STREAM
14
15
JPH_NAMESPACE_BEGIN
16
17
/// Base class for object stream input and output streams.
18
class JPH_EXPORT ObjectStream : public NonCopyable
19
{
20
public:
21
/// Stream type
22
enum class EStreamType
23
{
24
Text,
25
Binary,
26
};
27
28
protected:
29
/// Destructor
30
virtual ~ObjectStream() = default;
31
32
/// Identifier for objects
33
using Identifier = uint32;
34
35
static constexpr int sVersion = 1;
36
static constexpr int sRevision = 0;
37
static constexpr Identifier sNullIdentifier = 0;
38
};
39
40
/// Interface class for reading from an object stream
41
class JPH_EXPORT IObjectStreamIn : public ObjectStream
42
{
43
public:
44
///@name Input type specific operations
45
virtual bool ReadDataType(EOSDataType &outType) = 0;
46
virtual bool ReadName(String &outName) = 0;
47
virtual bool ReadIdentifier(Identifier &outIdentifier) = 0;
48
virtual bool ReadCount(uint32 &outCount) = 0;
49
50
///@name Read primitives
51
virtual bool ReadPrimitiveData(uint8 &outPrimitive) = 0;
52
virtual bool ReadPrimitiveData(uint16 &outPrimitive) = 0;
53
virtual bool ReadPrimitiveData(int &outPrimitive) = 0;
54
virtual bool ReadPrimitiveData(uint32 &outPrimitive) = 0;
55
virtual bool ReadPrimitiveData(uint64 &outPrimitive) = 0;
56
virtual bool ReadPrimitiveData(float &outPrimitive) = 0;
57
virtual bool ReadPrimitiveData(double &outPrimitive) = 0;
58
virtual bool ReadPrimitiveData(bool &outPrimitive) = 0;
59
virtual bool ReadPrimitiveData(String &outPrimitive) = 0;
60
virtual bool ReadPrimitiveData(Float3 &outPrimitive) = 0;
61
virtual bool ReadPrimitiveData(Float4 &outPrimitive) = 0;
62
virtual bool ReadPrimitiveData(Double3 &outPrimitive) = 0;
63
virtual bool ReadPrimitiveData(Vec3 &outPrimitive) = 0;
64
virtual bool ReadPrimitiveData(DVec3 &outPrimitive) = 0;
65
virtual bool ReadPrimitiveData(Vec4 &outPrimitive) = 0;
66
virtual bool ReadPrimitiveData(UVec4 &outPrimitive) = 0;
67
virtual bool ReadPrimitiveData(Quat &outPrimitive) = 0;
68
virtual bool ReadPrimitiveData(Mat44 &outPrimitive) = 0;
69
virtual bool ReadPrimitiveData(DMat44 &outPrimitive) = 0;
70
71
///@name Read compounds
72
virtual bool ReadClassData(const char *inClassName, void *inInstance) = 0;
73
virtual bool ReadPointerData(const RTTI *inRTTI, void **inPointer, int inRefCountOffset = -1) = 0;
74
};
75
76
/// Interface class for writing to an object stream
77
class JPH_EXPORT IObjectStreamOut : public ObjectStream
78
{
79
public:
80
///@name Output type specific operations
81
virtual void WriteDataType(EOSDataType inType) = 0;
82
virtual void WriteName(const char *inName) = 0;
83
virtual void WriteIdentifier(Identifier inIdentifier) = 0;
84
virtual void WriteCount(uint32 inCount) = 0;
85
86
///@name Write primitives
87
virtual void WritePrimitiveData(const uint8 &inPrimitive) = 0;
88
virtual void WritePrimitiveData(const uint16 &inPrimitive) = 0;
89
virtual void WritePrimitiveData(const int &inPrimitive) = 0;
90
virtual void WritePrimitiveData(const uint32 &inPrimitive) = 0;
91
virtual void WritePrimitiveData(const uint64 &inPrimitive) = 0;
92
virtual void WritePrimitiveData(const float &inPrimitive) = 0;
93
virtual void WritePrimitiveData(const double &inPrimitive) = 0;
94
virtual void WritePrimitiveData(const bool &inPrimitive) = 0;
95
virtual void WritePrimitiveData(const String &inPrimitive) = 0;
96
virtual void WritePrimitiveData(const Float3 &inPrimitive) = 0;
97
virtual void WritePrimitiveData(const Float4 &inPrimitive) = 0;
98
virtual void WritePrimitiveData(const Double3 &inPrimitive) = 0;
99
virtual void WritePrimitiveData(const Vec3 &inPrimitive) = 0;
100
virtual void WritePrimitiveData(const DVec3 &inPrimitive) = 0;
101
virtual void WritePrimitiveData(const Vec4 &inPrimitive) = 0;
102
virtual void WritePrimitiveData(const UVec4 &inPrimitive) = 0;
103
virtual void WritePrimitiveData(const Quat &inPrimitive) = 0;
104
virtual void WritePrimitiveData(const Mat44 &inPrimitive) = 0;
105
virtual void WritePrimitiveData(const DMat44 &inPrimitive) = 0;
106
107
///@name Write compounds
108
virtual void WritePointerData(const RTTI *inRTTI, const void *inPointer) = 0;
109
virtual void WriteClassData(const RTTI *inRTTI, const void *inInstance) = 0;
110
111
///@name Layout hints (for text output)
112
virtual void HintNextItem() { /* Default is do nothing */ }
113
virtual void HintIndentUp() { /* Default is do nothing */ }
114
virtual void HintIndentDown() { /* Default is do nothing */ }
115
};
116
117
// Define macro to declare functions for a specific primitive type
118
#define JPH_DECLARE_PRIMITIVE(name) \
119
JPH_EXPORT bool OSIsType(name *, int inArrayDepth, EOSDataType inDataType, const char *inClassName); \
120
JPH_EXPORT bool OSReadData(IObjectStreamIn &ioStream, name &outPrimitive); \
121
JPH_EXPORT void OSWriteDataType(IObjectStreamOut &ioStream, name *); \
122
JPH_EXPORT void OSWriteData(IObjectStreamOut &ioStream, const name &inPrimitive);
123
124
// This file uses the JPH_DECLARE_PRIMITIVE macro to define all types
125
#include <Jolt/ObjectStream/ObjectStreamTypes.h>
126
127
// Define serialization templates
128
template <class T, class A>
129
bool OSIsType(Array<T, A> *, int inArrayDepth, EOSDataType inDataType, const char *inClassName)
130
{
131
return (inArrayDepth > 0 && OSIsType(static_cast<T *>(nullptr), inArrayDepth - 1, inDataType, inClassName));
132
}
133
134
template <class T, uint N>
135
bool OSIsType(StaticArray<T, N> *, int inArrayDepth, EOSDataType inDataType, const char *inClassName)
136
{
137
return (inArrayDepth > 0 && OSIsType(static_cast<T *>(nullptr), inArrayDepth - 1, inDataType, inClassName));
138
}
139
140
template <class T, uint N>
141
bool OSIsType(T (*)[N], int inArrayDepth, EOSDataType inDataType, const char *inClassName)
142
{
143
return (inArrayDepth > 0 && OSIsType(static_cast<T *>(nullptr), inArrayDepth - 1, inDataType, inClassName));
144
}
145
146
template <class T>
147
bool OSIsType(Ref<T> *, int inArrayDepth, EOSDataType inDataType, const char *inClassName)
148
{
149
return OSIsType(static_cast<T *>(nullptr), inArrayDepth, inDataType, inClassName);
150
}
151
152
template <class T>
153
bool OSIsType(RefConst<T> *, int inArrayDepth, EOSDataType inDataType, const char *inClassName)
154
{
155
return OSIsType(static_cast<T *>(nullptr), inArrayDepth, inDataType, inClassName);
156
}
157
158
/// Define serialization templates for dynamic arrays
159
template <class T, class A>
160
bool OSReadData(IObjectStreamIn &ioStream, Array<T, A> &inArray)
161
{
162
bool continue_reading = true;
163
164
// Read array length
165
uint32 array_length;
166
continue_reading = ioStream.ReadCount(array_length);
167
168
// Read array items
169
if (continue_reading)
170
{
171
inArray.clear();
172
inArray.resize(array_length);
173
for (uint32 el = 0; el < array_length && continue_reading; ++el)
174
continue_reading = OSReadData(ioStream, inArray[el]);
175
}
176
177
return continue_reading;
178
}
179
180
/// Define serialization templates for static arrays
181
template <class T, uint N>
182
bool OSReadData(IObjectStreamIn &ioStream, StaticArray<T, N> &inArray)
183
{
184
bool continue_reading = true;
185
186
// Read array length
187
uint32 array_length;
188
continue_reading = ioStream.ReadCount(array_length);
189
190
// Check if we can fit this many elements
191
if (array_length > N)
192
return false;
193
194
// Read array items
195
if (continue_reading)
196
{
197
inArray.clear();
198
inArray.resize(array_length);
199
for (uint32 el = 0; el < array_length && continue_reading; ++el)
200
continue_reading = OSReadData(ioStream, inArray[el]);
201
}
202
203
return continue_reading;
204
}
205
206
/// Define serialization templates for C style arrays
207
template <class T, uint N>
208
bool OSReadData(IObjectStreamIn &ioStream, T (&inArray)[N])
209
{
210
bool continue_reading = true;
211
212
// Read array length
213
uint32 array_length;
214
continue_reading = ioStream.ReadCount(array_length);
215
if (array_length != N)
216
return false;
217
218
// Read array items
219
for (uint32 el = 0; el < N && continue_reading; ++el)
220
continue_reading = OSReadData(ioStream, inArray[el]);
221
222
return continue_reading;
223
}
224
225
/// Define serialization templates for references
226
template <class T>
227
bool OSReadData(IObjectStreamIn &ioStream, Ref<T> &inRef)
228
{
229
return ioStream.ReadPointerData(JPH_RTTI(T), inRef.InternalGetPointer(), T::sInternalGetRefCountOffset());
230
}
231
232
template <class T>
233
bool OSReadData(IObjectStreamIn &ioStream, RefConst<T> &inRef)
234
{
235
return ioStream.ReadPointerData(JPH_RTTI(T), inRef.InternalGetPointer(), T::sInternalGetRefCountOffset());
236
}
237
238
// Define serialization templates for dynamic arrays
239
template <class T, class A>
240
void OSWriteDataType(IObjectStreamOut &ioStream, Array<T, A> *)
241
{
242
ioStream.WriteDataType(EOSDataType::Array);
243
OSWriteDataType(ioStream, static_cast<T *>(nullptr));
244
}
245
246
template <class T, class A>
247
void OSWriteData(IObjectStreamOut &ioStream, const Array<T, A> &inArray)
248
{
249
// Write size of array
250
ioStream.HintNextItem();
251
ioStream.WriteCount(static_cast<uint32>(inArray.size()));
252
253
// Write data in array
254
ioStream.HintIndentUp();
255
for (const T &v : inArray)
256
OSWriteData(ioStream, v);
257
ioStream.HintIndentDown();
258
}
259
260
/// Define serialization templates for static arrays
261
template <class T, uint N>
262
void OSWriteDataType(IObjectStreamOut &ioStream, StaticArray<T, N> *)
263
{
264
ioStream.WriteDataType(EOSDataType::Array);
265
OSWriteDataType(ioStream, static_cast<T *>(nullptr));
266
}
267
268
template <class T, uint N>
269
void OSWriteData(IObjectStreamOut &ioStream, const StaticArray<T, N> &inArray)
270
{
271
// Write size of array
272
ioStream.HintNextItem();
273
ioStream.WriteCount(inArray.size());
274
275
// Write data in array
276
ioStream.HintIndentUp();
277
for (const typename StaticArray<T, N>::value_type &v : inArray)
278
OSWriteData(ioStream, v);
279
ioStream.HintIndentDown();
280
}
281
282
/// Define serialization templates for C style arrays
283
template <class T, uint N>
284
void OSWriteDataType(IObjectStreamOut &ioStream, T (*)[N])
285
{
286
ioStream.WriteDataType(EOSDataType::Array);
287
OSWriteDataType(ioStream, static_cast<T *>(nullptr));
288
}
289
290
template <class T, uint N>
291
void OSWriteData(IObjectStreamOut &ioStream, const T (&inArray)[N])
292
{
293
// Write size of array
294
ioStream.HintNextItem();
295
ioStream.WriteCount(uint32(N));
296
297
// Write data in array
298
ioStream.HintIndentUp();
299
for (const T &v : inArray)
300
OSWriteData(ioStream, v);
301
ioStream.HintIndentDown();
302
}
303
304
/// Define serialization templates for references
305
template <class T>
306
void OSWriteDataType(IObjectStreamOut &ioStream, Ref<T> *)
307
{
308
OSWriteDataType(ioStream, static_cast<T *>(nullptr));
309
}
310
311
template <class T>
312
void OSWriteData(IObjectStreamOut &ioStream, const Ref<T> &inRef)
313
{
314
if (inRef != nullptr)
315
ioStream.WritePointerData(GetRTTI(inRef.GetPtr()), inRef.GetPtr());
316
else
317
ioStream.WritePointerData(nullptr, nullptr);
318
}
319
320
template <class T>
321
void OSWriteDataType(IObjectStreamOut &ioStream, RefConst<T> *)
322
{
323
OSWriteDataType(ioStream, static_cast<T *>(nullptr));
324
}
325
326
template <class T>
327
void OSWriteData(IObjectStreamOut &ioStream, const RefConst<T> &inRef)
328
{
329
if (inRef != nullptr)
330
ioStream.WritePointerData(GetRTTI(inRef.GetPtr()), inRef.GetPtr());
331
else
332
ioStream.WritePointerData(nullptr, nullptr);
333
}
334
335
JPH_NAMESPACE_END
336
337
#endif // JPH_OBJECT_STREAM
338
339