initial commit, 4.5 stable
Some checks failed
🔗 GHA / 📊 Static checks (push) Has been cancelled
🔗 GHA / 🤖 Android (push) Has been cancelled
🔗 GHA / 🍏 iOS (push) Has been cancelled
🔗 GHA / 🐧 Linux (push) Has been cancelled
🔗 GHA / 🍎 macOS (push) Has been cancelled
🔗 GHA / 🏁 Windows (push) Has been cancelled
🔗 GHA / 🌐 Web (push) Has been cancelled

This commit is contained in:
2025-09-16 20:46:46 -04:00
commit 9d30169a8d
13378 changed files with 7050105 additions and 0 deletions

View File

@@ -0,0 +1,333 @@
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
// SPDX-License-Identifier: MIT
#pragma once
#include <Jolt/Core/StaticArray.h>
#include <Jolt/Core/Reference.h>
#include <Jolt/Core/RTTI.h>
#include <Jolt/Core/NonCopyable.h>
#include <Jolt/ObjectStream/SerializableAttribute.h>
#ifdef JPH_OBJECT_STREAM
JPH_NAMESPACE_BEGIN
/// Base class for object stream input and output streams.
class JPH_EXPORT ObjectStream : public NonCopyable
{
public:
/// Stream type
enum class EStreamType
{
Text,
Binary,
};
protected:
/// Destructor
virtual ~ObjectStream() = default;
/// Identifier for objects
using Identifier = uint32;
static constexpr int sVersion = 1;
static constexpr int sRevision = 0;
static constexpr Identifier sNullIdentifier = 0;
};
/// Interface class for reading from an object stream
class JPH_EXPORT IObjectStreamIn : public ObjectStream
{
public:
///@name Input type specific operations
virtual bool ReadDataType(EOSDataType &outType) = 0;
virtual bool ReadName(String &outName) = 0;
virtual bool ReadIdentifier(Identifier &outIdentifier) = 0;
virtual bool ReadCount(uint32 &outCount) = 0;
///@name Read primitives
virtual bool ReadPrimitiveData(uint8 &outPrimitive) = 0;
virtual bool ReadPrimitiveData(uint16 &outPrimitive) = 0;
virtual bool ReadPrimitiveData(int &outPrimitive) = 0;
virtual bool ReadPrimitiveData(uint32 &outPrimitive) = 0;
virtual bool ReadPrimitiveData(uint64 &outPrimitive) = 0;
virtual bool ReadPrimitiveData(float &outPrimitive) = 0;
virtual bool ReadPrimitiveData(double &outPrimitive) = 0;
virtual bool ReadPrimitiveData(bool &outPrimitive) = 0;
virtual bool ReadPrimitiveData(String &outPrimitive) = 0;
virtual bool ReadPrimitiveData(Float3 &outPrimitive) = 0;
virtual bool ReadPrimitiveData(Double3 &outPrimitive) = 0;
virtual bool ReadPrimitiveData(Vec3 &outPrimitive) = 0;
virtual bool ReadPrimitiveData(DVec3 &outPrimitive) = 0;
virtual bool ReadPrimitiveData(Vec4 &outPrimitive) = 0;
virtual bool ReadPrimitiveData(Quat &outPrimitive) = 0;
virtual bool ReadPrimitiveData(Mat44 &outPrimitive) = 0;
virtual bool ReadPrimitiveData(DMat44 &outPrimitive) = 0;
///@name Read compounds
virtual bool ReadClassData(const char *inClassName, void *inInstance) = 0;
virtual bool ReadPointerData(const RTTI *inRTTI, void **inPointer, int inRefCountOffset = -1) = 0;
};
/// Interface class for writing to an object stream
class JPH_EXPORT IObjectStreamOut : public ObjectStream
{
public:
///@name Output type specific operations
virtual void WriteDataType(EOSDataType inType) = 0;
virtual void WriteName(const char *inName) = 0;
virtual void WriteIdentifier(Identifier inIdentifier) = 0;
virtual void WriteCount(uint32 inCount) = 0;
///@name Write primitives
virtual void WritePrimitiveData(const uint8 &inPrimitive) = 0;
virtual void WritePrimitiveData(const uint16 &inPrimitive) = 0;
virtual void WritePrimitiveData(const int &inPrimitive) = 0;
virtual void WritePrimitiveData(const uint32 &inPrimitive) = 0;
virtual void WritePrimitiveData(const uint64 &inPrimitive) = 0;
virtual void WritePrimitiveData(const float &inPrimitive) = 0;
virtual void WritePrimitiveData(const double &inPrimitive) = 0;
virtual void WritePrimitiveData(const bool &inPrimitive) = 0;
virtual void WritePrimitiveData(const String &inPrimitive) = 0;
virtual void WritePrimitiveData(const Float3 &inPrimitive) = 0;
virtual void WritePrimitiveData(const Double3 &inPrimitive) = 0;
virtual void WritePrimitiveData(const Vec3 &inPrimitive) = 0;
virtual void WritePrimitiveData(const DVec3 &inPrimitive) = 0;
virtual void WritePrimitiveData(const Vec4 &inPrimitive) = 0;
virtual void WritePrimitiveData(const Quat &inPrimitive) = 0;
virtual void WritePrimitiveData(const Mat44 &inPrimitive) = 0;
virtual void WritePrimitiveData(const DMat44 &inPrimitive) = 0;
///@name Write compounds
virtual void WritePointerData(const RTTI *inRTTI, const void *inPointer) = 0;
virtual void WriteClassData(const RTTI *inRTTI, const void *inInstance) = 0;
///@name Layout hints (for text output)
virtual void HintNextItem() { /* Default is do nothing */ }
virtual void HintIndentUp() { /* Default is do nothing */ }
virtual void HintIndentDown() { /* Default is do nothing */ }
};
// Define macro to declare functions for a specific primitive type
#define JPH_DECLARE_PRIMITIVE(name) \
JPH_EXPORT bool OSIsType(name *, int inArrayDepth, EOSDataType inDataType, const char *inClassName); \
JPH_EXPORT bool OSReadData(IObjectStreamIn &ioStream, name &outPrimitive); \
JPH_EXPORT void OSWriteDataType(IObjectStreamOut &ioStream, name *); \
JPH_EXPORT void OSWriteData(IObjectStreamOut &ioStream, const name &inPrimitive);
// This file uses the JPH_DECLARE_PRIMITIVE macro to define all types
#include <Jolt/ObjectStream/ObjectStreamTypes.h>
// Define serialization templates
template <class T, class A>
bool OSIsType(Array<T, A> *, int inArrayDepth, EOSDataType inDataType, const char *inClassName)
{
return (inArrayDepth > 0 && OSIsType(static_cast<T *>(nullptr), inArrayDepth - 1, inDataType, inClassName));
}
template <class T, uint N>
bool OSIsType(StaticArray<T, N> *, int inArrayDepth, EOSDataType inDataType, const char *inClassName)
{
return (inArrayDepth > 0 && OSIsType(static_cast<T *>(nullptr), inArrayDepth - 1, inDataType, inClassName));
}
template <class T, uint N>
bool OSIsType(T (*)[N], int inArrayDepth, EOSDataType inDataType, const char *inClassName)
{
return (inArrayDepth > 0 && OSIsType(static_cast<T *>(nullptr), inArrayDepth - 1, inDataType, inClassName));
}
template <class T>
bool OSIsType(Ref<T> *, int inArrayDepth, EOSDataType inDataType, const char *inClassName)
{
return OSIsType(static_cast<T *>(nullptr), inArrayDepth, inDataType, inClassName);
}
template <class T>
bool OSIsType(RefConst<T> *, int inArrayDepth, EOSDataType inDataType, const char *inClassName)
{
return OSIsType(static_cast<T *>(nullptr), inArrayDepth, inDataType, inClassName);
}
/// Define serialization templates for dynamic arrays
template <class T, class A>
bool OSReadData(IObjectStreamIn &ioStream, Array<T, A> &inArray)
{
bool continue_reading = true;
// Read array length
uint32 array_length;
continue_reading = ioStream.ReadCount(array_length);
// Read array items
if (continue_reading)
{
inArray.clear();
inArray.resize(array_length);
for (uint32 el = 0; el < array_length && continue_reading; ++el)
continue_reading = OSReadData(ioStream, inArray[el]);
}
return continue_reading;
}
/// Define serialization templates for static arrays
template <class T, uint N>
bool OSReadData(IObjectStreamIn &ioStream, StaticArray<T, N> &inArray)
{
bool continue_reading = true;
// Read array length
uint32 array_length;
continue_reading = ioStream.ReadCount(array_length);
// Check if we can fit this many elements
if (array_length > N)
return false;
// Read array items
if (continue_reading)
{
inArray.clear();
inArray.resize(array_length);
for (uint32 el = 0; el < array_length && continue_reading; ++el)
continue_reading = OSReadData(ioStream, inArray[el]);
}
return continue_reading;
}
/// Define serialization templates for C style arrays
template <class T, uint N>
bool OSReadData(IObjectStreamIn &ioStream, T (&inArray)[N])
{
bool continue_reading = true;
// Read array length
uint32 array_length;
continue_reading = ioStream.ReadCount(array_length);
if (array_length != N)
return false;
// Read array items
for (uint32 el = 0; el < N && continue_reading; ++el)
continue_reading = OSReadData(ioStream, inArray[el]);
return continue_reading;
}
/// Define serialization templates for references
template <class T>
bool OSReadData(IObjectStreamIn &ioStream, Ref<T> &inRef)
{
return ioStream.ReadPointerData(JPH_RTTI(T), inRef.InternalGetPointer(), T::sInternalGetRefCountOffset());
}
template <class T>
bool OSReadData(IObjectStreamIn &ioStream, RefConst<T> &inRef)
{
return ioStream.ReadPointerData(JPH_RTTI(T), inRef.InternalGetPointer(), T::sInternalGetRefCountOffset());
}
// Define serialization templates for dynamic arrays
template <class T, class A>
void OSWriteDataType(IObjectStreamOut &ioStream, Array<T, A> *)
{
ioStream.WriteDataType(EOSDataType::Array);
OSWriteDataType(ioStream, static_cast<T *>(nullptr));
}
template <class T, class A>
void OSWriteData(IObjectStreamOut &ioStream, const Array<T, A> &inArray)
{
// Write size of array
ioStream.HintNextItem();
ioStream.WriteCount(static_cast<uint32>(inArray.size()));
// Write data in array
ioStream.HintIndentUp();
for (const T &v : inArray)
OSWriteData(ioStream, v);
ioStream.HintIndentDown();
}
/// Define serialization templates for static arrays
template <class T, uint N>
void OSWriteDataType(IObjectStreamOut &ioStream, StaticArray<T, N> *)
{
ioStream.WriteDataType(EOSDataType::Array);
OSWriteDataType(ioStream, static_cast<T *>(nullptr));
}
template <class T, uint N>
void OSWriteData(IObjectStreamOut &ioStream, const StaticArray<T, N> &inArray)
{
// Write size of array
ioStream.HintNextItem();
ioStream.WriteCount(inArray.size());
// Write data in array
ioStream.HintIndentUp();
for (const typename StaticArray<T, N>::value_type &v : inArray)
OSWriteData(ioStream, v);
ioStream.HintIndentDown();
}
/// Define serialization templates for C style arrays
template <class T, uint N>
void OSWriteDataType(IObjectStreamOut &ioStream, T (*)[N])
{
ioStream.WriteDataType(EOSDataType::Array);
OSWriteDataType(ioStream, static_cast<T *>(nullptr));
}
template <class T, uint N>
void OSWriteData(IObjectStreamOut &ioStream, const T (&inArray)[N])
{
// Write size of array
ioStream.HintNextItem();
ioStream.WriteCount(uint32(N));
// Write data in array
ioStream.HintIndentUp();
for (const T &v : inArray)
OSWriteData(ioStream, v);
ioStream.HintIndentDown();
}
/// Define serialization templates for references
template <class T>
void OSWriteDataType(IObjectStreamOut &ioStream, Ref<T> *)
{
OSWriteDataType(ioStream, static_cast<T *>(nullptr));
}
template <class T>
void OSWriteData(IObjectStreamOut &ioStream, const Ref<T> &inRef)
{
if (inRef != nullptr)
ioStream.WritePointerData(GetRTTI(inRef.GetPtr()), inRef.GetPtr());
else
ioStream.WritePointerData(nullptr, nullptr);
}
template <class T>
void OSWriteDataType(IObjectStreamOut &ioStream, RefConst<T> *)
{
OSWriteDataType(ioStream, static_cast<T *>(nullptr));
}
template <class T>
void OSWriteData(IObjectStreamOut &ioStream, const RefConst<T> &inRef)
{
if (inRef != nullptr)
ioStream.WritePointerData(GetRTTI(inRef.GetPtr()), inRef.GetPtr());
else
ioStream.WritePointerData(nullptr, nullptr);
}
JPH_NAMESPACE_END
#endif // JPH_OBJECT_STREAM

