Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/jolt_physics/Jolt/ObjectStream/ObjectStream.h
9906 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(Double3 &outPrimitive) = 0;
62
virtual bool ReadPrimitiveData(Vec3 &outPrimitive) = 0;
63
virtual bool ReadPrimitiveData(DVec3 &outPrimitive) = 0;
64
virtual bool ReadPrimitiveData(Vec4 &outPrimitive) = 0;
65
virtual bool ReadPrimitiveData(Quat &outPrimitive) = 0;
66
virtual bool ReadPrimitiveData(Mat44 &outPrimitive) = 0;
67
virtual bool ReadPrimitiveData(DMat44 &outPrimitive) = 0;
68
69
///@name Read compounds
70
virtual bool ReadClassData(const char *inClassName, void *inInstance) = 0;
71
virtual bool ReadPointerData(const RTTI *inRTTI, void **inPointer, int inRefCountOffset = -1) = 0;
72
};
73
74
/// Interface class for writing to an object stream
75
class JPH_EXPORT IObjectStreamOut : public ObjectStream
76
{
77
public:
78
///@name Output type specific operations
79
virtual void WriteDataType(EOSDataType inType) = 0;
80
virtual void WriteName(const char *inName) = 0;
81
virtual void WriteIdentifier(Identifier inIdentifier) = 0;
82
virtual void WriteCount(uint32 inCount) = 0;
83
84
///@name Write primitives
85
virtual void WritePrimitiveData(const uint8 &inPrimitive) = 0;
86
virtual void WritePrimitiveData(const uint16 &inPrimitive) = 0;
87
virtual void WritePrimitiveData(const int &inPrimitive) = 0;
88
virtual void WritePrimitiveData(const uint32 &inPrimitive) = 0;
89
virtual void WritePrimitiveData(const uint64 &inPrimitive) = 0;
90
virtual void WritePrimitiveData(const float &inPrimitive) = 0;
91
virtual void WritePrimitiveData(const double &inPrimitive) = 0;
92
virtual void WritePrimitiveData(const bool &inPrimitive) = 0;
93
virtual void WritePrimitiveData(const String &inPrimitive) = 0;
94
virtual void WritePrimitiveData(const Float3 &inPrimitive) = 0;
95
virtual void WritePrimitiveData(const Double3 &inPrimitive) = 0;
96
virtual void WritePrimitiveData(const Vec3 &inPrimitive) = 0;
97
virtual void WritePrimitiveData(const DVec3 &inPrimitive) = 0;
98
virtual void WritePrimitiveData(const Vec4 &inPrimitive) = 0;
99
virtual void WritePrimitiveData(const Quat &inPrimitive) = 0;
100
virtual void WritePrimitiveData(const Mat44 &inPrimitive) = 0;
101
virtual void WritePrimitiveData(const DMat44 &inPrimitive) = 0;
102
103
///@name Write compounds
104
virtual void WritePointerData(const RTTI *inRTTI, const void *inPointer) = 0;
105
virtual void WriteClassData(const RTTI *inRTTI, const void *inInstance) = 0;
106
107
///@name Layout hints (for text output)
108
virtual void HintNextItem() { /* Default is do nothing */ }
109
virtual void HintIndentUp() { /* Default is do nothing */ }
110
virtual void HintIndentDown() { /* Default is do nothing */ }
111
};
112
113
// Define macro to declare functions for a specific primitive type
114
#define JPH_DECLARE_PRIMITIVE(name) \
115
JPH_EXPORT bool OSIsType(name *, int inArrayDepth, EOSDataType inDataType, const char *inClassName); \
116
JPH_EXPORT bool OSReadData(IObjectStreamIn &ioStream, name &outPrimitive); \
117
JPH_EXPORT void OSWriteDataType(IObjectStreamOut &ioStream, name *); \
118
JPH_EXPORT void OSWriteData(IObjectStreamOut &ioStream, const name &inPrimitive);
119
120
// This file uses the JPH_DECLARE_PRIMITIVE macro to define all types
121
#include <Jolt/ObjectStream/ObjectStreamTypes.h>
122
123
// Define serialization templates
124
template <class T, class A>
125
bool OSIsType(Array<T, A> *, int inArrayDepth, EOSDataType inDataType, const char *inClassName)
126
{
127
return (inArrayDepth > 0 && OSIsType(static_cast<T *>(nullptr), inArrayDepth - 1, inDataType, inClassName));
128
}
129
130
template <class T, uint N>
131
bool OSIsType(StaticArray<T, N> *, int inArrayDepth, EOSDataType inDataType, const char *inClassName)
132
{
133
return (inArrayDepth > 0 && OSIsType(static_cast<T *>(nullptr), inArrayDepth - 1, inDataType, inClassName));
134
}
135
136
template <class T, uint N>
137
bool OSIsType(T (*)[N], int inArrayDepth, EOSDataType inDataType, const char *inClassName)
138
{
139
return (inArrayDepth > 0 && OSIsType(static_cast<T *>(nullptr), inArrayDepth - 1, inDataType, inClassName));
140
}
141
142
template <class T>
143
bool OSIsType(Ref<T> *, int inArrayDepth, EOSDataType inDataType, const char *inClassName)
144
{
145
return OSIsType(static_cast<T *>(nullptr), inArrayDepth, inDataType, inClassName);
146
}
147
148
template <class T>
149
bool OSIsType(RefConst<T> *, int inArrayDepth, EOSDataType inDataType, const char *inClassName)
150
{
151
return OSIsType(static_cast<T *>(nullptr), inArrayDepth, inDataType, inClassName);
152
}
153
154
/// Define serialization templates for dynamic arrays
155
template <class T, class A>
156
bool OSReadData(IObjectStreamIn &ioStream, Array<T, A> &inArray)
157
{
158
bool continue_reading = true;
159
160
// Read array length
161
uint32 array_length;
162
continue_reading = ioStream.ReadCount(array_length);
163
164
// Read array items
165
if (continue_reading)
166
{
167
inArray.clear();
168
inArray.resize(array_length);
169
for (uint32 el = 0; el < array_length && continue_reading; ++el)
170
continue_reading = OSReadData(ioStream, inArray[el]);
171
}
172
173
return continue_reading;
174
}
175
176
/// Define serialization templates for static arrays
177
template <class T, uint N>
178
bool OSReadData(IObjectStreamIn &ioStream, StaticArray<T, N> &inArray)
179
{
180
bool continue_reading = true;
181
182
// Read array length
183
uint32 array_length;
184
continue_reading = ioStream.ReadCount(array_length);
185
186
// Check if we can fit this many elements
187
if (array_length > N)
188
return false;
189
190
// Read array items
191
if (continue_reading)
192
{
193
inArray.clear();
194
inArray.resize(array_length);
195
for (uint32 el = 0; el < array_length && continue_reading; ++el)
196
continue_reading = OSReadData(ioStream, inArray[el]);
197
}
198
199
return continue_reading;
200
}
201
202
/// Define serialization templates for C style arrays
203
template <class T, uint N>
204
bool OSReadData(IObjectStreamIn &ioStream, T (&inArray)[N])
205
{
206
bool continue_reading = true;
207
208
// Read array length
209
uint32 array_length;
210
continue_reading = ioStream.ReadCount(array_length);
211
if (array_length != N)
212
return false;
213
214
// Read array items
215
for (uint32 el = 0; el < N && continue_reading; ++el)
216
continue_reading = OSReadData(ioStream, inArray[el]);
217
218
return continue_reading;
219
}
220
221
/// Define serialization templates for references
222
template <class T>
223
bool OSReadData(IObjectStreamIn &ioStream, Ref<T> &inRef)
224
{
225
return ioStream.ReadPointerData(JPH_RTTI(T), inRef.InternalGetPointer(), T::sInternalGetRefCountOffset());
226
}
227
228
template <class T>
229
bool OSReadData(IObjectStreamIn &ioStream, RefConst<T> &inRef)
230
{
231
return ioStream.ReadPointerData(JPH_RTTI(T), inRef.InternalGetPointer(), T::sInternalGetRefCountOffset());
232
}
233
234
// Define serialization templates for dynamic arrays
235
template <class T, class A>
236
void OSWriteDataType(IObjectStreamOut &ioStream, Array<T, A> *)
237
{
238
ioStream.WriteDataType(EOSDataType::Array);
239
OSWriteDataType(ioStream, static_cast<T *>(nullptr));
240
}
241
242
template <class T, class A>
243
void OSWriteData(IObjectStreamOut &ioStream, const Array<T, A> &inArray)
244
{
245
// Write size of array
246
ioStream.HintNextItem();
247
ioStream.WriteCount(static_cast<uint32>(inArray.size()));
248
249
// Write data in array
250
ioStream.HintIndentUp();
251
for (const T &v : inArray)
252
OSWriteData(ioStream, v);
253
ioStream.HintIndentDown();
254
}
255
256
/// Define serialization templates for static arrays
257
template <class T, uint N>
258
void OSWriteDataType(IObjectStreamOut &ioStream, StaticArray<T, N> *)
259
{
260
ioStream.WriteDataType(EOSDataType::Array);
261
OSWriteDataType(ioStream, static_cast<T *>(nullptr));
262
}
263
264
template <class T, uint N>
265
void OSWriteData(IObjectStreamOut &ioStream, const StaticArray<T, N> &inArray)
266
{
267
// Write size of array
268
ioStream.HintNextItem();
269
ioStream.WriteCount(inArray.size());
270
271
// Write data in array
272
ioStream.HintIndentUp();
273
for (const typename StaticArray<T, N>::value_type &v : inArray)
274
OSWriteData(ioStream, v);
275
ioStream.HintIndentDown();
276
}
277
278
/// Define serialization templates for C style arrays
279
template <class T, uint N>
280
void OSWriteDataType(IObjectStreamOut &ioStream, T (*)[N])
281
{
282
ioStream.WriteDataType(EOSDataType::Array);
283
OSWriteDataType(ioStream, static_cast<T *>(nullptr));
284
}
285
286
template <class T, uint N>
287
void OSWriteData(IObjectStreamOut &ioStream, const T (&inArray)[N])
288
{
289
// Write size of array
290
ioStream.HintNextItem();
291
ioStream.WriteCount(uint32(N));
292
293
// Write data in array
294
ioStream.HintIndentUp();
295
for (const T &v : inArray)
296
OSWriteData(ioStream, v);
297
ioStream.HintIndentDown();
298
}
299
300
/// Define serialization templates for references
301
template <class T>
302
void OSWriteDataType(IObjectStreamOut &ioStream, Ref<T> *)
303
{
304
OSWriteDataType(ioStream, static_cast<T *>(nullptr));
305
}
306
307
template <class T>
308
void OSWriteData(IObjectStreamOut &ioStream, const Ref<T> &inRef)
309
{
310
if (inRef != nullptr)
311
ioStream.WritePointerData(GetRTTI(inRef.GetPtr()), inRef.GetPtr());
312
else
313
ioStream.WritePointerData(nullptr, nullptr);
314
}
315
316
template <class T>
317
void OSWriteDataType(IObjectStreamOut &ioStream, RefConst<T> *)
318
{
319
OSWriteDataType(ioStream, static_cast<T *>(nullptr));
320
}
321
322
template <class T>
323
void OSWriteData(IObjectStreamOut &ioStream, const RefConst<T> &inRef)
324
{
325
if (inRef != nullptr)
326
ioStream.WritePointerData(GetRTTI(inRef.GetPtr()), inRef.GetPtr());
327
else
328
ioStream.WritePointerData(nullptr, nullptr);
329
}
330
331
JPH_NAMESPACE_END
332
333
#endif // JPH_OBJECT_STREAM
334
335