forked from LeenkxTeam/LNXSDK
HaxeJolt
This commit is contained in:
@ -0,0 +1,54 @@
|
||||
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
|
||||
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Jolt/Core/RTTI.h>
|
||||
|
||||
JPH_NAMESPACE_BEGIN
|
||||
|
||||
/// Helper functions to get the underlying RTTI type of a type (so e.g. Array<sometype> will return sometype)
|
||||
template <class T>
|
||||
const RTTI *GetPrimitiveTypeOfType(T *)
|
||||
{
|
||||
return GetRTTIOfType((T *)nullptr);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
const RTTI *GetPrimitiveTypeOfType(T **)
|
||||
{
|
||||
return GetRTTIOfType((T *)nullptr);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
const RTTI *GetPrimitiveTypeOfType(Ref<T> *)
|
||||
{
|
||||
return GetRTTIOfType((T *)nullptr);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
const RTTI *GetPrimitiveTypeOfType(RefConst<T> *)
|
||||
{
|
||||
return GetRTTIOfType((T *)nullptr);
|
||||
}
|
||||
|
||||
template <class T, class A>
|
||||
const RTTI *GetPrimitiveTypeOfType(Array<T, A> *)
|
||||
{
|
||||
return GetPrimitiveTypeOfType((T *)nullptr);
|
||||
}
|
||||
|
||||
template <class T, uint N>
|
||||
const RTTI *GetPrimitiveTypeOfType(StaticArray<T, N> *)
|
||||
{
|
||||
return GetPrimitiveTypeOfType((T *)nullptr);
|
||||
}
|
||||
|
||||
template <class T, uint N>
|
||||
const RTTI *GetPrimitiveTypeOfType(T (*)[N])
|
||||
{
|
||||
return GetPrimitiveTypeOfType((T *)nullptr);
|
||||
}
|
||||
|
||||
JPH_NAMESPACE_END
|
||||
38
lib/haxejolt/JoltPhysics/Jolt/ObjectStream/ObjectStream.cpp
Normal file
38
lib/haxejolt/JoltPhysics/Jolt/ObjectStream/ObjectStream.cpp
Normal file
@ -0,0 +1,38 @@
|
||||
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
|
||||
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#include <Jolt/Jolt.h>
|
||||
|
||||
#include <Jolt/ObjectStream/ObjectStream.h>
|
||||
|
||||
#ifdef JPH_OBJECT_STREAM
|
||||
|
||||
JPH_NAMESPACE_BEGIN
|
||||
|
||||
// Define macro to declare functions for a specific primitive type
|
||||
#define JPH_DECLARE_PRIMITIVE(name) \
|
||||
bool OSIsType(name *, int inArrayDepth, EOSDataType inDataType, const char *inClassName) \
|
||||
{ \
|
||||
return inArrayDepth == 0 && inDataType == EOSDataType::T_##name; \
|
||||
} \
|
||||
bool OSReadData(IObjectStreamIn &ioStream, name &outPrimitive) \
|
||||
{ \
|
||||
return ioStream.ReadPrimitiveData(outPrimitive); \
|
||||
} \
|
||||
void OSWriteDataType(IObjectStreamOut &ioStream, name *) \
|
||||
{ \
|
||||
ioStream.WriteDataType(EOSDataType::T_##name); \
|
||||
} \
|
||||
void OSWriteData(IObjectStreamOut &ioStream, const name &inPrimitive) \
|
||||
{ \
|
||||
ioStream.HintNextItem(); \
|
||||
ioStream.WritePrimitiveData(inPrimitive); \
|
||||
}
|
||||
|
||||
// This file uses the JPH_DECLARE_PRIMITIVE macro to define all types
|
||||
#include <Jolt/ObjectStream/ObjectStreamTypes.h>
|
||||
|
||||
JPH_NAMESPACE_END
|
||||
|
||||
#endif // JPH_OBJECT_STREAM
|
||||
337
lib/haxejolt/JoltPhysics/Jolt/ObjectStream/ObjectStream.h
Normal file
337
lib/haxejolt/JoltPhysics/Jolt/ObjectStream/ObjectStream.h
Normal file
@ -0,0 +1,337 @@
|
||||
// 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(Float4 &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(UVec4 &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 Float4 &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 UVec4 &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
|
||||
@ -0,0 +1,252 @@
|
||||
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
|
||||
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#include <Jolt/Jolt.h>
|
||||
|
||||
#ifdef JPH_OBJECT_STREAM
|
||||
|
||||
#include <Jolt/ObjectStream/ObjectStreamBinaryIn.h>
|
||||
|
||||
JPH_NAMESPACE_BEGIN
|
||||
|
||||
ObjectStreamBinaryIn::ObjectStreamBinaryIn(istream &inStream) :
|
||||
ObjectStreamIn(inStream)
|
||||
{
|
||||
}
|
||||
|
||||
bool ObjectStreamBinaryIn::ReadDataType(EOSDataType &outType)
|
||||
{
|
||||
uint32 type;
|
||||
mStream.read((char *)&type, sizeof(type));
|
||||
if (mStream.fail()) return false;
|
||||
outType = (EOSDataType)type;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ObjectStreamBinaryIn::ReadName(String &outName)
|
||||
{
|
||||
return ReadPrimitiveData(outName);
|
||||
}
|
||||
|
||||
bool ObjectStreamBinaryIn::ReadIdentifier(Identifier &outIdentifier)
|
||||
{
|
||||
Identifier id;
|
||||
mStream.read((char *)&id, sizeof(id));
|
||||
if (mStream.fail()) return false;
|
||||
outIdentifier = id;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ObjectStreamBinaryIn::ReadCount(uint32 &outCount)
|
||||
{
|
||||
uint32 count;
|
||||
mStream.read((char *)&count, sizeof(count));
|
||||
if (mStream.fail()) return false;
|
||||
outCount = count;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ObjectStreamBinaryIn::ReadPrimitiveData(uint8 &outPrimitive)
|
||||
{
|
||||
uint8 primitive;
|
||||
mStream.read((char *)&primitive, sizeof(primitive));
|
||||
if (mStream.fail()) return false;
|
||||
outPrimitive = primitive;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ObjectStreamBinaryIn::ReadPrimitiveData(uint16 &outPrimitive)
|
||||
{
|
||||
uint16 primitive;
|
||||
mStream.read((char *)&primitive, sizeof(primitive));
|
||||
if (mStream.fail()) return false;
|
||||
outPrimitive = primitive;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ObjectStreamBinaryIn::ReadPrimitiveData(int &outPrimitive)
|
||||
{
|
||||
int primitive;
|
||||
mStream.read((char *)&primitive, sizeof(primitive));
|
||||
if (mStream.fail()) return false;
|
||||
outPrimitive = primitive;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ObjectStreamBinaryIn::ReadPrimitiveData(uint32 &outPrimitive)
|
||||
{
|
||||
uint32 primitive;
|
||||
mStream.read((char *)&primitive, sizeof(primitive));
|
||||
if (mStream.fail()) return false;
|
||||
outPrimitive = primitive;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ObjectStreamBinaryIn::ReadPrimitiveData(uint64 &outPrimitive)
|
||||
{
|
||||
uint64 primitive;
|
||||
mStream.read((char *)&primitive, sizeof(primitive));
|
||||
if (mStream.fail()) return false;
|
||||
outPrimitive = primitive;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ObjectStreamBinaryIn::ReadPrimitiveData(float &outPrimitive)
|
||||
{
|
||||
float primitive;
|
||||
mStream.read((char *)&primitive, sizeof(primitive));
|
||||
if (mStream.fail()) return false;
|
||||
outPrimitive = primitive;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ObjectStreamBinaryIn::ReadPrimitiveData(double &outPrimitive)
|
||||
{
|
||||
double primitive;
|
||||
mStream.read((char *)&primitive, sizeof(primitive));
|
||||
if (mStream.fail()) return false;
|
||||
outPrimitive = primitive;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ObjectStreamBinaryIn::ReadPrimitiveData(bool &outPrimitive)
|
||||
{
|
||||
bool primitive;
|
||||
mStream.read((char *)&primitive, sizeof(primitive));
|
||||
if (mStream.fail()) return false;
|
||||
outPrimitive = primitive;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ObjectStreamBinaryIn::ReadPrimitiveData(String &outPrimitive)
|
||||
{
|
||||
// Read length or ID of string
|
||||
uint32 len;
|
||||
if (!ReadPrimitiveData(len))
|
||||
return false;
|
||||
|
||||
// Check empty string
|
||||
if (len == 0)
|
||||
{
|
||||
outPrimitive.clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if it is an ID in the string table
|
||||
if (len & 0x80000000)
|
||||
{
|
||||
StringTable::iterator i = mStringTable.find(len);
|
||||
if (i == mStringTable.end())
|
||||
return false;
|
||||
outPrimitive = i->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Read the string
|
||||
char *data = (char *)JPH_STACK_ALLOC(len + 1);
|
||||
mStream.read(data, len);
|
||||
if (mStream.fail()) return false;
|
||||
data[len] = 0;
|
||||
outPrimitive = data;
|
||||
|
||||
// Insert string in table
|
||||
mStringTable.try_emplace(mNextStringID, outPrimitive);
|
||||
mNextStringID++;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ObjectStreamBinaryIn::ReadPrimitiveData(Float3 &outPrimitive)
|
||||
{
|
||||
Float3 primitive;
|
||||
mStream.read((char *)&primitive, sizeof(Float3));
|
||||
if (mStream.fail()) return false;
|
||||
outPrimitive = primitive;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ObjectStreamBinaryIn::ReadPrimitiveData(Float4 &outPrimitive)
|
||||
{
|
||||
Float4 primitive;
|
||||
mStream.read((char *)&primitive, sizeof(Float4));
|
||||
if (mStream.fail()) return false;
|
||||
outPrimitive = primitive;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ObjectStreamBinaryIn::ReadPrimitiveData(Double3 &outPrimitive)
|
||||
{
|
||||
Double3 primitive;
|
||||
mStream.read((char *)&primitive, sizeof(Double3));
|
||||
if (mStream.fail()) return false;
|
||||
outPrimitive = primitive;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ObjectStreamBinaryIn::ReadPrimitiveData(Vec3 &outPrimitive)
|
||||
{
|
||||
Float3 primitive;
|
||||
mStream.read((char *)&primitive, sizeof(Float3));
|
||||
if (mStream.fail()) return false;
|
||||
outPrimitive = Vec3(primitive); // Use Float3 constructor so that we initialize W too
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ObjectStreamBinaryIn::ReadPrimitiveData(DVec3 &outPrimitive)
|
||||
{
|
||||
Double3 primitive;
|
||||
mStream.read((char *)&primitive, sizeof(Double3));
|
||||
if (mStream.fail()) return false;
|
||||
outPrimitive = DVec3(primitive); // Use Float3 constructor so that we initialize W too
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ObjectStreamBinaryIn::ReadPrimitiveData(Vec4 &outPrimitive)
|
||||
{
|
||||
Vec4 primitive;
|
||||
mStream.read((char *)&primitive, sizeof(primitive));
|
||||
if (mStream.fail()) return false;
|
||||
outPrimitive = primitive;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ObjectStreamBinaryIn::ReadPrimitiveData(UVec4 &outPrimitive)
|
||||
{
|
||||
UVec4 primitive;
|
||||
mStream.read((char *)&primitive, sizeof(primitive));
|
||||
if (mStream.fail()) return false;
|
||||
outPrimitive = primitive;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ObjectStreamBinaryIn::ReadPrimitiveData(Quat &outPrimitive)
|
||||
{
|
||||
Quat primitive;
|
||||
mStream.read((char *)&primitive, sizeof(primitive));
|
||||
if (mStream.fail()) return false;
|
||||
outPrimitive = primitive;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ObjectStreamBinaryIn::ReadPrimitiveData(Mat44 &outPrimitive)
|
||||
{
|
||||
Mat44 primitive;
|
||||
mStream.read((char *)&primitive, sizeof(primitive));
|
||||
if (mStream.fail()) return false;
|
||||
outPrimitive = primitive;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ObjectStreamBinaryIn::ReadPrimitiveData(DMat44 &outPrimitive)
|
||||
{
|
||||
Vec4 c0, c1, c2;
|
||||
DVec3 c3;
|
||||
if (!ReadPrimitiveData(c0) || !ReadPrimitiveData(c1) || !ReadPrimitiveData(c2) || !ReadPrimitiveData(c3))
|
||||
return false;
|
||||
outPrimitive = DMat44(c0, c1, c2, c3);
|
||||
return true;
|
||||
}
|
||||
|
||||
JPH_NAMESPACE_END
|
||||
|
||||
#endif // JPH_OBJECT_STREAM
|
||||
@ -0,0 +1,57 @@
|
||||
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
|
||||
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Jolt/ObjectStream/ObjectStreamIn.h>
|
||||
|
||||
#ifdef JPH_OBJECT_STREAM
|
||||
|
||||
JPH_NAMESPACE_BEGIN
|
||||
|
||||
/// Implementation of ObjectStream binary input stream.
|
||||
class JPH_EXPORT ObjectStreamBinaryIn : public ObjectStreamIn
|
||||
{
|
||||
public:
|
||||
JPH_OVERRIDE_NEW_DELETE
|
||||
|
||||
/// Constructor
|
||||
explicit ObjectStreamBinaryIn(istream &inStream);
|
||||
|
||||
///@name Input type specific operations
|
||||
virtual bool ReadDataType(EOSDataType &outType) override;
|
||||
virtual bool ReadName(String &outName) override;
|
||||
virtual bool ReadIdentifier(Identifier &outIdentifier) override;
|
||||
virtual bool ReadCount(uint32 &outCount) override;
|
||||
|
||||
virtual bool ReadPrimitiveData(uint8 &outPrimitive) override;
|
||||
virtual bool ReadPrimitiveData(uint16 &outPrimitive) override;
|
||||
virtual bool ReadPrimitiveData(int &outPrimitive) override;
|
||||
virtual bool ReadPrimitiveData(uint32 &outPrimitive) override;
|
||||
virtual bool ReadPrimitiveData(uint64 &outPrimitive) override;
|
||||
virtual bool ReadPrimitiveData(float &outPrimitive) override;
|
||||
virtual bool ReadPrimitiveData(double &outPrimitive) override;
|
||||
virtual bool ReadPrimitiveData(bool &outPrimitive) override;
|
||||
virtual bool ReadPrimitiveData(String &outPrimitive) override;
|
||||
virtual bool ReadPrimitiveData(Float3 &outPrimitive) override;
|
||||
virtual bool ReadPrimitiveData(Float4 &outPrimitive) override;
|
||||
virtual bool ReadPrimitiveData(Double3 &outPrimitive) override;
|
||||
virtual bool ReadPrimitiveData(Vec3 &outPrimitive) override;
|
||||
virtual bool ReadPrimitiveData(DVec3 &outPrimitive) override;
|
||||
virtual bool ReadPrimitiveData(Vec4 &outPrimitive) override;
|
||||
virtual bool ReadPrimitiveData(UVec4 &outPrimitive) override;
|
||||
virtual bool ReadPrimitiveData(Quat &outPrimitive) override;
|
||||
virtual bool ReadPrimitiveData(Mat44 &outPrimitive) override;
|
||||
virtual bool ReadPrimitiveData(DMat44 &outPrimitive) override;
|
||||
|
||||
private:
|
||||
using StringTable = UnorderedMap<uint32, String>;
|
||||
|
||||
StringTable mStringTable;
|
||||
uint32 mNextStringID = 0x80000000;
|
||||
};
|
||||
|
||||
JPH_NAMESPACE_END
|
||||
|
||||
#endif // JPH_OBJECT_STREAM
|
||||
@ -0,0 +1,165 @@
|
||||
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
|
||||
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#include <Jolt/Jolt.h>
|
||||
|
||||
#ifdef JPH_OBJECT_STREAM
|
||||
|
||||
#include <Jolt/ObjectStream/ObjectStreamBinaryOut.h>
|
||||
#include <Jolt/Core/StringTools.h>
|
||||
|
||||
JPH_NAMESPACE_BEGIN
|
||||
|
||||
ObjectStreamBinaryOut::ObjectStreamBinaryOut(ostream &inStream) :
|
||||
ObjectStreamOut(inStream)
|
||||
{
|
||||
String header;
|
||||
header = StringFormat("BOS%2d.%02d", ObjectStream::sVersion, ObjectStream::sRevision);
|
||||
mStream.write(header.c_str(), header.size());
|
||||
}
|
||||
|
||||
void ObjectStreamBinaryOut::WriteDataType(EOSDataType inType)
|
||||
{
|
||||
mStream.write((const char *)&inType, sizeof(inType));
|
||||
}
|
||||
|
||||
void ObjectStreamBinaryOut::WriteName(const char *inName)
|
||||
{
|
||||
WritePrimitiveData(String(inName));
|
||||
}
|
||||
|
||||
void ObjectStreamBinaryOut::WriteIdentifier(Identifier inIdentifier)
|
||||
{
|
||||
mStream.write((const char *)&inIdentifier, sizeof(inIdentifier));
|
||||
}
|
||||
|
||||
void ObjectStreamBinaryOut::WriteCount(uint32 inCount)
|
||||
{
|
||||
mStream.write((const char *)&inCount, sizeof(inCount));
|
||||
}
|
||||
|
||||
void ObjectStreamBinaryOut::WritePrimitiveData(const uint8 &inPrimitive)
|
||||
{
|
||||
mStream.write((const char *)&inPrimitive, sizeof(inPrimitive));
|
||||
}
|
||||
|
||||
void ObjectStreamBinaryOut::WritePrimitiveData(const uint16 &inPrimitive)
|
||||
{
|
||||
mStream.write((const char *)&inPrimitive, sizeof(inPrimitive));
|
||||
}
|
||||
|
||||
void ObjectStreamBinaryOut::WritePrimitiveData(const int &inPrimitive)
|
||||
{
|
||||
mStream.write((const char *)&inPrimitive, sizeof(inPrimitive));
|
||||
}
|
||||
|
||||
void ObjectStreamBinaryOut::WritePrimitiveData(const uint32 &inPrimitive)
|
||||
{
|
||||
mStream.write((const char *)&inPrimitive, sizeof(inPrimitive));
|
||||
}
|
||||
|
||||
void ObjectStreamBinaryOut::WritePrimitiveData(const uint64 &inPrimitive)
|
||||
{
|
||||
mStream.write((const char *)&inPrimitive, sizeof(inPrimitive));
|
||||
}
|
||||
|
||||
void ObjectStreamBinaryOut::WritePrimitiveData(const float &inPrimitive)
|
||||
{
|
||||
mStream.write((const char *)&inPrimitive, sizeof(inPrimitive));
|
||||
}
|
||||
|
||||
void ObjectStreamBinaryOut::WritePrimitiveData(const double &inPrimitive)
|
||||
{
|
||||
mStream.write((const char *)&inPrimitive, sizeof(inPrimitive));
|
||||
}
|
||||
|
||||
void ObjectStreamBinaryOut::WritePrimitiveData(const bool &inPrimitive)
|
||||
{
|
||||
mStream.write((const char *)&inPrimitive, sizeof(inPrimitive));
|
||||
}
|
||||
|
||||
void ObjectStreamBinaryOut::WritePrimitiveData(const String &inPrimitive)
|
||||
{
|
||||
// Empty strings are trivial
|
||||
if (inPrimitive.empty())
|
||||
{
|
||||
WritePrimitiveData((uint32)0);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if we've already written this string
|
||||
StringTable::iterator i = mStringTable.find(inPrimitive);
|
||||
if (i != mStringTable.end())
|
||||
{
|
||||
WritePrimitiveData(i->second);
|
||||
return;
|
||||
}
|
||||
|
||||
// Insert string in table
|
||||
mStringTable.try_emplace(inPrimitive, mNextStringID);
|
||||
mNextStringID++;
|
||||
|
||||
// Write string
|
||||
uint32 len = min((uint32)inPrimitive.size(), (uint32)0x7fffffff);
|
||||
WritePrimitiveData(len);
|
||||
mStream.write(inPrimitive.c_str(), len);
|
||||
}
|
||||
|
||||
void ObjectStreamBinaryOut::WritePrimitiveData(const Float3 &inPrimitive)
|
||||
{
|
||||
mStream.write((const char *)&inPrimitive, sizeof(Float3));
|
||||
}
|
||||
|
||||
void ObjectStreamBinaryOut::WritePrimitiveData(const Float4 &inPrimitive)
|
||||
{
|
||||
mStream.write((const char *)&inPrimitive, sizeof(Float4));
|
||||
}
|
||||
|
||||
void ObjectStreamBinaryOut::WritePrimitiveData(const Double3 &inPrimitive)
|
||||
{
|
||||
mStream.write((const char *)&inPrimitive, sizeof(Double3));
|
||||
}
|
||||
|
||||
void ObjectStreamBinaryOut::WritePrimitiveData(const Vec3 &inPrimitive)
|
||||
{
|
||||
mStream.write((const char *)&inPrimitive, 3 * sizeof(float));
|
||||
}
|
||||
|
||||
void ObjectStreamBinaryOut::WritePrimitiveData(const DVec3 &inPrimitive)
|
||||
{
|
||||
mStream.write((const char *)&inPrimitive, 3 * sizeof(double));
|
||||
}
|
||||
|
||||
void ObjectStreamBinaryOut::WritePrimitiveData(const Vec4 &inPrimitive)
|
||||
{
|
||||
mStream.write((const char *)&inPrimitive, sizeof(inPrimitive));
|
||||
}
|
||||
|
||||
void ObjectStreamBinaryOut::WritePrimitiveData(const UVec4 &inPrimitive)
|
||||
{
|
||||
mStream.write((const char *)&inPrimitive, sizeof(inPrimitive));
|
||||
}
|
||||
|
||||
void ObjectStreamBinaryOut::WritePrimitiveData(const Quat &inPrimitive)
|
||||
{
|
||||
mStream.write((const char *)&inPrimitive, sizeof(inPrimitive));
|
||||
}
|
||||
|
||||
void ObjectStreamBinaryOut::WritePrimitiveData(const Mat44 &inPrimitive)
|
||||
{
|
||||
mStream.write((const char *)&inPrimitive, sizeof(inPrimitive));
|
||||
}
|
||||
|
||||
void ObjectStreamBinaryOut::WritePrimitiveData(const DMat44 &inPrimitive)
|
||||
{
|
||||
WritePrimitiveData(inPrimitive.GetColumn4(0));
|
||||
WritePrimitiveData(inPrimitive.GetColumn4(1));
|
||||
WritePrimitiveData(inPrimitive.GetColumn4(2));
|
||||
WritePrimitiveData(inPrimitive.GetTranslation());
|
||||
}
|
||||
|
||||
JPH_NAMESPACE_END
|
||||
|
||||
#endif // JPH_OBJECT_STREAM
|
||||
|
||||
@ -0,0 +1,57 @@
|
||||
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
|
||||
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Jolt/ObjectStream/ObjectStreamOut.h>
|
||||
|
||||
#ifdef JPH_OBJECT_STREAM
|
||||
|
||||
JPH_NAMESPACE_BEGIN
|
||||
|
||||
/// Implementation of ObjectStream binary output stream.
|
||||
class JPH_EXPORT ObjectStreamBinaryOut : public ObjectStreamOut
|
||||
{
|
||||
public:
|
||||
JPH_OVERRIDE_NEW_DELETE
|
||||
|
||||
/// Constructor and destructor
|
||||
explicit ObjectStreamBinaryOut(ostream &inStream);
|
||||
|
||||
///@name Output type specific operations
|
||||
virtual void WriteDataType(EOSDataType inType) override;
|
||||
virtual void WriteName(const char *inName) override;
|
||||
virtual void WriteIdentifier(Identifier inIdentifier) override;
|
||||
virtual void WriteCount(uint32 inCount) override;
|
||||
|
||||
virtual void WritePrimitiveData(const uint8 &inPrimitive) override;
|
||||
virtual void WritePrimitiveData(const uint16 &inPrimitive) override;
|
||||
virtual void WritePrimitiveData(const int &inPrimitive) override;
|
||||
virtual void WritePrimitiveData(const uint32 &inPrimitive) override;
|
||||
virtual void WritePrimitiveData(const uint64 &inPrimitive) override;
|
||||
virtual void WritePrimitiveData(const float &inPrimitive) override;
|
||||
virtual void WritePrimitiveData(const double &inPrimitive) override;
|
||||
virtual void WritePrimitiveData(const bool &inPrimitive) override;
|
||||
virtual void WritePrimitiveData(const String &inPrimitive) override;
|
||||
virtual void WritePrimitiveData(const Float3 &inPrimitive) override;
|
||||
virtual void WritePrimitiveData(const Float4 &inPrimitive) override;
|
||||
virtual void WritePrimitiveData(const Double3 &inPrimitive) override;
|
||||
virtual void WritePrimitiveData(const Vec3 &inPrimitive) override;
|
||||
virtual void WritePrimitiveData(const DVec3 &inPrimitive) override;
|
||||
virtual void WritePrimitiveData(const Vec4 &inPrimitive) override;
|
||||
virtual void WritePrimitiveData(const UVec4 &inPrimitive) override;
|
||||
virtual void WritePrimitiveData(const Quat &inPrimitive) override;
|
||||
virtual void WritePrimitiveData(const Mat44 &inPrimitive) override;
|
||||
virtual void WritePrimitiveData(const DMat44 &inPrimitive) override;
|
||||
|
||||
private:
|
||||
using StringTable = UnorderedMap<String, uint32>;
|
||||
|
||||
StringTable mStringTable;
|
||||
uint32 mNextStringID = 0x80000000;
|
||||
};
|
||||
|
||||
JPH_NAMESPACE_END
|
||||
|
||||
#endif // JPH_OBJECT_STREAM
|
||||
635
lib/haxejolt/JoltPhysics/Jolt/ObjectStream/ObjectStreamIn.cpp
Normal file
635
lib/haxejolt/JoltPhysics/Jolt/ObjectStream/ObjectStreamIn.cpp
Normal file
@ -0,0 +1,635 @@
|
||||
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
|
||||
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#include <Jolt/Jolt.h>
|
||||
|
||||
#ifdef JPH_OBJECT_STREAM
|
||||
|
||||
#include <Jolt/ObjectStream/ObjectStreamIn.h>
|
||||
#include <Jolt/Core/Factory.h>
|
||||
#include <Jolt/Core/UnorderedSet.h>
|
||||
#include <Jolt/ObjectStream/ObjectStreamTextIn.h>
|
||||
#include <Jolt/ObjectStream/ObjectStreamBinaryIn.h>
|
||||
#include <Jolt/ObjectStream/SerializableObject.h>
|
||||
|
||||
JPH_NAMESPACE_BEGIN
|
||||
|
||||
ObjectStreamIn::ObjectStreamIn(istream &inStream) :
|
||||
mStream(inStream)
|
||||
{
|
||||
}
|
||||
|
||||
bool ObjectStreamIn::GetInfo(istream &inStream, EStreamType &outType, int &outVersion, int &outRevision)
|
||||
{
|
||||
// Read header and check if it is the correct format, e.g. "TOS 1.00"
|
||||
char header[9];
|
||||
memset(header, 0, 9);
|
||||
inStream.read(header, 8);
|
||||
if ((header[0] == 'B' || header[0] == 'T') && header[1] == 'O' && header[2] == 'S'
|
||||
&& (header[3] == ' ' || isdigit(header[3])) && isdigit(header[4])
|
||||
&& header[5] == '.' && isdigit(header[6]) && isdigit(header[7]))
|
||||
{
|
||||
// Check if this is a binary or text objectfile
|
||||
switch (header[0])
|
||||
{
|
||||
case 'T': outType = ObjectStream::EStreamType::Text; break;
|
||||
case 'B': outType = ObjectStream::EStreamType::Binary; break;
|
||||
default: JPH_ASSERT(false); break;
|
||||
}
|
||||
|
||||
// Extract version and revision
|
||||
header[5] = '\0';
|
||||
outVersion = atoi(&header[3]);
|
||||
outRevision = atoi(&header[6]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Trace("ObjectStreamIn: Not a valid object stream.");
|
||||
return false;
|
||||
}
|
||||
|
||||
ObjectStreamIn *ObjectStreamIn::Open(istream &inStream)
|
||||
{
|
||||
// Check if file is an ObjectStream of the correct version and revision
|
||||
EStreamType type;
|
||||
int version;
|
||||
int revision;
|
||||
if (GetInfo(inStream, type, version, revision))
|
||||
{
|
||||
if (version == sVersion && revision == sRevision)
|
||||
{
|
||||
// Create an input stream of the correct type
|
||||
switch (type)
|
||||
{
|
||||
case EStreamType::Text: return new ObjectStreamTextIn(inStream);
|
||||
case EStreamType::Binary: return new ObjectStreamBinaryIn(inStream);
|
||||
default: JPH_ASSERT(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Trace("ObjectStreamIn: Different version stream (%d.%02d, expected %d.%02d).", version, revision, sVersion, sRevision);
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void *ObjectStreamIn::Read(const RTTI *inRTTI)
|
||||
{
|
||||
using ObjectSet = UnorderedSet<void *>;
|
||||
|
||||
// Read all information on the stream
|
||||
void *main_object = nullptr;
|
||||
bool continue_reading = true;
|
||||
for (;;)
|
||||
{
|
||||
// Get type of next operation
|
||||
EOSDataType data_type;
|
||||
if (!ReadDataType(data_type))
|
||||
break;
|
||||
|
||||
if (data_type == EOSDataType::Declare)
|
||||
{
|
||||
// Read type declaration
|
||||
if (!ReadRTTI())
|
||||
{
|
||||
Trace("ObjectStreamIn: Fatal error while reading class description for class %s.", inRTTI->GetName());
|
||||
continue_reading = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (data_type == EOSDataType::Object)
|
||||
{
|
||||
const RTTI *rtti;
|
||||
void *object = ReadObject(rtti);
|
||||
if (!main_object && object)
|
||||
{
|
||||
// This is the first and thus main object of the file.
|
||||
if (rtti->IsKindOf(inRTTI))
|
||||
{
|
||||
// Object is of correct type
|
||||
main_object = object;
|
||||
}
|
||||
else
|
||||
{
|
||||
Trace("ObjectStreamIn: Main object of different type. Expected %s, but found %s.", inRTTI->GetName(), rtti->GetName());
|
||||
continue_reading = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Invalid or out of place token found
|
||||
Trace("ObjectStreamIn: Invalid or out of place token found.");
|
||||
continue_reading = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve links (pointer, references)
|
||||
if (continue_reading)
|
||||
{
|
||||
// Resolve links
|
||||
ObjectSet referenced_objects;
|
||||
for (Link &link : mUnresolvedLinks)
|
||||
{
|
||||
IdentifierMap::const_iterator j = mIdentifierMap.find(link.mIdentifier);
|
||||
if (j != mIdentifierMap.end() && j->second.mRTTI->IsKindOf(link.mRTTI))
|
||||
{
|
||||
const ObjectInfo &obj_info = j->second;
|
||||
|
||||
// Set pointer
|
||||
*link.mPointer = obj_info.mInstance;
|
||||
|
||||
// Increment refcount if it was a referencing pointer
|
||||
if (link.mRefCountOffset != -1)
|
||||
++(*(uint32 *)(((uint8 *)obj_info.mInstance) + link.mRefCountOffset));
|
||||
|
||||
// Add referenced object to the list
|
||||
if (referenced_objects.find(obj_info.mInstance) == referenced_objects.end())
|
||||
referenced_objects.insert(obj_info.mInstance);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Referenced object not found, set pointer to nullptr
|
||||
Trace("ObjectStreamIn: Setting incorrect pointer to class of type %s to nullptr.", link.mRTTI->GetName());
|
||||
*link.mPointer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// Release unreferenced objects except the main object
|
||||
for (const IdentifierMap::value_type &j : mIdentifierMap)
|
||||
{
|
||||
const ObjectInfo &obj_info = j.second;
|
||||
|
||||
if (obj_info.mInstance != main_object)
|
||||
{
|
||||
ObjectSet::const_iterator k = referenced_objects.find(obj_info.mInstance);
|
||||
if (k == referenced_objects.end())
|
||||
{
|
||||
Trace("ObjectStreamIn: Releasing unreferenced object of type %s.", obj_info.mRTTI->GetName());
|
||||
obj_info.mRTTI->DestructObject(obj_info.mInstance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return main_object;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Release all objects if a fatal error occurred
|
||||
for (const IdentifierMap::value_type &i : mIdentifierMap)
|
||||
{
|
||||
const ObjectInfo &obj_info = i.second;
|
||||
obj_info.mRTTI->DestructObject(obj_info.mInstance);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void *ObjectStreamIn::ReadObject(const RTTI *& outRTTI)
|
||||
{
|
||||
// Read the object class
|
||||
void *object = nullptr;
|
||||
String class_name;
|
||||
if (ReadName(class_name))
|
||||
{
|
||||
// Get class description
|
||||
ClassDescriptionMap::iterator i = mClassDescriptionMap.find(class_name);
|
||||
if (i != mClassDescriptionMap.end())
|
||||
{
|
||||
const ClassDescription &class_desc = i->second;
|
||||
|
||||
// Read object identifier
|
||||
Identifier identifier;
|
||||
if (ReadIdentifier(identifier))
|
||||
{
|
||||
// Check if this object can be read or must be skipped
|
||||
if (identifier != sNullIdentifier
|
||||
&& class_desc.mRTTI
|
||||
&& !class_desc.mRTTI->IsAbstract())
|
||||
{
|
||||
// Create object instance
|
||||
outRTTI = class_desc.mRTTI;
|
||||
object = outRTTI->CreateObject();
|
||||
|
||||
// Read object attributes
|
||||
if (ReadClassData(class_desc, object))
|
||||
{
|
||||
// Add object to identifier map
|
||||
mIdentifierMap.try_emplace(identifier, object, outRTTI);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fatal error while reading attributes, release object
|
||||
outRTTI->DestructObject(object);
|
||||
object = nullptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Skip this object
|
||||
// TODO: This operation can fail, but there is no check yet
|
||||
Trace("ObjectStreamIn: Found uncreatable object %s.", class_name.c_str());
|
||||
ReadClassData(class_desc, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: This is a fatal error, but this function has no way of indicating this
|
||||
Trace("ObjectStreamIn: Found object of unknown class %s.", class_name.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
bool ObjectStreamIn::ReadRTTI()
|
||||
{
|
||||
// Read class name and find it's attribute info
|
||||
String class_name;
|
||||
if (!ReadName(class_name))
|
||||
return false;
|
||||
|
||||
// Find class
|
||||
const RTTI *rtti = Factory::sInstance->Find(class_name.c_str());
|
||||
if (rtti == nullptr)
|
||||
Trace("ObjectStreamIn: Unknown class: \"%s\".", class_name.c_str());
|
||||
|
||||
// Insert class description
|
||||
ClassDescription &class_desc = mClassDescriptionMap.try_emplace(class_name, rtti).first->second;
|
||||
|
||||
// Read the number of entries in the description
|
||||
uint32 count;
|
||||
if (!ReadCount(count))
|
||||
return false;
|
||||
|
||||
// Read the entries
|
||||
for (uint32 i = 0; i < count; ++i)
|
||||
{
|
||||
AttributeDescription attribute;
|
||||
|
||||
// Read name
|
||||
String attribute_name;
|
||||
if (!ReadName(attribute_name))
|
||||
return false;
|
||||
|
||||
// Read type
|
||||
if (!ReadDataType(attribute.mSourceType))
|
||||
return false;
|
||||
|
||||
// Read array depth
|
||||
while (attribute.mSourceType == EOSDataType::Array)
|
||||
{
|
||||
++attribute.mArrayDepth;
|
||||
if (!ReadDataType(attribute.mSourceType))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read instance/pointer class name
|
||||
if ((attribute.mSourceType == EOSDataType::Instance || attribute.mSourceType == EOSDataType::Pointer)
|
||||
&& !ReadName(attribute.mClassName))
|
||||
return false;
|
||||
|
||||
// Find attribute in rtti
|
||||
if (rtti)
|
||||
{
|
||||
// Find attribute index
|
||||
for (int idx = 0; idx < rtti->GetAttributeCount(); ++idx)
|
||||
{
|
||||
const SerializableAttribute &attr = rtti->GetAttribute(idx);
|
||||
if (attribute_name.compare(attr.GetName()) == 0)
|
||||
{
|
||||
attribute.mIndex = idx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if attribute is of expected type
|
||||
if (attribute.mIndex >= 0)
|
||||
{
|
||||
const SerializableAttribute &attr = rtti->GetAttribute(attribute.mIndex);
|
||||
if (attr.IsType(attribute.mArrayDepth, attribute.mSourceType, attribute.mClassName.c_str()))
|
||||
{
|
||||
// No conversion needed
|
||||
attribute.mDestinationType = attribute.mSourceType;
|
||||
}
|
||||
else if (attribute.mArrayDepth == 0 && attribute.mClassName.empty())
|
||||
{
|
||||
// Try to apply type conversions
|
||||
if (attribute.mSourceType == EOSDataType::T_Vec3 && attr.IsType(0, EOSDataType::T_DVec3, ""))
|
||||
attribute.mDestinationType = EOSDataType::T_DVec3;
|
||||
else if (attribute.mSourceType == EOSDataType::T_DVec3 && attr.IsType(0, EOSDataType::T_Vec3, ""))
|
||||
attribute.mDestinationType = EOSDataType::T_Vec3;
|
||||
else
|
||||
attribute.mIndex = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// No conversion exists
|
||||
attribute.mIndex = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add attribute to the class description
|
||||
class_desc.mAttributes.push_back(attribute);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ObjectStreamIn::ReadClassData(const char *inClassName, void *inInstance)
|
||||
{
|
||||
// Find the class description
|
||||
ClassDescriptionMap::iterator i = mClassDescriptionMap.find(inClassName);
|
||||
if (i != mClassDescriptionMap.end())
|
||||
return ReadClassData(i->second, inInstance);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ObjectStreamIn::ReadClassData(const ClassDescription &inClassDesc, void *inInstance)
|
||||
{
|
||||
// Read data for this class
|
||||
bool continue_reading = true;
|
||||
|
||||
for (const AttributeDescription &attr_desc : inClassDesc.mAttributes)
|
||||
{
|
||||
// Read or skip the attribute data
|
||||
if (attr_desc.mIndex >= 0 && inInstance)
|
||||
{
|
||||
const SerializableAttribute &attr = inClassDesc.mRTTI->GetAttribute(attr_desc.mIndex);
|
||||
if (attr_desc.mSourceType == attr_desc.mDestinationType)
|
||||
{
|
||||
continue_reading = attr.ReadData(*this, inInstance);
|
||||
}
|
||||
else if (attr_desc.mSourceType == EOSDataType::T_Vec3 && attr_desc.mDestinationType == EOSDataType::T_DVec3)
|
||||
{
|
||||
// Vec3 to DVec3
|
||||
Vec3 tmp;
|
||||
continue_reading = ReadPrimitiveData(tmp);
|
||||
if (continue_reading)
|
||||
*attr.GetMemberPointer<DVec3>(inInstance) = DVec3(tmp);
|
||||
}
|
||||
else if (attr_desc.mSourceType == EOSDataType::T_DVec3 && attr_desc.mDestinationType == EOSDataType::T_Vec3)
|
||||
{
|
||||
// DVec3 to Vec3
|
||||
DVec3 tmp;
|
||||
continue_reading = ReadPrimitiveData(tmp);
|
||||
if (continue_reading)
|
||||
*attr.GetMemberPointer<Vec3>(inInstance) = Vec3(tmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
JPH_ASSERT(false); // Unknown conversion
|
||||
continue_reading = SkipAttributeData(attr_desc.mArrayDepth, attr_desc.mSourceType, attr_desc.mClassName.c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
continue_reading = SkipAttributeData(attr_desc.mArrayDepth, attr_desc.mSourceType, attr_desc.mClassName.c_str());
|
||||
|
||||
if (!continue_reading)
|
||||
break;
|
||||
}
|
||||
|
||||
return continue_reading;
|
||||
}
|
||||
|
||||
bool ObjectStreamIn::ReadPointerData(const RTTI *inRTTI, void **inPointer, int inRefCountOffset)
|
||||
{
|
||||
Identifier identifier;
|
||||
if (ReadIdentifier(identifier))
|
||||
{
|
||||
if (identifier == sNullIdentifier)
|
||||
{
|
||||
// Set nullptr pointer
|
||||
inPointer = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Put pointer on the list to be resolved later on
|
||||
Link &link = mUnresolvedLinks.emplace_back();
|
||||
link.mPointer = inPointer;
|
||||
link.mRefCountOffset = inRefCountOffset;
|
||||
link.mIdentifier = identifier;
|
||||
link.mRTTI = inRTTI;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ObjectStreamIn::SkipAttributeData(int inArrayDepth, EOSDataType inDataType, const char *inClassName)
|
||||
{
|
||||
bool continue_reading = true;
|
||||
|
||||
// Get number of items to read
|
||||
uint32 count = 1;
|
||||
for (; inArrayDepth > 0; --inArrayDepth)
|
||||
{
|
||||
uint32 temporary;
|
||||
if (ReadCount(temporary))
|
||||
{
|
||||
// Multiply for multi dimensional arrays
|
||||
count *= temporary;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fatal error while reading array size
|
||||
continue_reading = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Read data for all items
|
||||
if (continue_reading)
|
||||
{
|
||||
if (inDataType == EOSDataType::Instance)
|
||||
{
|
||||
// Get the class description
|
||||
ClassDescriptionMap::iterator i = mClassDescriptionMap.find(inClassName);
|
||||
if (i != mClassDescriptionMap.end())
|
||||
{
|
||||
for (; count > 0 && continue_reading; --count)
|
||||
continue_reading = ReadClassData(i->second, nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
continue_reading = false;
|
||||
Trace("ObjectStreamIn: Found instance of unknown class %s.", inClassName);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (; count > 0 && continue_reading; --count)
|
||||
{
|
||||
switch (inDataType)
|
||||
{
|
||||
case EOSDataType::Pointer:
|
||||
{
|
||||
Identifier temporary;
|
||||
continue_reading = ReadIdentifier(temporary);
|
||||
break;
|
||||
}
|
||||
|
||||
case EOSDataType::T_uint8:
|
||||
{
|
||||
uint8 temporary;
|
||||
continue_reading = ReadPrimitiveData(temporary);
|
||||
break;
|
||||
}
|
||||
|
||||
case EOSDataType::T_uint16:
|
||||
{
|
||||
uint16 temporary;
|
||||
continue_reading = ReadPrimitiveData(temporary);
|
||||
break;
|
||||
}
|
||||
|
||||
case EOSDataType::T_int:
|
||||
{
|
||||
int temporary;
|
||||
continue_reading = ReadPrimitiveData(temporary);
|
||||
break;
|
||||
}
|
||||
|
||||
case EOSDataType::T_uint32:
|
||||
{
|
||||
uint32 temporary;
|
||||
continue_reading = ReadPrimitiveData(temporary);
|
||||
break;
|
||||
}
|
||||
|
||||
case EOSDataType::T_uint64:
|
||||
{
|
||||
uint64 temporary;
|
||||
continue_reading = ReadPrimitiveData(temporary);
|
||||
break;
|
||||
}
|
||||
|
||||
case EOSDataType::T_float:
|
||||
{
|
||||
float temporary;
|
||||
continue_reading = ReadPrimitiveData(temporary);
|
||||
break;
|
||||
}
|
||||
|
||||
case EOSDataType::T_double:
|
||||
{
|
||||
double temporary;
|
||||
continue_reading = ReadPrimitiveData(temporary);
|
||||
break;
|
||||
}
|
||||
|
||||
case EOSDataType::T_bool:
|
||||
{
|
||||
bool temporary;
|
||||
continue_reading = ReadPrimitiveData(temporary);
|
||||
break;
|
||||
}
|
||||
|
||||
case EOSDataType::T_String:
|
||||
{
|
||||
String temporary;
|
||||
continue_reading = ReadPrimitiveData(temporary);
|
||||
break;
|
||||
}
|
||||
|
||||
case EOSDataType::T_Float3:
|
||||
{
|
||||
Float3 temporary;
|
||||
continue_reading = ReadPrimitiveData(temporary);
|
||||
break;
|
||||
}
|
||||
|
||||
case EOSDataType::T_Float4:
|
||||
{
|
||||
Float4 temporary;
|
||||
continue_reading = ReadPrimitiveData(temporary);
|
||||
break;
|
||||
}
|
||||
|
||||
case EOSDataType::T_Double3:
|
||||
{
|
||||
Double3 temporary;
|
||||
continue_reading = ReadPrimitiveData(temporary);
|
||||
break;
|
||||
}
|
||||
|
||||
case EOSDataType::T_Vec3:
|
||||
{
|
||||
Vec3 temporary;
|
||||
continue_reading = ReadPrimitiveData(temporary);
|
||||
break;
|
||||
}
|
||||
|
||||
case EOSDataType::T_DVec3:
|
||||
{
|
||||
DVec3 temporary;
|
||||
continue_reading = ReadPrimitiveData(temporary);
|
||||
break;
|
||||
}
|
||||
|
||||
case EOSDataType::T_Vec4:
|
||||
{
|
||||
Vec4 temporary;
|
||||
continue_reading = ReadPrimitiveData(temporary);
|
||||
break;
|
||||
}
|
||||
|
||||
case EOSDataType::T_UVec4:
|
||||
{
|
||||
UVec4 temporary;
|
||||
continue_reading = ReadPrimitiveData(temporary);
|
||||
break;
|
||||
}
|
||||
|
||||
case EOSDataType::T_Quat:
|
||||
{
|
||||
Quat temporary;
|
||||
continue_reading = ReadPrimitiveData(temporary);
|
||||
break;
|
||||
}
|
||||
|
||||
case EOSDataType::T_Mat44:
|
||||
{
|
||||
Mat44 temporary;
|
||||
continue_reading = ReadPrimitiveData(temporary);
|
||||
break;
|
||||
}
|
||||
|
||||
case EOSDataType::T_DMat44:
|
||||
{
|
||||
DMat44 temporary;
|
||||
continue_reading = ReadPrimitiveData(temporary);
|
||||
break;
|
||||
}
|
||||
|
||||
case EOSDataType::Array:
|
||||
case EOSDataType::Object:
|
||||
case EOSDataType::Declare:
|
||||
case EOSDataType::Instance:
|
||||
case EOSDataType::Invalid:
|
||||
default:
|
||||
continue_reading = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return continue_reading;
|
||||
}
|
||||
|
||||
JPH_NAMESPACE_END
|
||||
|
||||
#endif // JPH_OBJECT_STREAM
|
||||
148
lib/haxejolt/JoltPhysics/Jolt/ObjectStream/ObjectStreamIn.h
Normal file
148
lib/haxejolt/JoltPhysics/Jolt/ObjectStream/ObjectStreamIn.h
Normal file
@ -0,0 +1,148 @@
|
||||
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
|
||||
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Jolt/ObjectStream/ObjectStream.h>
|
||||
#include <Jolt/Core/Reference.h>
|
||||
#include <Jolt/Core/RTTI.h>
|
||||
#include <Jolt/Core/UnorderedMap.h>
|
||||
|
||||
JPH_SUPPRESS_WARNINGS_STD_BEGIN
|
||||
#include <fstream>
|
||||
JPH_SUPPRESS_WARNINGS_STD_END
|
||||
|
||||
#ifdef JPH_OBJECT_STREAM
|
||||
|
||||
JPH_NAMESPACE_BEGIN
|
||||
|
||||
/// ObjectStreamIn contains all logic for reading an object from disk. It is the base
|
||||
/// class for the text and binary input streams (ObjectStreamTextIn and ObjectStreamBinaryIn).
|
||||
class JPH_EXPORT ObjectStreamIn : public IObjectStreamIn
|
||||
{
|
||||
private:
|
||||
struct ClassDescription;
|
||||
|
||||
public:
|
||||
/// Main function to read an object from a stream
|
||||
template <class T>
|
||||
static bool sReadObject(istream &inStream, T *&outObject)
|
||||
{
|
||||
// Create the input stream
|
||||
bool result = false;
|
||||
ObjectStreamIn *stream = ObjectStreamIn::Open(inStream);
|
||||
if (stream)
|
||||
{
|
||||
// Read the object
|
||||
outObject = (T *)stream->Read(JPH_RTTI(T));
|
||||
result = (outObject != nullptr);
|
||||
delete stream;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Main function to read an object from a stream (reference counting pointer version)
|
||||
template <class T>
|
||||
static bool sReadObject(istream &inStream, Ref<T> &outObject)
|
||||
{
|
||||
T *object = nullptr;
|
||||
bool result = sReadObject(inStream, object);
|
||||
outObject = object;
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Main function to read an object from a file
|
||||
template <class T>
|
||||
static bool sReadObject(const char *inFileName, T *&outObject)
|
||||
{
|
||||
std::ifstream stream;
|
||||
stream.open(inFileName, std::ifstream::in | std::ifstream::binary);
|
||||
if (!stream.is_open())
|
||||
return false;
|
||||
return sReadObject(stream, outObject);
|
||||
}
|
||||
|
||||
/// Main function to read an object from a file (reference counting pointer version)
|
||||
template <class T>
|
||||
static bool sReadObject(const char *inFileName, Ref<T> &outObject)
|
||||
{
|
||||
T *object = nullptr;
|
||||
bool result = sReadObject(inFileName, object);
|
||||
outObject = object;
|
||||
return result;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// EVERYTHING BELOW THIS SHOULD NOT DIRECTLY BE CALLED
|
||||
//////////////////////////////////////////////////////
|
||||
|
||||
///@name Serialization operations
|
||||
void * Read(const RTTI *inRTTI);
|
||||
void * ReadObject(const RTTI *& outRTTI);
|
||||
bool ReadRTTI();
|
||||
virtual bool ReadClassData(const char *inClassName, void *inInstance) override;
|
||||
bool ReadClassData(const ClassDescription &inClassDesc, void *inInstance);
|
||||
virtual bool ReadPointerData(const RTTI *inRTTI, void **inPointer, int inRefCountOffset = -1) override;
|
||||
bool SkipAttributeData(int inArrayDepth, EOSDataType inDataType, const char *inClassName);
|
||||
|
||||
protected:
|
||||
/// Constructor
|
||||
explicit ObjectStreamIn(istream &inStream);
|
||||
|
||||
/// Determine the type and version of an object stream
|
||||
static bool GetInfo(istream &inStream, EStreamType &outType, int &outVersion, int &outRevision);
|
||||
|
||||
/// Static constructor
|
||||
static ObjectStreamIn * Open(istream &inStream);
|
||||
|
||||
istream & mStream;
|
||||
|
||||
private:
|
||||
/// Class descriptions
|
||||
struct AttributeDescription
|
||||
{
|
||||
int mArrayDepth = 0;
|
||||
EOSDataType mSourceType = EOSDataType::Invalid;
|
||||
EOSDataType mDestinationType = EOSDataType::Invalid;
|
||||
String mClassName;
|
||||
int mIndex = -1;
|
||||
};
|
||||
|
||||
struct ClassDescription
|
||||
{
|
||||
ClassDescription() = default;
|
||||
explicit ClassDescription(const RTTI *inRTTI) : mRTTI(inRTTI) { }
|
||||
|
||||
const RTTI * mRTTI = nullptr;
|
||||
Array<AttributeDescription> mAttributes;
|
||||
};
|
||||
|
||||
struct ObjectInfo
|
||||
{
|
||||
ObjectInfo() = default;
|
||||
ObjectInfo(void *inInstance, const RTTI *inRTTI) : mInstance(inInstance), mRTTI(inRTTI) { }
|
||||
|
||||
void * mInstance = nullptr;
|
||||
const RTTI * mRTTI = nullptr;
|
||||
};
|
||||
|
||||
struct Link
|
||||
{
|
||||
void ** mPointer;
|
||||
int mRefCountOffset;
|
||||
Identifier mIdentifier;
|
||||
const RTTI * mRTTI;
|
||||
};
|
||||
|
||||
using IdentifierMap = UnorderedMap<Identifier, ObjectInfo>;
|
||||
using ClassDescriptionMap = UnorderedMap<String, ClassDescription>;
|
||||
|
||||
ClassDescriptionMap mClassDescriptionMap;
|
||||
IdentifierMap mIdentifierMap; ///< Links identifier to an object pointer
|
||||
Array<Link> mUnresolvedLinks; ///< All pointers (links) are resolved after reading the entire file, e.g. when all object exist
|
||||
};
|
||||
|
||||
JPH_NAMESPACE_END
|
||||
|
||||
#endif // JPH_OBJECT_STREAM
|
||||
166
lib/haxejolt/JoltPhysics/Jolt/ObjectStream/ObjectStreamOut.cpp
Normal file
166
lib/haxejolt/JoltPhysics/Jolt/ObjectStream/ObjectStreamOut.cpp
Normal file
@ -0,0 +1,166 @@
|
||||
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
|
||||
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#include <Jolt/Jolt.h>
|
||||
|
||||
#include <Jolt/ObjectStream/ObjectStreamOut.h>
|
||||
#include <Jolt/ObjectStream/ObjectStreamTextOut.h>
|
||||
#include <Jolt/ObjectStream/ObjectStreamBinaryOut.h>
|
||||
#include <Jolt/ObjectStream/TypeDeclarations.h>
|
||||
|
||||
#ifdef JPH_OBJECT_STREAM
|
||||
|
||||
JPH_NAMESPACE_BEGIN
|
||||
|
||||
ObjectStreamOut::ObjectStreamOut(ostream &inStream) :
|
||||
mStream(inStream)
|
||||
{
|
||||
// Add all primitives to the class set
|
||||
#define JPH_DECLARE_PRIMITIVE(name) mClassSet.insert(JPH_RTTI(name));
|
||||
#include <Jolt/ObjectStream/ObjectStreamTypes.h>
|
||||
}
|
||||
|
||||
ObjectStreamOut *ObjectStreamOut::Open(EStreamType inType, ostream &inStream)
|
||||
{
|
||||
switch (inType)
|
||||
{
|
||||
case EStreamType::Text: return new ObjectStreamTextOut(inStream);
|
||||
case EStreamType::Binary: return new ObjectStreamBinaryOut(inStream);
|
||||
default: JPH_ASSERT(false);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool ObjectStreamOut::Write(const void *inObject, const RTTI *inRTTI)
|
||||
{
|
||||
// Assign a new identifier to the object and write it
|
||||
mIdentifierMap.try_emplace(inObject, mNextIdentifier, inRTTI);
|
||||
mNextIdentifier++;
|
||||
WriteObject(inObject);
|
||||
|
||||
// Write all linked objects
|
||||
ObjectQueue::size_type cur = 0;
|
||||
for (; cur < mObjectQueue.size() && !mStream.fail(); ++cur)
|
||||
WriteObject(mObjectQueue[cur]);
|
||||
mObjectQueue.erase(mObjectQueue.begin(), mObjectQueue.begin() + cur);
|
||||
|
||||
return !mStream.fail();
|
||||
}
|
||||
|
||||
void ObjectStreamOut::WriteObject(const void *inObject)
|
||||
{
|
||||
// Find object identifier
|
||||
IdentifierMap::iterator i = mIdentifierMap.find(inObject);
|
||||
JPH_ASSERT(i != mIdentifierMap.end());
|
||||
|
||||
// Write class description and associated descriptions
|
||||
QueueRTTI(i->second.mRTTI);
|
||||
ClassQueue::size_type cur = 0;
|
||||
for (; cur < mClassQueue.size() && !mStream.fail(); ++cur)
|
||||
WriteRTTI(mClassQueue[cur]);
|
||||
mClassQueue.erase(mClassQueue.begin(), mClassQueue.begin() + cur);
|
||||
|
||||
HintNextItem();
|
||||
HintNextItem();
|
||||
|
||||
// Write object header.
|
||||
WriteDataType(EOSDataType::Object);
|
||||
WriteName(i->second.mRTTI->GetName());
|
||||
WriteIdentifier(i->second.mIdentifier);
|
||||
|
||||
// Write attribute data
|
||||
WriteClassData(i->second.mRTTI, inObject);
|
||||
}
|
||||
|
||||
void ObjectStreamOut::QueueRTTI(const RTTI *inRTTI)
|
||||
{
|
||||
ClassSet::const_iterator i = mClassSet.find(inRTTI);
|
||||
if (i == mClassSet.end())
|
||||
{
|
||||
mClassSet.insert(inRTTI);
|
||||
mClassQueue.push_back(inRTTI);
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectStreamOut::WriteRTTI(const RTTI *inRTTI)
|
||||
{
|
||||
HintNextItem();
|
||||
HintNextItem();
|
||||
|
||||
// Write class header. E.g. in text mode: "class <name> <attr-count>"
|
||||
WriteDataType(EOSDataType::Declare);
|
||||
WriteName(inRTTI->GetName());
|
||||
WriteCount(inRTTI->GetAttributeCount());
|
||||
|
||||
// Write class attribute info
|
||||
HintIndentUp();
|
||||
for (int attr_index = 0; attr_index < inRTTI->GetAttributeCount(); ++attr_index)
|
||||
{
|
||||
// Get attribute
|
||||
const SerializableAttribute &attr = inRTTI->GetAttribute(attr_index);
|
||||
|
||||
// Write definition of attribute class if undefined
|
||||
const RTTI *rtti = attr.GetMemberPrimitiveType();
|
||||
if (rtti != nullptr)
|
||||
QueueRTTI(rtti);
|
||||
|
||||
HintNextItem();
|
||||
|
||||
// Write attribute information.
|
||||
WriteName(attr.GetName());
|
||||
attr.WriteDataType(*this);
|
||||
}
|
||||
HintIndentDown();
|
||||
}
|
||||
|
||||
void ObjectStreamOut::WriteClassData(const RTTI *inRTTI, const void *inInstance)
|
||||
{
|
||||
JPH_ASSERT(inInstance);
|
||||
|
||||
// Write attributes
|
||||
HintIndentUp();
|
||||
for (int attr_index = 0; attr_index < inRTTI->GetAttributeCount(); ++attr_index)
|
||||
{
|
||||
// Get attribute
|
||||
const SerializableAttribute &attr = inRTTI->GetAttribute(attr_index);
|
||||
attr.WriteData(*this, inInstance);
|
||||
}
|
||||
HintIndentDown();
|
||||
}
|
||||
|
||||
void ObjectStreamOut::WritePointerData(const RTTI *inRTTI, const void *inPointer)
|
||||
{
|
||||
Identifier identifier;
|
||||
|
||||
if (inPointer)
|
||||
{
|
||||
// Check if this object has an identifier
|
||||
IdentifierMap::iterator i = mIdentifierMap.find(inPointer);
|
||||
if (i != mIdentifierMap.end())
|
||||
{
|
||||
// Object already has an identifier
|
||||
identifier = i->second.mIdentifier;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Assign a new identifier to this object and queue it for serialization
|
||||
identifier = mNextIdentifier++;
|
||||
mIdentifierMap.try_emplace(inPointer, identifier, inRTTI);
|
||||
mObjectQueue.push_back(inPointer);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Write nullptr pointer
|
||||
identifier = sNullIdentifier;
|
||||
}
|
||||
|
||||
// Write the identifier
|
||||
HintNextItem();
|
||||
WriteIdentifier(identifier);
|
||||
}
|
||||
|
||||
JPH_NAMESPACE_END
|
||||
|
||||
#endif // JPH_OBJECT_STREAM
|
||||
101
lib/haxejolt/JoltPhysics/Jolt/ObjectStream/ObjectStreamOut.h
Normal file
101
lib/haxejolt/JoltPhysics/Jolt/ObjectStream/ObjectStreamOut.h
Normal file
@ -0,0 +1,101 @@
|
||||
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
|
||||
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Jolt/ObjectStream/ObjectStream.h>
|
||||
#include <Jolt/Core/RTTI.h>
|
||||
#include <Jolt/Core/UnorderedMap.h>
|
||||
#include <Jolt/Core/UnorderedSet.h>
|
||||
|
||||
JPH_SUPPRESS_WARNINGS_STD_BEGIN
|
||||
#include <fstream>
|
||||
JPH_SUPPRESS_WARNINGS_STD_END
|
||||
|
||||
#ifdef JPH_OBJECT_STREAM
|
||||
|
||||
JPH_NAMESPACE_BEGIN
|
||||
|
||||
/// ObjectStreamOut contains all logic for writing an object to disk. It is the base
|
||||
/// class for the text and binary output streams (ObjectStreamTextOut and ObjectStreamBinaryOut).
|
||||
class JPH_EXPORT ObjectStreamOut : public IObjectStreamOut
|
||||
{
|
||||
private:
|
||||
struct ObjectInfo;
|
||||
|
||||
public:
|
||||
/// Main function to write an object to a stream
|
||||
template <class T>
|
||||
static bool sWriteObject(ostream &inStream, ObjectStream::EStreamType inType, const T &inObject)
|
||||
{
|
||||
// Create the output stream
|
||||
bool result = false;
|
||||
ObjectStreamOut *stream = ObjectStreamOut::Open(inType, inStream);
|
||||
if (stream)
|
||||
{
|
||||
// Write the object to the stream
|
||||
result = stream->Write((void *)&inObject, GetRTTI(&inObject));
|
||||
delete stream;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Main function to write an object to a file
|
||||
template <class T>
|
||||
static bool sWriteObject(const char *inFileName, ObjectStream::EStreamType inType, const T &inObject)
|
||||
{
|
||||
std::ofstream stream;
|
||||
stream.open(inFileName, std::ofstream::out | std::ofstream::trunc | std::ofstream::binary);
|
||||
if (!stream.is_open())
|
||||
return false;
|
||||
return sWriteObject(stream, inType, inObject);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// EVERYTHING BELOW THIS SHOULD NOT DIRECTLY BE CALLED
|
||||
//////////////////////////////////////////////////////
|
||||
|
||||
///@name Serialization operations
|
||||
bool Write(const void *inObject, const RTTI *inRTTI);
|
||||
void WriteObject(const void *inObject);
|
||||
void QueueRTTI(const RTTI *inRTTI);
|
||||
void WriteRTTI(const RTTI *inRTTI);
|
||||
virtual void WriteClassData(const RTTI *inRTTI, const void *inInstance) override;
|
||||
virtual void WritePointerData(const RTTI *inRTTI, const void *inPointer) override;
|
||||
|
||||
protected:
|
||||
/// Static constructor
|
||||
static ObjectStreamOut * Open(EStreamType inType, ostream &inStream);
|
||||
|
||||
/// Constructor
|
||||
explicit ObjectStreamOut(ostream &inStream);
|
||||
|
||||
ostream & mStream;
|
||||
|
||||
private:
|
||||
struct ObjectInfo
|
||||
{
|
||||
ObjectInfo() : mIdentifier(0), mRTTI(nullptr) { }
|
||||
ObjectInfo(Identifier inIdentifier, const RTTI *inRTTI) : mIdentifier(inIdentifier), mRTTI(inRTTI) { }
|
||||
|
||||
Identifier mIdentifier;
|
||||
const RTTI * mRTTI;
|
||||
};
|
||||
|
||||
using IdentifierMap = UnorderedMap<const void *, ObjectInfo>;
|
||||
using ClassSet = UnorderedSet<const RTTI *>;
|
||||
using ObjectQueue = Array<const void *>;
|
||||
using ClassQueue = Array<const RTTI *>;
|
||||
|
||||
Identifier mNextIdentifier = sNullIdentifier + 1; ///< Next free identifier for this stream
|
||||
IdentifierMap mIdentifierMap; ///< Links object pointer to an identifier
|
||||
ObjectQueue mObjectQueue; ///< Queue of objects to be written
|
||||
ClassSet mClassSet; ///< List of classes already written
|
||||
ClassQueue mClassQueue; ///< List of classes waiting to be written
|
||||
};
|
||||
|
||||
JPH_NAMESPACE_END
|
||||
|
||||
#endif // JPH_OBJECT_STREAM
|
||||
@ -0,0 +1,418 @@
|
||||
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
|
||||
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#include <Jolt/Jolt.h>
|
||||
|
||||
#ifdef JPH_OBJECT_STREAM
|
||||
|
||||
#include <Jolt/ObjectStream/ObjectStreamTextIn.h>
|
||||
|
||||
JPH_NAMESPACE_BEGIN
|
||||
|
||||
ObjectStreamTextIn::ObjectStreamTextIn(istream &inStream) :
|
||||
ObjectStreamIn(inStream)
|
||||
{
|
||||
}
|
||||
|
||||
bool ObjectStreamTextIn::ReadDataType(EOSDataType &outType)
|
||||
{
|
||||
String token;
|
||||
if (ReadWord(token))
|
||||
{
|
||||
transform(token.begin(), token.end(), token.begin(), [](char inValue) { return (char)tolower(inValue); });
|
||||
if (token == "declare")
|
||||
outType = EOSDataType::Declare;
|
||||
else if (token == "object")
|
||||
outType = EOSDataType::Object;
|
||||
else if (token == "instance")
|
||||
outType = EOSDataType::Instance;
|
||||
else if (token == "pointer")
|
||||
outType = EOSDataType::Pointer;
|
||||
else if (token == "array")
|
||||
outType = EOSDataType::Array;
|
||||
else if (token == "uint8")
|
||||
outType = EOSDataType::T_uint8;
|
||||
else if (token == "uint16")
|
||||
outType = EOSDataType::T_uint16;
|
||||
else if (token == "int")
|
||||
outType = EOSDataType::T_int;
|
||||
else if (token == "uint32")
|
||||
outType = EOSDataType::T_uint32;
|
||||
else if (token == "uint64")
|
||||
outType = EOSDataType::T_uint64;
|
||||
else if (token == "float")
|
||||
outType = EOSDataType::T_float;
|
||||
else if (token == "double")
|
||||
outType = EOSDataType::T_double;
|
||||
else if (token == "bool")
|
||||
outType = EOSDataType::T_bool;
|
||||
else if (token == "string")
|
||||
outType = EOSDataType::T_String;
|
||||
else if (token == "float3")
|
||||
outType = EOSDataType::T_Float3;
|
||||
else if (token == "float4")
|
||||
outType = EOSDataType::T_Float4;
|
||||
else if (token == "double3")
|
||||
outType = EOSDataType::T_Double3;
|
||||
else if (token == "vec3")
|
||||
outType = EOSDataType::T_Vec3;
|
||||
else if (token == "dvec3")
|
||||
outType = EOSDataType::T_DVec3;
|
||||
else if (token == "vec4")
|
||||
outType = EOSDataType::T_Vec4;
|
||||
else if (token == "uvec4")
|
||||
outType = EOSDataType::T_UVec4;
|
||||
else if (token == "quat")
|
||||
outType = EOSDataType::T_Quat;
|
||||
else if (token == "mat44")
|
||||
outType = EOSDataType::T_Mat44;
|
||||
else if (token == "dmat44")
|
||||
outType = EOSDataType::T_DMat44;
|
||||
else
|
||||
{
|
||||
Trace("ObjectStreamTextIn: Found unknown data type.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ObjectStreamTextIn::ReadName(String &outName)
|
||||
{
|
||||
return ReadWord(outName);
|
||||
}
|
||||
|
||||
bool ObjectStreamTextIn::ReadIdentifier(Identifier &outIdentifier)
|
||||
{
|
||||
String token;
|
||||
if (!ReadWord(token))
|
||||
return false;
|
||||
outIdentifier = (uint32)std::strtoul(token.c_str(), nullptr, 16);
|
||||
if (errno == ERANGE)
|
||||
{
|
||||
outIdentifier = sNullIdentifier;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ObjectStreamTextIn::ReadCount(uint32 &outCount)
|
||||
{
|
||||
return ReadPrimitiveData(outCount);
|
||||
}
|
||||
|
||||
bool ObjectStreamTextIn::ReadPrimitiveData(uint8 &outPrimitive)
|
||||
{
|
||||
String token;
|
||||
if (!ReadWord(token))
|
||||
return false;
|
||||
uint32 temporary;
|
||||
IStringStream stream(token);
|
||||
stream >> temporary;
|
||||
if (!stream.fail())
|
||||
{
|
||||
outPrimitive = (uint8)temporary;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ObjectStreamTextIn::ReadPrimitiveData(uint16 &outPrimitive)
|
||||
{
|
||||
String token;
|
||||
if (!ReadWord(token))
|
||||
return false;
|
||||
uint32 temporary;
|
||||
IStringStream stream(token);
|
||||
stream >> temporary;
|
||||
if (!stream.fail())
|
||||
{
|
||||
outPrimitive = (uint16)temporary;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ObjectStreamTextIn::ReadPrimitiveData(int &outPrimitive)
|
||||
{
|
||||
String token;
|
||||
if (!ReadWord(token))
|
||||
return false;
|
||||
IStringStream stream(token);
|
||||
stream >> outPrimitive;
|
||||
return !stream.fail();
|
||||
}
|
||||
|
||||
bool ObjectStreamTextIn::ReadPrimitiveData(uint32 &outPrimitive)
|
||||
{
|
||||
String token;
|
||||
if (!ReadWord(token))
|
||||
return false;
|
||||
IStringStream stream(token);
|
||||
stream >> outPrimitive;
|
||||
return !stream.fail();
|
||||
}
|
||||
|
||||
bool ObjectStreamTextIn::ReadPrimitiveData(uint64 &outPrimitive)
|
||||
{
|
||||
String token;
|
||||
if (!ReadWord(token))
|
||||
return false;
|
||||
IStringStream stream(token);
|
||||
stream >> outPrimitive;
|
||||
return !stream.fail();
|
||||
}
|
||||
|
||||
bool ObjectStreamTextIn::ReadPrimitiveData(float &outPrimitive)
|
||||
{
|
||||
String token;
|
||||
if (!ReadWord(token))
|
||||
return false;
|
||||
IStringStream stream(token);
|
||||
stream >> outPrimitive;
|
||||
return !stream.fail();
|
||||
}
|
||||
|
||||
bool ObjectStreamTextIn::ReadPrimitiveData(double &outPrimitive)
|
||||
{
|
||||
String token;
|
||||
if (!ReadWord(token))
|
||||
return false;
|
||||
IStringStream stream(token);
|
||||
stream >> outPrimitive;
|
||||
return !stream.fail();
|
||||
}
|
||||
|
||||
bool ObjectStreamTextIn::ReadPrimitiveData(bool &outPrimitive)
|
||||
{
|
||||
String token;
|
||||
if (!ReadWord(token))
|
||||
return false;
|
||||
transform(token.begin(), token.end(), token.begin(), [](char inValue) { return (char)tolower(inValue); });
|
||||
outPrimitive = token == "true";
|
||||
return outPrimitive || token == "false";
|
||||
}
|
||||
|
||||
bool ObjectStreamTextIn::ReadPrimitiveData(String &outPrimitive)
|
||||
{
|
||||
outPrimitive.clear();
|
||||
|
||||
char c;
|
||||
|
||||
// Skip whitespace
|
||||
for (;;)
|
||||
{
|
||||
if (!ReadChar(c))
|
||||
return false;
|
||||
|
||||
if (!isspace(c))
|
||||
break;
|
||||
}
|
||||
|
||||
// Check if it is a opening quote
|
||||
if (c != '\"')
|
||||
return false;
|
||||
|
||||
// Read string and interpret special characters
|
||||
String result;
|
||||
bool escaped = false;
|
||||
for (;;)
|
||||
{
|
||||
if (!ReadChar(c))
|
||||
break;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '\n':
|
||||
case '\t':
|
||||
break;
|
||||
|
||||
case '\\':
|
||||
if (escaped)
|
||||
{
|
||||
result += '\\';
|
||||
escaped = false;
|
||||
}
|
||||
else
|
||||
escaped = true;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
if (escaped)
|
||||
{
|
||||
result += '\n';
|
||||
escaped = false;
|
||||
}
|
||||
else
|
||||
result += 'n';
|
||||
break;
|
||||
|
||||
case 't':
|
||||
if (escaped)
|
||||
{
|
||||
result += '\t';
|
||||
escaped = false;
|
||||
}
|
||||
else
|
||||
result += 't';
|
||||
break;
|
||||
|
||||
case '\"':
|
||||
if (escaped)
|
||||
{
|
||||
result += '\"';
|
||||
escaped = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Found closing double quote
|
||||
outPrimitive = result;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (escaped)
|
||||
escaped = false;
|
||||
else
|
||||
result += c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ObjectStreamTextIn::ReadPrimitiveData(Float3 &outPrimitive)
|
||||
{
|
||||
float x, y, z;
|
||||
if (!ReadPrimitiveData(x) || !ReadPrimitiveData(y) || !ReadPrimitiveData(z))
|
||||
return false;
|
||||
outPrimitive = Float3(x, y, z);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ObjectStreamTextIn::ReadPrimitiveData(Float4 &outPrimitive)
|
||||
{
|
||||
float x, y, z, w;
|
||||
if (!ReadPrimitiveData(x) || !ReadPrimitiveData(y) || !ReadPrimitiveData(z) || !ReadPrimitiveData(w))
|
||||
return false;
|
||||
outPrimitive = Float4(x, y, z, w);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ObjectStreamTextIn::ReadPrimitiveData(Double3 &outPrimitive)
|
||||
{
|
||||
double x, y, z;
|
||||
if (!ReadPrimitiveData(x) || !ReadPrimitiveData(y) || !ReadPrimitiveData(z))
|
||||
return false;
|
||||
outPrimitive = Double3(x, y, z);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ObjectStreamTextIn::ReadPrimitiveData(Vec3 &outPrimitive)
|
||||
{
|
||||
float x, y, z;
|
||||
if (!ReadPrimitiveData(x) || !ReadPrimitiveData(y) || !ReadPrimitiveData(z))
|
||||
return false;
|
||||
outPrimitive = Vec3(x, y, z);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ObjectStreamTextIn::ReadPrimitiveData(DVec3 &outPrimitive)
|
||||
{
|
||||
double x, y, z;
|
||||
if (!ReadPrimitiveData(x) || !ReadPrimitiveData(y) || !ReadPrimitiveData(z))
|
||||
return false;
|
||||
outPrimitive = DVec3(x, y, z);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ObjectStreamTextIn::ReadPrimitiveData(Vec4 &outPrimitive)
|
||||
{
|
||||
float x, y, z, w;
|
||||
if (!ReadPrimitiveData(x) || !ReadPrimitiveData(y) || !ReadPrimitiveData(z) || !ReadPrimitiveData(w))
|
||||
return false;
|
||||
outPrimitive = Vec4(x, y, z, w);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ObjectStreamTextIn::ReadPrimitiveData(UVec4 &outPrimitive)
|
||||
{
|
||||
uint32 x, y, z, w;
|
||||
if (!ReadPrimitiveData(x) || !ReadPrimitiveData(y) || !ReadPrimitiveData(z) || !ReadPrimitiveData(w))
|
||||
return false;
|
||||
outPrimitive = UVec4(x, y, z, w);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ObjectStreamTextIn::ReadPrimitiveData(Quat &outPrimitive)
|
||||
{
|
||||
float x, y, z, w;
|
||||
if (!ReadPrimitiveData(x) || !ReadPrimitiveData(y) || !ReadPrimitiveData(z) || !ReadPrimitiveData(w))
|
||||
return false;
|
||||
outPrimitive = Quat(x, y, z, w);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ObjectStreamTextIn::ReadPrimitiveData(Mat44 &outPrimitive)
|
||||
{
|
||||
Vec4 c0, c1, c2, c3;
|
||||
if (!ReadPrimitiveData(c0) || !ReadPrimitiveData(c1) || !ReadPrimitiveData(c2) || !ReadPrimitiveData(c3))
|
||||
return false;
|
||||
outPrimitive = Mat44(c0, c1, c2, c3);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ObjectStreamTextIn::ReadPrimitiveData(DMat44 &outPrimitive)
|
||||
{
|
||||
Vec4 c0, c1, c2;
|
||||
DVec3 c3;
|
||||
if (!ReadPrimitiveData(c0) || !ReadPrimitiveData(c1) || !ReadPrimitiveData(c2) || !ReadPrimitiveData(c3))
|
||||
return false;
|
||||
outPrimitive = DMat44(c0, c1, c2, c3);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ObjectStreamTextIn::ReadChar(char &outChar)
|
||||
{
|
||||
mStream.get(outChar);
|
||||
return !mStream.eof();
|
||||
}
|
||||
|
||||
bool ObjectStreamTextIn::ReadWord(String &outWord)
|
||||
{
|
||||
outWord.clear();
|
||||
|
||||
char c;
|
||||
|
||||
// Skip whitespace
|
||||
for (;;)
|
||||
{
|
||||
if (!ReadChar(c))
|
||||
return false;
|
||||
|
||||
if (!isspace(c))
|
||||
break;
|
||||
}
|
||||
|
||||
// Read word
|
||||
for (;;)
|
||||
{
|
||||
outWord += c;
|
||||
|
||||
if (!ReadChar(c))
|
||||
break;
|
||||
|
||||
if (isspace(c))
|
||||
break;
|
||||
}
|
||||
|
||||
return !outWord.empty();
|
||||
}
|
||||
|
||||
JPH_NAMESPACE_END
|
||||
|
||||
#endif // JPH_OBJECT_STREAM
|
||||
@ -0,0 +1,55 @@
|
||||
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
|
||||
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Jolt/ObjectStream/ObjectStreamIn.h>
|
||||
|
||||
#ifdef JPH_OBJECT_STREAM
|
||||
|
||||
JPH_NAMESPACE_BEGIN
|
||||
|
||||
/// Implementation of ObjectStream text input stream.
|
||||
class JPH_EXPORT ObjectStreamTextIn : public ObjectStreamIn
|
||||
{
|
||||
public:
|
||||
JPH_OVERRIDE_NEW_DELETE
|
||||
|
||||
/// Constructor
|
||||
explicit ObjectStreamTextIn(istream &inStream);
|
||||
|
||||
///@name Input type specific operations
|
||||
virtual bool ReadDataType(EOSDataType &outType) override;
|
||||
virtual bool ReadName(String &outName) override;
|
||||
virtual bool ReadIdentifier(Identifier &outIdentifier) override;
|
||||
virtual bool ReadCount(uint32 &outCount) override;
|
||||
|
||||
virtual bool ReadPrimitiveData(uint8 &outPrimitive) override;
|
||||
virtual bool ReadPrimitiveData(uint16 &outPrimitive) override;
|
||||
virtual bool ReadPrimitiveData(int &outPrimitive) override;
|
||||
virtual bool ReadPrimitiveData(uint32 &outPrimitive) override;
|
||||
virtual bool ReadPrimitiveData(uint64 &outPrimitive) override;
|
||||
virtual bool ReadPrimitiveData(float &outPrimitive) override;
|
||||
virtual bool ReadPrimitiveData(double &outPrimitive) override;
|
||||
virtual bool ReadPrimitiveData(bool &outPrimitive) override;
|
||||
virtual bool ReadPrimitiveData(String &outPrimitive) override;
|
||||
virtual bool ReadPrimitiveData(Float3 &outPrimitive) override;
|
||||
virtual bool ReadPrimitiveData(Float4 &outPrimitive) override;
|
||||
virtual bool ReadPrimitiveData(Double3 &outPrimitive) override;
|
||||
virtual bool ReadPrimitiveData(Vec3 &outPrimitive) override;
|
||||
virtual bool ReadPrimitiveData(DVec3 &outPrimitive) override;
|
||||
virtual bool ReadPrimitiveData(Vec4 &outPrimitive) override;
|
||||
virtual bool ReadPrimitiveData(UVec4 &outPrimitive) override;
|
||||
virtual bool ReadPrimitiveData(Quat &outPrimitive) override;
|
||||
virtual bool ReadPrimitiveData(Mat44 &outPrimitive) override;
|
||||
virtual bool ReadPrimitiveData(DMat44 &outPrimitive) override;
|
||||
|
||||
private:
|
||||
bool ReadChar(char &outChar);
|
||||
bool ReadWord(String &outWord);
|
||||
};
|
||||
|
||||
JPH_NAMESPACE_END
|
||||
|
||||
#endif // JPH_OBJECT_STREAM
|
||||
@ -0,0 +1,255 @@
|
||||
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
|
||||
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#include <Jolt/Jolt.h>
|
||||
|
||||
#ifdef JPH_OBJECT_STREAM
|
||||
|
||||
#include <Jolt/ObjectStream/ObjectStreamTextOut.h>
|
||||
#include <Jolt/Core/StringTools.h>
|
||||
|
||||
JPH_NAMESPACE_BEGIN
|
||||
|
||||
ObjectStreamTextOut::ObjectStreamTextOut(ostream &inStream) :
|
||||
ObjectStreamOut(inStream)
|
||||
{
|
||||
WriteWord(StringFormat("TOS%2d.%02d", ObjectStream::sVersion, ObjectStream::sRevision));
|
||||
}
|
||||
|
||||
void ObjectStreamTextOut::WriteDataType(EOSDataType inType)
|
||||
{
|
||||
switch (inType)
|
||||
{
|
||||
case EOSDataType::Declare: WriteWord("declare "); break;
|
||||
case EOSDataType::Object: WriteWord("object "); break;
|
||||
case EOSDataType::Instance: WriteWord("instance "); break;
|
||||
case EOSDataType::Pointer: WriteWord("pointer "); break;
|
||||
case EOSDataType::Array: WriteWord("array "); break;
|
||||
case EOSDataType::T_uint8: WriteWord("uint8"); break;
|
||||
case EOSDataType::T_uint16: WriteWord("uint16"); break;
|
||||
case EOSDataType::T_int: WriteWord("int"); break;
|
||||
case EOSDataType::T_uint32: WriteWord("uint32"); break;
|
||||
case EOSDataType::T_uint64: WriteWord("uint64"); break;
|
||||
case EOSDataType::T_float: WriteWord("float"); break;
|
||||
case EOSDataType::T_double: WriteWord("double"); break;
|
||||
case EOSDataType::T_bool: WriteWord("bool"); break;
|
||||
case EOSDataType::T_String: WriteWord("string"); break;
|
||||
case EOSDataType::T_Float3: WriteWord("float3"); break;
|
||||
case EOSDataType::T_Float4: WriteWord("float4"); break;
|
||||
case EOSDataType::T_Double3: WriteWord("double3"); break;
|
||||
case EOSDataType::T_Vec3: WriteWord("vec3"); break;
|
||||
case EOSDataType::T_DVec3: WriteWord("dvec3"); break;
|
||||
case EOSDataType::T_Vec4: WriteWord("vec4"); break;
|
||||
case EOSDataType::T_UVec4: WriteWord("uvec4"); break;
|
||||
case EOSDataType::T_Quat: WriteWord("quat"); break;
|
||||
case EOSDataType::T_Mat44: WriteWord("mat44"); break;
|
||||
case EOSDataType::T_DMat44: WriteWord("dmat44"); break;
|
||||
case EOSDataType::Invalid:
|
||||
default: JPH_ASSERT(false); break;
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectStreamTextOut::WriteName(const char *inName)
|
||||
{
|
||||
WriteWord(String(inName) + " ");
|
||||
}
|
||||
|
||||
void ObjectStreamTextOut::WriteIdentifier(Identifier inIdentifier)
|
||||
{
|
||||
WriteWord(StringFormat("%08X", inIdentifier));
|
||||
}
|
||||
|
||||
void ObjectStreamTextOut::WriteCount(uint32 inCount)
|
||||
{
|
||||
WriteWord(std::to_string(inCount));
|
||||
}
|
||||
|
||||
void ObjectStreamTextOut::WritePrimitiveData(const uint8 &inPrimitive)
|
||||
{
|
||||
WriteWord(std::to_string(inPrimitive));
|
||||
}
|
||||
|
||||
void ObjectStreamTextOut::WritePrimitiveData(const uint16 &inPrimitive)
|
||||
{
|
||||
WriteWord(std::to_string(inPrimitive));
|
||||
}
|
||||
|
||||
void ObjectStreamTextOut::WritePrimitiveData(const int &inPrimitive)
|
||||
{
|
||||
WriteWord(std::to_string(inPrimitive));
|
||||
}
|
||||
|
||||
void ObjectStreamTextOut::WritePrimitiveData(const uint32 &inPrimitive)
|
||||
{
|
||||
WriteWord(std::to_string(inPrimitive));
|
||||
}
|
||||
|
||||
void ObjectStreamTextOut::WritePrimitiveData(const uint64 &inPrimitive)
|
||||
{
|
||||
WriteWord(std::to_string(inPrimitive));
|
||||
}
|
||||
|
||||
void ObjectStreamTextOut::WritePrimitiveData(const float &inPrimitive)
|
||||
{
|
||||
std::ostringstream stream;
|
||||
stream.precision(9);
|
||||
stream << inPrimitive;
|
||||
WriteWord(stream.str());
|
||||
}
|
||||
|
||||
void ObjectStreamTextOut::WritePrimitiveData(const double &inPrimitive)
|
||||
{
|
||||
std::ostringstream stream;
|
||||
stream.precision(17);
|
||||
stream << inPrimitive;
|
||||
WriteWord(stream.str());
|
||||
}
|
||||
|
||||
void ObjectStreamTextOut::WritePrimitiveData(const bool &inPrimitive)
|
||||
{
|
||||
WriteWord(inPrimitive? "true" : "false");
|
||||
}
|
||||
|
||||
void ObjectStreamTextOut::WritePrimitiveData(const Float3 &inPrimitive)
|
||||
{
|
||||
WritePrimitiveData(inPrimitive.x);
|
||||
WriteChar(' ');
|
||||
WritePrimitiveData(inPrimitive.y);
|
||||
WriteChar(' ');
|
||||
WritePrimitiveData(inPrimitive.z);
|
||||
}
|
||||
|
||||
void ObjectStreamTextOut::WritePrimitiveData(const Float4 &inPrimitive)
|
||||
{
|
||||
WritePrimitiveData(inPrimitive.x);
|
||||
WriteChar(' ');
|
||||
WritePrimitiveData(inPrimitive.y);
|
||||
WriteChar(' ');
|
||||
WritePrimitiveData(inPrimitive.z);
|
||||
WriteChar(' ');
|
||||
WritePrimitiveData(inPrimitive.w);
|
||||
}
|
||||
|
||||
void ObjectStreamTextOut::WritePrimitiveData(const Double3 &inPrimitive)
|
||||
{
|
||||
WritePrimitiveData(inPrimitive.x);
|
||||
WriteChar(' ');
|
||||
WritePrimitiveData(inPrimitive.y);
|
||||
WriteChar(' ');
|
||||
WritePrimitiveData(inPrimitive.z);
|
||||
}
|
||||
|
||||
void ObjectStreamTextOut::WritePrimitiveData(const Vec3 &inPrimitive)
|
||||
{
|
||||
WritePrimitiveData(inPrimitive.GetX());
|
||||
WriteChar(' ');
|
||||
WritePrimitiveData(inPrimitive.GetY());
|
||||
WriteChar(' ');
|
||||
WritePrimitiveData(inPrimitive.GetZ());
|
||||
}
|
||||
|
||||
void ObjectStreamTextOut::WritePrimitiveData(const DVec3 &inPrimitive)
|
||||
{
|
||||
WritePrimitiveData(inPrimitive.GetX());
|
||||
WriteChar(' ');
|
||||
WritePrimitiveData(inPrimitive.GetY());
|
||||
WriteChar(' ');
|
||||
WritePrimitiveData(inPrimitive.GetZ());
|
||||
}
|
||||
|
||||
void ObjectStreamTextOut::WritePrimitiveData(const Vec4 &inPrimitive)
|
||||
{
|
||||
WritePrimitiveData(inPrimitive.GetX());
|
||||
WriteChar(' ');
|
||||
WritePrimitiveData(inPrimitive.GetY());
|
||||
WriteChar(' ');
|
||||
WritePrimitiveData(inPrimitive.GetZ());
|
||||
WriteChar(' ');
|
||||
WritePrimitiveData(inPrimitive.GetW());
|
||||
}
|
||||
|
||||
void ObjectStreamTextOut::WritePrimitiveData(const UVec4 &inPrimitive)
|
||||
{
|
||||
WritePrimitiveData(inPrimitive.GetX());
|
||||
WriteChar(' ');
|
||||
WritePrimitiveData(inPrimitive.GetY());
|
||||
WriteChar(' ');
|
||||
WritePrimitiveData(inPrimitive.GetZ());
|
||||
WriteChar(' ');
|
||||
WritePrimitiveData(inPrimitive.GetW());
|
||||
}
|
||||
|
||||
void ObjectStreamTextOut::WritePrimitiveData(const Quat &inPrimitive)
|
||||
{
|
||||
WritePrimitiveData(inPrimitive.GetX());
|
||||
WriteChar(' ');
|
||||
WritePrimitiveData(inPrimitive.GetY());
|
||||
WriteChar(' ');
|
||||
WritePrimitiveData(inPrimitive.GetZ());
|
||||
WriteChar(' ');
|
||||
WritePrimitiveData(inPrimitive.GetW());
|
||||
}
|
||||
|
||||
void ObjectStreamTextOut::WritePrimitiveData(const Mat44 &inPrimitive)
|
||||
{
|
||||
WritePrimitiveData(inPrimitive.GetColumn4(0));
|
||||
WriteChar(' ');
|
||||
WritePrimitiveData(inPrimitive.GetColumn4(1));
|
||||
WriteChar(' ');
|
||||
WritePrimitiveData(inPrimitive.GetColumn4(2));
|
||||
WriteChar(' ');
|
||||
WritePrimitiveData(inPrimitive.GetColumn4(3));
|
||||
}
|
||||
|
||||
void ObjectStreamTextOut::WritePrimitiveData(const DMat44 &inPrimitive)
|
||||
{
|
||||
WritePrimitiveData(inPrimitive.GetColumn4(0));
|
||||
WriteChar(' ');
|
||||
WritePrimitiveData(inPrimitive.GetColumn4(1));
|
||||
WriteChar(' ');
|
||||
WritePrimitiveData(inPrimitive.GetColumn4(2));
|
||||
WriteChar(' ');
|
||||
WritePrimitiveData(inPrimitive.GetTranslation());
|
||||
}
|
||||
|
||||
void ObjectStreamTextOut::WritePrimitiveData(const String &inPrimitive)
|
||||
{
|
||||
String temporary(inPrimitive);
|
||||
StringReplace(temporary, "\\", "\\\\");
|
||||
StringReplace(temporary, "\n", "\\n");
|
||||
StringReplace(temporary, "\t", "\\t");
|
||||
StringReplace(temporary, "\"", "\\\"");
|
||||
WriteWord(String("\"") + temporary + String("\""));
|
||||
}
|
||||
|
||||
void ObjectStreamTextOut::HintNextItem()
|
||||
{
|
||||
WriteWord("\r\n");
|
||||
for (int i = 0; i < mIndentation; ++i)
|
||||
WriteWord(" ");
|
||||
}
|
||||
|
||||
void ObjectStreamTextOut::HintIndentUp()
|
||||
{
|
||||
++mIndentation;
|
||||
}
|
||||
|
||||
void ObjectStreamTextOut::HintIndentDown()
|
||||
{
|
||||
--mIndentation;
|
||||
}
|
||||
|
||||
void ObjectStreamTextOut::WriteChar(char inChar)
|
||||
{
|
||||
mStream.put(inChar);
|
||||
}
|
||||
|
||||
void ObjectStreamTextOut::WriteWord(const string_view &inWord)
|
||||
{
|
||||
mStream << inWord;
|
||||
}
|
||||
|
||||
JPH_NAMESPACE_END
|
||||
|
||||
#endif // JPH_OBJECT_STREAM
|
||||
@ -0,0 +1,62 @@
|
||||
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
|
||||
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Jolt/ObjectStream/ObjectStreamOut.h>
|
||||
|
||||
#ifdef JPH_OBJECT_STREAM
|
||||
|
||||
JPH_NAMESPACE_BEGIN
|
||||
|
||||
/// Implementation of ObjectStream text output stream.
|
||||
class JPH_EXPORT ObjectStreamTextOut : public ObjectStreamOut
|
||||
{
|
||||
public:
|
||||
JPH_OVERRIDE_NEW_DELETE
|
||||
|
||||
/// Constructor and destructor
|
||||
explicit ObjectStreamTextOut(ostream &inStream);
|
||||
|
||||
///@name Output type specific operations
|
||||
virtual void WriteDataType(EOSDataType inType) override;
|
||||
virtual void WriteName(const char *inName) override;
|
||||
virtual void WriteIdentifier(Identifier inIdentifier) override;
|
||||
virtual void WriteCount(uint32 inCount) override;
|
||||
|
||||
virtual void WritePrimitiveData(const uint8 &inPrimitive) override;
|
||||
virtual void WritePrimitiveData(const uint16 &inPrimitive) override;
|
||||
virtual void WritePrimitiveData(const int &inPrimitive) override;
|
||||
virtual void WritePrimitiveData(const uint32 &inPrimitive) override;
|
||||
virtual void WritePrimitiveData(const uint64 &inPrimitive) override;
|
||||
virtual void WritePrimitiveData(const float &inPrimitive) override;
|
||||
virtual void WritePrimitiveData(const double &inPrimitive) override;
|
||||
virtual void WritePrimitiveData(const bool &inPrimitive) override;
|
||||
virtual void WritePrimitiveData(const String &inPrimitive) override;
|
||||
virtual void WritePrimitiveData(const Float3 &inPrimitive) override;
|
||||
virtual void WritePrimitiveData(const Float4 &inPrimitive) override;
|
||||
virtual void WritePrimitiveData(const Double3 &inPrimitive) override;
|
||||
virtual void WritePrimitiveData(const Vec3 &inPrimitive) override;
|
||||
virtual void WritePrimitiveData(const DVec3 &inPrimitive) override;
|
||||
virtual void WritePrimitiveData(const Vec4 &inPrimitive) override;
|
||||
virtual void WritePrimitiveData(const UVec4 &inPrimitive) override;
|
||||
virtual void WritePrimitiveData(const Quat &inPrimitive) override;
|
||||
virtual void WritePrimitiveData(const Mat44 &inPrimitive) override;
|
||||
virtual void WritePrimitiveData(const DMat44 &inPrimitive) override;
|
||||
|
||||
///@name Layout hints (for text output)
|
||||
virtual void HintNextItem() override;
|
||||
virtual void HintIndentUp() override;
|
||||
virtual void HintIndentDown() override;
|
||||
|
||||
private:
|
||||
void WriteChar(char inChar);
|
||||
void WriteWord(const string_view &inWord);
|
||||
|
||||
int mIndentation = 0;
|
||||
};
|
||||
|
||||
JPH_NAMESPACE_END
|
||||
|
||||
#endif // JPH_OBJECT_STREAM
|
||||
@ -0,0 +1,26 @@
|
||||
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
|
||||
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
// Note: Order is important, an enum is created and its value is stored in a binary stream!
|
||||
JPH_DECLARE_PRIMITIVE(uint8)
|
||||
JPH_DECLARE_PRIMITIVE(uint16)
|
||||
JPH_DECLARE_PRIMITIVE(int)
|
||||
JPH_DECLARE_PRIMITIVE(uint32)
|
||||
JPH_DECLARE_PRIMITIVE(uint64)
|
||||
JPH_DECLARE_PRIMITIVE(float)
|
||||
JPH_DECLARE_PRIMITIVE(bool)
|
||||
JPH_DECLARE_PRIMITIVE(String)
|
||||
JPH_DECLARE_PRIMITIVE(Float3)
|
||||
JPH_DECLARE_PRIMITIVE(Vec3)
|
||||
JPH_DECLARE_PRIMITIVE(Vec4)
|
||||
JPH_DECLARE_PRIMITIVE(Quat)
|
||||
JPH_DECLARE_PRIMITIVE(Mat44)
|
||||
JPH_DECLARE_PRIMITIVE(double)
|
||||
JPH_DECLARE_PRIMITIVE(DVec3)
|
||||
JPH_DECLARE_PRIMITIVE(DMat44)
|
||||
JPH_DECLARE_PRIMITIVE(Double3)
|
||||
JPH_DECLARE_PRIMITIVE(Float4)
|
||||
JPH_DECLARE_PRIMITIVE(UVec4)
|
||||
|
||||
#undef JPH_DECLARE_PRIMITIVE
|
||||
@ -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
|
||||
@ -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) \
|
||||
JPH::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
|
||||
@ -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) \
|
||||
JPH::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
|
||||
@ -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
|
||||
170
lib/haxejolt/JoltPhysics/Jolt/ObjectStream/SerializableObject.h
Normal file
170
lib/haxejolt/JoltPhysics/Jolt/ObjectStream/SerializableObject.h
Normal file
@ -0,0 +1,170 @@
|
||||
// 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(JPH::IObjectStreamIn &ioStream, class_name &inInstance); \
|
||||
linkage prefix bool OSReadData(JPH::IObjectStreamIn &ioStream, class_name *&inPointer); \
|
||||
linkage prefix bool OSIsType(class_name *, int inArrayDepth, JPH::EOSDataType inDataType, const char *inClassName); \
|
||||
linkage prefix bool OSIsType(class_name **, int inArrayDepth, JPH::EOSDataType inDataType, const char *inClassName); \
|
||||
linkage prefix void OSWriteData(JPH::IObjectStreamOut &ioStream, const class_name &inInstance); \
|
||||
linkage prefix void OSWriteData(JPH::IObjectStreamOut &ioStream, class_name *const &inPointer); \
|
||||
linkage prefix void OSWriteDataType(JPH::IObjectStreamOut &ioStream, class_name *); \
|
||||
linkage prefix void OSWriteDataType(JPH::IObjectStreamOut &ioStream, class_name **);
|
||||
|
||||
// JPH_IMPLEMENT_SERIALIZATION_FUNCTIONS
|
||||
#define JPH_IMPLEMENT_SERIALIZATION_FUNCTIONS(class_name) \
|
||||
bool OSReadData(JPH::IObjectStreamIn &ioStream, class_name &inInstance) \
|
||||
{ \
|
||||
return ioStream.ReadClassData(#class_name, (void *)&inInstance); \
|
||||
} \
|
||||
bool OSReadData(JPH::IObjectStreamIn &ioStream, class_name *&inPointer) \
|
||||
{ \
|
||||
return ioStream.ReadPointerData(JPH_RTTI(class_name), (void **)&inPointer); \
|
||||
} \
|
||||
bool OSIsType(class_name *, int inArrayDepth, JPH::EOSDataType inDataType, const char *inClassName) \
|
||||
{ \
|
||||
return inArrayDepth == 0 && inDataType == JPH::EOSDataType::Instance && strcmp(inClassName, #class_name) == 0; \
|
||||
} \
|
||||
bool OSIsType(class_name **, int inArrayDepth, JPH::EOSDataType inDataType, const char *inClassName) \
|
||||
{ \
|
||||
return inArrayDepth == 0 && inDataType == JPH::EOSDataType::Pointer && strcmp(inClassName, #class_name) == 0; \
|
||||
} \
|
||||
void OSWriteData(JPH::IObjectStreamOut &ioStream, const class_name &inInstance) \
|
||||
{ \
|
||||
ioStream.WriteClassData(JPH_RTTI(class_name), (void *)&inInstance); \
|
||||
} \
|
||||
void OSWriteData(JPH::IObjectStreamOut &ioStream, class_name *const &inPointer) \
|
||||
{ \
|
||||
if (inPointer) \
|
||||
ioStream.WritePointerData(GetRTTI(inPointer), (void *)inPointer); \
|
||||
else \
|
||||
ioStream.WritePointerData(nullptr, nullptr); \
|
||||
} \
|
||||
void OSWriteDataType(JPH::IObjectStreamOut &ioStream, class_name *) \
|
||||
{ \
|
||||
ioStream.WriteDataType(JPH::EOSDataType::Instance); \
|
||||
ioStream.WriteName(#class_name); \
|
||||
} \
|
||||
void OSWriteDataType(JPH::IObjectStreamOut &ioStream, class_name **) \
|
||||
{ \
|
||||
ioStream.WriteDataType(JPH::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
|
||||
{
|
||||
JPH_DECLARE_SERIALIZABLE_ABSTRACT_BASE(JPH_EXPORT, SerializableObject)
|
||||
|
||||
public:
|
||||
/// Destructor
|
||||
virtual ~SerializableObject() = default;
|
||||
|
||||
protected:
|
||||
/// Don't allow (copy) constructing this base class, but allow derived classes to (copy) construct themselves
|
||||
SerializableObject() = default;
|
||||
SerializableObject(const SerializableObject &) = default;
|
||||
SerializableObject & operator = (const SerializableObject &) = default;
|
||||
};
|
||||
|
||||
JPH_NAMESPACE_END
|
||||
@ -0,0 +1,70 @@
|
||||
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
|
||||
// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#include <Jolt/Jolt.h>
|
||||
|
||||
#include <Jolt/ObjectStream/TypeDeclarations.h>
|
||||
|
||||
JPH_NAMESPACE_BEGIN
|
||||
|
||||
JPH_IMPLEMENT_RTTI_OUTSIDE_CLASS(uint8) { }
|
||||
JPH_IMPLEMENT_RTTI_OUTSIDE_CLASS(uint16) { }
|
||||
JPH_IMPLEMENT_RTTI_OUTSIDE_CLASS(int) { }
|
||||
JPH_IMPLEMENT_RTTI_OUTSIDE_CLASS(uint32) { }
|
||||
JPH_IMPLEMENT_RTTI_OUTSIDE_CLASS(uint64) { }
|
||||
JPH_IMPLEMENT_RTTI_OUTSIDE_CLASS(float) { }
|
||||
JPH_IMPLEMENT_RTTI_OUTSIDE_CLASS(double) { }
|
||||
JPH_IMPLEMENT_RTTI_OUTSIDE_CLASS(bool) { }
|
||||
JPH_IMPLEMENT_RTTI_OUTSIDE_CLASS(String) { }
|
||||
JPH_IMPLEMENT_RTTI_OUTSIDE_CLASS(Float3) { }
|
||||
JPH_IMPLEMENT_RTTI_OUTSIDE_CLASS(Float4) { }
|
||||
JPH_IMPLEMENT_RTTI_OUTSIDE_CLASS(Double3) { }
|
||||
JPH_IMPLEMENT_RTTI_OUTSIDE_CLASS(Vec3) { }
|
||||
JPH_IMPLEMENT_RTTI_OUTSIDE_CLASS(DVec3) { }
|
||||
JPH_IMPLEMENT_RTTI_OUTSIDE_CLASS(Vec4) { }
|
||||
JPH_IMPLEMENT_RTTI_OUTSIDE_CLASS(UVec4) { }
|
||||
JPH_IMPLEMENT_RTTI_OUTSIDE_CLASS(Quat) { }
|
||||
JPH_IMPLEMENT_RTTI_OUTSIDE_CLASS(Mat44) { }
|
||||
JPH_IMPLEMENT_RTTI_OUTSIDE_CLASS(DMat44) { }
|
||||
|
||||
JPH_IMPLEMENT_SERIALIZABLE_OUTSIDE_CLASS(Color)
|
||||
{
|
||||
JPH_ADD_ATTRIBUTE(Color, r)
|
||||
JPH_ADD_ATTRIBUTE(Color, g)
|
||||
JPH_ADD_ATTRIBUTE(Color, b)
|
||||
JPH_ADD_ATTRIBUTE(Color, a)
|
||||
}
|
||||
|
||||
JPH_IMPLEMENT_SERIALIZABLE_OUTSIDE_CLASS(AABox)
|
||||
{
|
||||
JPH_ADD_ATTRIBUTE(AABox, mMin)
|
||||
JPH_ADD_ATTRIBUTE(AABox, mMax)
|
||||
}
|
||||
|
||||
JPH_IMPLEMENT_SERIALIZABLE_OUTSIDE_CLASS(Triangle)
|
||||
{
|
||||
JPH_ADD_ATTRIBUTE(Triangle, mV)
|
||||
JPH_ADD_ATTRIBUTE(Triangle, mMaterialIndex)
|
||||
JPH_ADD_ATTRIBUTE(Triangle, mUserData)
|
||||
}
|
||||
|
||||
JPH_IMPLEMENT_SERIALIZABLE_OUTSIDE_CLASS(IndexedTriangleNoMaterial)
|
||||
{
|
||||
JPH_ADD_ATTRIBUTE(IndexedTriangleNoMaterial, mIdx)
|
||||
}
|
||||
|
||||
JPH_IMPLEMENT_SERIALIZABLE_OUTSIDE_CLASS(IndexedTriangle)
|
||||
{
|
||||
JPH_ADD_BASE_CLASS(IndexedTriangle, IndexedTriangleNoMaterial)
|
||||
|
||||
JPH_ADD_ATTRIBUTE(IndexedTriangle, mMaterialIndex)
|
||||
JPH_ADD_ATTRIBUTE(IndexedTriangle, mUserData)
|
||||
}
|
||||
|
||||
JPH_IMPLEMENT_SERIALIZABLE_OUTSIDE_CLASS(Plane)
|
||||
{
|
||||
JPH_ADD_ATTRIBUTE(Plane, mNormalAndConstant)
|
||||
}
|
||||
|
||||
JPH_NAMESPACE_END
|
||||
@ -0,0 +1,45 @@
|
||||
// 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, Float4);
|
||||
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, UVec4);
|
||||
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, IndexedTriangleNoMaterial);
|
||||
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>
|
||||
Reference in New Issue
Block a user