View File

@@ -0,0 +1,111 @@
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
// SPDX-License-Identifier: MIT
#pragma once
#ifdef JPH_OBJECT_STREAM
JPH_NAMESPACE_BEGIN
class RTTI;
class IObjectStreamIn;
class IObjectStreamOut;
/// Data type
enum class EOSDataType
{
/// Control codes
Declare, ///< Used to declare the attributes of a new object type
Object, ///< Start of a new object
Instance, ///< Used in attribute declaration, indicates that an object is an instanced attribute (no pointer)
Pointer, ///< Used in attribute declaration, indicates that an object is a pointer attribute
Array, ///< Used in attribute declaration, indicates that this is an array of objects
// Basic types (primitives)
#define JPH_DECLARE_PRIMITIVE(name) T_##name,
// This file uses the JPH_DECLARE_PRIMITIVE macro to define all types
#include <Jolt/ObjectStream/ObjectStreamTypes.h>
// Error values for read functions
Invalid, ///< Next token on the stream was not a valid data type
};
/// Attributes are members of classes that need to be serialized.
class SerializableAttribute
{
public:
///@ Serialization functions
using pGetMemberPrimitiveType = const RTTI * (*)();
using pIsType = bool (*)(int inArrayDepth, EOSDataType inDataType, const char *inClassName);
using pReadData = bool (*)(IObjectStreamIn &ioStream, void *inObject);
using pWriteData = void (*)(IObjectStreamOut &ioStream, const void *inObject);
using pWriteDataType = void (*)(IObjectStreamOut &ioStream);
/// Constructor
SerializableAttribute(const char *inName, uint inMemberOffset, pGetMemberPrimitiveType inGetMemberPrimitiveType, pIsType inIsType, pReadData inReadData, pWriteData inWriteData, pWriteDataType inWriteDataType) : mName(inName), mMemberOffset(inMemberOffset), mGetMemberPrimitiveType(inGetMemberPrimitiveType), mIsType(inIsType), mReadData(inReadData), mWriteData(inWriteData), mWriteDataType(inWriteDataType) { }
/// Construct from other attribute with base class offset
SerializableAttribute(const SerializableAttribute &inOther, int inBaseOffset) : mName(inOther.mName), mMemberOffset(inOther.mMemberOffset + inBaseOffset), mGetMemberPrimitiveType(inOther.mGetMemberPrimitiveType), mIsType(inOther.mIsType), mReadData(inOther.mReadData), mWriteData(inOther.mWriteData), mWriteDataType(inOther.mWriteDataType) { }
/// Name of the attribute
void SetName(const char *inName) { mName = inName; }
const char * GetName() const { return mName; }
/// Access to the memory location that contains the member
template <class T>
inline T * GetMemberPointer(void *inObject) const { return reinterpret_cast<T *>(reinterpret_cast<uint8 *>(inObject) + mMemberOffset); }
template <class T>
inline const T * GetMemberPointer(const void *inObject) const { return reinterpret_cast<const T *>(reinterpret_cast<const uint8 *>(inObject) + mMemberOffset); }
/// In case this attribute contains an RTTI type, return it (note that a Array<sometype> will return the rtti of sometype)
const RTTI * GetMemberPrimitiveType() const
{
return mGetMemberPrimitiveType();
}
/// Check if this attribute is of a specific type
bool IsType(int inArrayDepth, EOSDataType inDataType, const char *inClassName) const
{
return mIsType(inArrayDepth, inDataType, inClassName);
}
/// Read the data for this attribute into attribute containing class inObject
bool ReadData(IObjectStreamIn &ioStream, void *inObject) const
{
return mReadData(ioStream, GetMemberPointer<void>(inObject));
}
/// Write the data for this attribute from attribute containing class inObject
void WriteData(IObjectStreamOut &ioStream, const void *inObject) const
{
mWriteData(ioStream, GetMemberPointer<void>(inObject));
}
/// Write the data type of this attribute to a stream
void WriteDataType(IObjectStreamOut &ioStream) const
{
mWriteDataType(ioStream);
}
private:
// Name of the attribute
const char * mName;
// Offset of the member relative to the class
uint mMemberOffset;
// In case this attribute contains an RTTI type, return it (note that a Array<sometype> will return the rtti of sometype)
pGetMemberPrimitiveType mGetMemberPrimitiveType;
// Serialization operations
pIsType mIsType;
pReadData mReadData;
pWriteData mWriteData;
pWriteDataType mWriteDataType;
};
JPH_NAMESPACE_END
#endif // JPH_OBJECT_STREAM

View File

@@ -0,0 +1,67 @@
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
// SPDX-License-Identifier: MIT
#pragma once
#ifdef JPH_OBJECT_STREAM
#include <Jolt/ObjectStream/SerializableAttribute.h>
#include <Jolt/ObjectStream/ObjectStream.h>
JPH_NAMESPACE_BEGIN
//////////////////////////////////////////////////////////////////////////////////////////
// Macros to add properties to be serialized
//////////////////////////////////////////////////////////////////////////////////////////
template <class MemberType>
inline void AddSerializableAttributeEnum(RTTI &inRTTI, uint inOffset, const char *inName)
{
inRTTI.AddAttribute(SerializableAttribute(inName, inOffset,
[]() -> const RTTI *
{
return nullptr;
},
[](int inArrayDepth, EOSDataType inDataType, [[maybe_unused]] const char *inClassName)
{
return inArrayDepth == 0 && inDataType == EOSDataType::T_uint32;
},
[](IObjectStreamIn &ioStream, void *inObject)
{
uint32 temporary;
if (OSReadData(ioStream, temporary))
{
*reinterpret_cast<MemberType *>(inObject) = static_cast<MemberType>(temporary);
return true;
}
return false;
},
[](IObjectStreamOut &ioStream, const void *inObject)
{
static_assert(sizeof(MemberType) <= sizeof(uint32));
uint32 temporary = uint32(*reinterpret_cast<const MemberType *>(inObject));
OSWriteData(ioStream, temporary);
},
[](IObjectStreamOut &ioStream)
{
ioStream.WriteDataType(EOSDataType::T_uint32);
}));
}
// JPH_ADD_ENUM_ATTRIBUTE_WITH_ALIAS
#define JPH_ADD_ENUM_ATTRIBUTE_WITH_ALIAS(class_name, member_name, alias_name) \
AddSerializableAttributeEnum<decltype(class_name::member_name)>(inRTTI, offsetof(class_name, member_name), alias_name);
// JPH_ADD_ENUM_ATTRIBUTE
#define JPH_ADD_ENUM_ATTRIBUTE(class_name, member_name) \
JPH_ADD_ENUM_ATTRIBUTE_WITH_ALIAS(class_name, member_name, #member_name);
JPH_NAMESPACE_END
#else
#define JPH_ADD_ENUM_ATTRIBUTE_WITH_ALIAS(...)
#define JPH_ADD_ENUM_ATTRIBUTE(...)
#endif // JPH_OBJECT_STREAM

View File

@@ -0,0 +1,60 @@
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
// SPDX-License-Identifier: MIT
#pragma once
#ifdef JPH_OBJECT_STREAM
#include <Jolt/ObjectStream/SerializableAttribute.h>
#include <Jolt/ObjectStream/GetPrimitiveTypeOfType.h>
#include <Jolt/ObjectStream/ObjectStream.h>
JPH_NAMESPACE_BEGIN
//////////////////////////////////////////////////////////////////////////////////////////
// Macros to add properties to be serialized
//////////////////////////////////////////////////////////////////////////////////////////
template <class MemberType>
inline void AddSerializableAttributeTyped(RTTI &inRTTI, uint inOffset, const char *inName)
{
inRTTI.AddAttribute(SerializableAttribute(inName, inOffset,
[]()
{
return GetPrimitiveTypeOfType((MemberType *)nullptr);
},
[](int inArrayDepth, EOSDataType inDataType, const char *inClassName)
{
return OSIsType((MemberType *)nullptr, inArrayDepth, inDataType, inClassName);
},
[](IObjectStreamIn &ioStream, void *inObject)
{
return OSReadData(ioStream, *reinterpret_cast<MemberType *>(inObject));
},
[](IObjectStreamOut &ioStream, const void *inObject)
{
OSWriteData(ioStream, *reinterpret_cast<const MemberType *>(inObject));
},
[](IObjectStreamOut &ioStream)
{
OSWriteDataType(ioStream, (MemberType *)nullptr);
}));
}
// JPH_ADD_ATTRIBUTE
#define JPH_ADD_ATTRIBUTE_WITH_ALIAS(class_name, member_name, alias_name) \
AddSerializableAttributeTyped<decltype(class_name::member_name)>(inRTTI, offsetof(class_name, member_name), alias_name);
// JPH_ADD_ATTRIBUTE
#define JPH_ADD_ATTRIBUTE(class_name, member_name) \
JPH_ADD_ATTRIBUTE_WITH_ALIAS(class_name, member_name, #member_name)
JPH_NAMESPACE_END
#else
#define JPH_ADD_ATTRIBUTE_WITH_ALIAS(...)
#define JPH_ADD_ATTRIBUTE(...)
#endif // JPH_OBJECT_STREAM

View File

@@ -0,0 +1,15 @@
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
// SPDX-License-Identifier: MIT
#include <Jolt/Jolt.h>
#include <Jolt/ObjectStream/SerializableObject.h>
JPH_NAMESPACE_BEGIN
JPH_IMPLEMENT_SERIALIZABLE_ABSTRACT(SerializableObject)
{
}
JPH_NAMESPACE_END

View File

@@ -0,0 +1,164 @@
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
// SPDX-License-Identifier: MIT
#pragma once
#include <Jolt/ObjectStream/ObjectStream.h>
JPH_NAMESPACE_BEGIN
//////////////////////////////////////////////////////////////////////////////////////////
// Helper macros
//////////////////////////////////////////////////////////////////////////////////////////
#ifdef JPH_OBJECT_STREAM
// JPH_DECLARE_SERIALIZATION_FUNCTIONS
#define JPH_DECLARE_SERIALIZATION_FUNCTIONS(linkage, prefix, class_name) \
linkage prefix bool OSReadData(IObjectStreamIn &ioStream, class_name &inInstance); \
linkage prefix bool OSReadData(IObjectStreamIn &ioStream, class_name *&inPointer); \
linkage prefix bool OSIsType(class_name *, int inArrayDepth, EOSDataType inDataType, const char *inClassName); \
linkage prefix bool OSIsType(class_name **, int inArrayDepth, EOSDataType inDataType, const char *inClassName); \
linkage prefix void OSWriteData(IObjectStreamOut &ioStream, const class_name &inInstance); \
linkage prefix void OSWriteData(IObjectStreamOut &ioStream, class_name *const &inPointer); \
linkage prefix void OSWriteDataType(IObjectStreamOut &ioStream, class_name *); \
linkage prefix void OSWriteDataType(IObjectStreamOut &ioStream, class_name **);
// JPH_IMPLEMENT_SERIALIZATION_FUNCTIONS
#define JPH_IMPLEMENT_SERIALIZATION_FUNCTIONS(class_name) \
bool OSReadData(IObjectStreamIn &ioStream, class_name &inInstance) \
{ \
return ioStream.ReadClassData(#class_name, (void *)&inInstance); \
} \
bool OSReadData(IObjectStreamIn &ioStream, class_name *&inPointer) \
{ \
return ioStream.ReadPointerData(JPH_RTTI(class_name), (void **)&inPointer); \
} \
bool OSIsType(class_name *, int inArrayDepth, EOSDataType inDataType, const char *inClassName) \
{ \
return inArrayDepth == 0 && inDataType == EOSDataType::Instance && strcmp(inClassName, #class_name) == 0; \
} \
bool OSIsType(class_name **, int inArrayDepth, EOSDataType inDataType, const char *inClassName) \
{ \
return inArrayDepth == 0 && inDataType == EOSDataType::Pointer && strcmp(inClassName, #class_name) == 0; \
} \
void OSWriteData(IObjectStreamOut &ioStream, const class_name &inInstance) \
{ \
ioStream.WriteClassData(JPH_RTTI(class_name), (void *)&inInstance); \
} \
void OSWriteData(IObjectStreamOut &ioStream, class_name *const &inPointer) \
{ \
if (inPointer) \
ioStream.WritePointerData(GetRTTI(inPointer), (void *)inPointer); \
else \
ioStream.WritePointerData(nullptr, nullptr); \
} \
void OSWriteDataType(IObjectStreamOut &ioStream, class_name *) \
{ \
ioStream.WriteDataType(EOSDataType::Instance); \
ioStream.WriteName(#class_name); \
} \
void OSWriteDataType(IObjectStreamOut &ioStream, class_name **) \
{ \
ioStream.WriteDataType(EOSDataType::Pointer); \
ioStream.WriteName(#class_name); \
}
#else
#define JPH_DECLARE_SERIALIZATION_FUNCTIONS(...)
#define JPH_IMPLEMENT_SERIALIZATION_FUNCTIONS(...)
#endif // JPH_OBJECT_STREAM
//////////////////////////////////////////////////////////////////////////////////////////
// Use these macros on non-virtual objects to make them serializable
//////////////////////////////////////////////////////////////////////////////////////////
// JPH_DECLARE_SERIALIZABLE_NON_VIRTUAL
#define JPH_DECLARE_SERIALIZABLE_NON_VIRTUAL(linkage, class_name) \
public: \
JPH_DECLARE_RTTI_NON_VIRTUAL(linkage, class_name) \
JPH_DECLARE_SERIALIZATION_FUNCTIONS(linkage, friend, class_name) \
// JPH_IMPLEMENT_SERIALIZABLE_NON_VIRTUAL
#define JPH_IMPLEMENT_SERIALIZABLE_NON_VIRTUAL(class_name) \
JPH_IMPLEMENT_SERIALIZATION_FUNCTIONS(class_name) \
JPH_IMPLEMENT_RTTI_NON_VIRTUAL(class_name) \
//////////////////////////////////////////////////////////////////////////////////////////
// Same as above, but when you cannot insert the declaration in the class itself
//////////////////////////////////////////////////////////////////////////////////////////
// JPH_DECLARE_SERIALIZABLE_OUTSIDE_CLASS
#define JPH_DECLARE_SERIALIZABLE_OUTSIDE_CLASS(linkage, class_name) \
JPH_DECLARE_RTTI_OUTSIDE_CLASS(linkage, class_name) \
JPH_DECLARE_SERIALIZATION_FUNCTIONS(linkage, extern, class_name) \
// JPH_IMPLEMENT_SERIALIZABLE_OUTSIDE_CLASS
#define JPH_IMPLEMENT_SERIALIZABLE_OUTSIDE_CLASS(class_name) \
JPH_IMPLEMENT_SERIALIZATION_FUNCTIONS(class_name) \
JPH_IMPLEMENT_RTTI_OUTSIDE_CLASS(class_name) \
//////////////////////////////////////////////////////////////////////////////////////////
// Same as above, but for classes that have virtual functions
//////////////////////////////////////////////////////////////////////////////////////////
// JPH_DECLARE_SERIALIZABLE_VIRTUAL - Use for concrete, non-base classes
#define JPH_DECLARE_SERIALIZABLE_VIRTUAL(linkage, class_name) \
public: \
JPH_DECLARE_RTTI_VIRTUAL(linkage, class_name) \
JPH_DECLARE_SERIALIZATION_FUNCTIONS(linkage, friend, class_name) \
// JPH_IMPLEMENT_SERIALIZABLE_VIRTUAL
#define JPH_IMPLEMENT_SERIALIZABLE_VIRTUAL(class_name) \
JPH_IMPLEMENT_SERIALIZATION_FUNCTIONS(class_name) \
JPH_IMPLEMENT_RTTI_VIRTUAL(class_name) \
// JPH_DECLARE_SERIALIZABLE_ABSTRACT - Use for abstract, non-base classes
#define JPH_DECLARE_SERIALIZABLE_ABSTRACT(linkage, class_name) \
public: \
JPH_DECLARE_RTTI_ABSTRACT(linkage, class_name) \
JPH_DECLARE_SERIALIZATION_FUNCTIONS(linkage, friend, class_name) \
// JPH_IMPLEMENT_SERIALIZABLE_ABSTRACT
#define JPH_IMPLEMENT_SERIALIZABLE_ABSTRACT(class_name) \
JPH_IMPLEMENT_SERIALIZATION_FUNCTIONS(class_name) \
JPH_IMPLEMENT_RTTI_ABSTRACT(class_name) \
// JPH_DECLARE_SERIALIZABLE_VIRTUAL_BASE - Use for concrete base classes
#define JPH_DECLARE_SERIALIZABLE_VIRTUAL_BASE(linkage, class_name) \
public: \
JPH_DECLARE_RTTI_VIRTUAL_BASE(linkage, class_name) \
JPH_DECLARE_SERIALIZATION_FUNCTIONS(linkage, friend, class_name) \
// JPH_IMPLEMENT_SERIALIZABLE_VIRTUAL_BASE
#define JPH_IMPLEMENT_SERIALIZABLE_VIRTUAL_BASE(class_name) \
JPH_IMPLEMENT_SERIALIZATION_FUNCTIONS(class_name) \
JPH_IMPLEMENT_RTTI_VIRTUAL_BASE(class_name) \
// JPH_DECLARE_SERIALIZABLE_ABSTRACT_BASE - Use for abstract base class
#define JPH_DECLARE_SERIALIZABLE_ABSTRACT_BASE(linkage, class_name) \
public: \
JPH_DECLARE_RTTI_ABSTRACT_BASE(linkage, class_name) \
JPH_DECLARE_SERIALIZATION_FUNCTIONS(linkage, friend, class_name) \
// JPH_IMPLEMENT_SERIALIZABLE_ABSTRACT_BASE
#define JPH_IMPLEMENT_SERIALIZABLE_ABSTRACT_BASE(class_name) \
JPH_IMPLEMENT_SERIALIZATION_FUNCTIONS(class_name) \
JPH_IMPLEMENT_RTTI_ABSTRACT_BASE(class_name)
/// Classes must be derived from SerializableObject if you want to be able to save pointers or
/// reference counting pointers to objects of this or derived classes. The type will automatically
/// be determined during serialization and upon deserialization it will be restored correctly.
class JPH_EXPORT SerializableObject : public NonCopyable
{
JPH_DECLARE_SERIALIZABLE_ABSTRACT_BASE(JPH_EXPORT, SerializableObject)
public:
/// Constructor
virtual ~SerializableObject() = default;
};
JPH_NAMESPACE_END

View File

@@ -0,0 +1,42 @@
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
// SPDX-License-Identifier: MIT
#pragma once
#include <Jolt/ObjectStream/SerializableObject.h>
#include <Jolt/Core/Color.h>
#include <Jolt/Geometry/AABox.h>
#include <Jolt/Geometry/Triangle.h>
#include <Jolt/Geometry/IndexedTriangle.h>
JPH_NAMESPACE_BEGIN
JPH_DECLARE_RTTI_OUTSIDE_CLASS(JPH_EXPORT, uint8);
JPH_DECLARE_RTTI_OUTSIDE_CLASS(JPH_EXPORT, uint16);
JPH_DECLARE_RTTI_OUTSIDE_CLASS(JPH_EXPORT, int);
JPH_DECLARE_RTTI_OUTSIDE_CLASS(JPH_EXPORT, uint32);
JPH_DECLARE_RTTI_OUTSIDE_CLASS(JPH_EXPORT, uint64);
JPH_DECLARE_RTTI_OUTSIDE_CLASS(JPH_EXPORT, float);
JPH_DECLARE_RTTI_OUTSIDE_CLASS(JPH_EXPORT, double);
JPH_DECLARE_RTTI_OUTSIDE_CLASS(JPH_EXPORT, bool);
JPH_DECLARE_RTTI_OUTSIDE_CLASS(JPH_EXPORT, String);
JPH_DECLARE_RTTI_OUTSIDE_CLASS(JPH_EXPORT, Float3);
JPH_DECLARE_RTTI_OUTSIDE_CLASS(JPH_EXPORT, Double3);
JPH_DECLARE_RTTI_OUTSIDE_CLASS(JPH_EXPORT, Vec3);
JPH_DECLARE_RTTI_OUTSIDE_CLASS(JPH_EXPORT, DVec3);
JPH_DECLARE_RTTI_OUTSIDE_CLASS(JPH_EXPORT, Vec4);
JPH_DECLARE_RTTI_OUTSIDE_CLASS(JPH_EXPORT, Quat);
JPH_DECLARE_RTTI_OUTSIDE_CLASS(JPH_EXPORT, Mat44);
JPH_DECLARE_RTTI_OUTSIDE_CLASS(JPH_EXPORT, DMat44);
JPH_DECLARE_SERIALIZABLE_OUTSIDE_CLASS(JPH_EXPORT, Color);
JPH_DECLARE_SERIALIZABLE_OUTSIDE_CLASS(JPH_EXPORT, AABox);
JPH_DECLARE_SERIALIZABLE_OUTSIDE_CLASS(JPH_EXPORT, Triangle);
JPH_DECLARE_SERIALIZABLE_OUTSIDE_CLASS(JPH_EXPORT, IndexedTriangle);
JPH_DECLARE_SERIALIZABLE_OUTSIDE_CLASS(JPH_EXPORT, Plane);
JPH_NAMESPACE_END
// These need to be added after all types have been registered or else clang under linux will not find GetRTTIOfType for the type
#include <Jolt/ObjectStream/SerializableAttributeTyped.h>
#include <Jolt/ObjectStream/SerializableAttributeEnum.h>