Path: blob/master/thirdparty/jolt_physics/Jolt/ObjectStream/ObjectStream.h
21075 views
// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)1// SPDX-FileCopyrightText: 2021 Jorrit Rouwe2// SPDX-License-Identifier: MIT34#pragma once56#include <Jolt/Core/StaticArray.h>7#include <Jolt/Core/Reference.h>8#include <Jolt/Core/RTTI.h>9#include <Jolt/Core/NonCopyable.h>10#include <Jolt/ObjectStream/SerializableAttribute.h>1112#ifdef JPH_OBJECT_STREAM1314JPH_NAMESPACE_BEGIN1516/// Base class for object stream input and output streams.17class JPH_EXPORT ObjectStream : public NonCopyable18{19public:20/// Stream type21enum class EStreamType22{23Text,24Binary,25};2627protected:28/// Destructor29virtual ~ObjectStream() = default;3031/// Identifier for objects32using Identifier = uint32;3334static constexpr int sVersion = 1;35static constexpr int sRevision = 0;36static constexpr Identifier sNullIdentifier = 0;37};3839/// Interface class for reading from an object stream40class JPH_EXPORT IObjectStreamIn : public ObjectStream41{42public:43///@name Input type specific operations44virtual bool ReadDataType(EOSDataType &outType) = 0;45virtual bool ReadName(String &outName) = 0;46virtual bool ReadIdentifier(Identifier &outIdentifier) = 0;47virtual bool ReadCount(uint32 &outCount) = 0;4849///@name Read primitives50virtual bool ReadPrimitiveData(uint8 &outPrimitive) = 0;51virtual bool ReadPrimitiveData(uint16 &outPrimitive) = 0;52virtual bool ReadPrimitiveData(int &outPrimitive) = 0;53virtual bool ReadPrimitiveData(uint32 &outPrimitive) = 0;54virtual bool ReadPrimitiveData(uint64 &outPrimitive) = 0;55virtual bool ReadPrimitiveData(float &outPrimitive) = 0;56virtual bool ReadPrimitiveData(double &outPrimitive) = 0;57virtual bool ReadPrimitiveData(bool &outPrimitive) = 0;58virtual bool ReadPrimitiveData(String &outPrimitive) = 0;59virtual bool ReadPrimitiveData(Float3 &outPrimitive) = 0;60virtual bool ReadPrimitiveData(Float4 &outPrimitive) = 0;61virtual bool ReadPrimitiveData(Double3 &outPrimitive) = 0;62virtual bool ReadPrimitiveData(Vec3 &outPrimitive) = 0;63virtual bool ReadPrimitiveData(DVec3 &outPrimitive) = 0;64virtual bool ReadPrimitiveData(Vec4 &outPrimitive) = 0;65virtual bool ReadPrimitiveData(UVec4 &outPrimitive) = 0;66virtual bool ReadPrimitiveData(Quat &outPrimitive) = 0;67virtual bool ReadPrimitiveData(Mat44 &outPrimitive) = 0;68virtual bool ReadPrimitiveData(DMat44 &outPrimitive) = 0;6970///@name Read compounds71virtual bool ReadClassData(const char *inClassName, void *inInstance) = 0;72virtual bool ReadPointerData(const RTTI *inRTTI, void **inPointer, int inRefCountOffset = -1) = 0;73};7475/// Interface class for writing to an object stream76class JPH_EXPORT IObjectStreamOut : public ObjectStream77{78public:79///@name Output type specific operations80virtual void WriteDataType(EOSDataType inType) = 0;81virtual void WriteName(const char *inName) = 0;82virtual void WriteIdentifier(Identifier inIdentifier) = 0;83virtual void WriteCount(uint32 inCount) = 0;8485///@name Write primitives86virtual void WritePrimitiveData(const uint8 &inPrimitive) = 0;87virtual void WritePrimitiveData(const uint16 &inPrimitive) = 0;88virtual void WritePrimitiveData(const int &inPrimitive) = 0;89virtual void WritePrimitiveData(const uint32 &inPrimitive) = 0;90virtual void WritePrimitiveData(const uint64 &inPrimitive) = 0;91virtual void WritePrimitiveData(const float &inPrimitive) = 0;92virtual void WritePrimitiveData(const double &inPrimitive) = 0;93virtual void WritePrimitiveData(const bool &inPrimitive) = 0;94virtual void WritePrimitiveData(const String &inPrimitive) = 0;95virtual void WritePrimitiveData(const Float3 &inPrimitive) = 0;96virtual void WritePrimitiveData(const Float4 &inPrimitive) = 0;97virtual void WritePrimitiveData(const Double3 &inPrimitive) = 0;98virtual void WritePrimitiveData(const Vec3 &inPrimitive) = 0;99virtual void WritePrimitiveData(const DVec3 &inPrimitive) = 0;100virtual void WritePrimitiveData(const Vec4 &inPrimitive) = 0;101virtual void WritePrimitiveData(const UVec4 &inPrimitive) = 0;102virtual void WritePrimitiveData(const Quat &inPrimitive) = 0;103virtual void WritePrimitiveData(const Mat44 &inPrimitive) = 0;104virtual void WritePrimitiveData(const DMat44 &inPrimitive) = 0;105106///@name Write compounds107virtual void WritePointerData(const RTTI *inRTTI, const void *inPointer) = 0;108virtual void WriteClassData(const RTTI *inRTTI, const void *inInstance) = 0;109110///@name Layout hints (for text output)111virtual void HintNextItem() { /* Default is do nothing */ }112virtual void HintIndentUp() { /* Default is do nothing */ }113virtual void HintIndentDown() { /* Default is do nothing */ }114};115116// Define macro to declare functions for a specific primitive type117#define JPH_DECLARE_PRIMITIVE(name) \118JPH_EXPORT bool OSIsType(name *, int inArrayDepth, EOSDataType inDataType, const char *inClassName); \119JPH_EXPORT bool OSReadData(IObjectStreamIn &ioStream, name &outPrimitive); \120JPH_EXPORT void OSWriteDataType(IObjectStreamOut &ioStream, name *); \121JPH_EXPORT void OSWriteData(IObjectStreamOut &ioStream, const name &inPrimitive);122123// This file uses the JPH_DECLARE_PRIMITIVE macro to define all types124#include <Jolt/ObjectStream/ObjectStreamTypes.h>125126// Define serialization templates127template <class T, class A>128bool OSIsType(Array<T, A> *, int inArrayDepth, EOSDataType inDataType, const char *inClassName)129{130return (inArrayDepth > 0 && OSIsType(static_cast<T *>(nullptr), inArrayDepth - 1, inDataType, inClassName));131}132133template <class T, uint N>134bool OSIsType(StaticArray<T, N> *, int inArrayDepth, EOSDataType inDataType, const char *inClassName)135{136return (inArrayDepth > 0 && OSIsType(static_cast<T *>(nullptr), inArrayDepth - 1, inDataType, inClassName));137}138139template <class T, uint N>140bool OSIsType(T (*)[N], int inArrayDepth, EOSDataType inDataType, const char *inClassName)141{142return (inArrayDepth > 0 && OSIsType(static_cast<T *>(nullptr), inArrayDepth - 1, inDataType, inClassName));143}144145template <class T>146bool OSIsType(Ref<T> *, int inArrayDepth, EOSDataType inDataType, const char *inClassName)147{148return OSIsType(static_cast<T *>(nullptr), inArrayDepth, inDataType, inClassName);149}150151template <class T>152bool OSIsType(RefConst<T> *, int inArrayDepth, EOSDataType inDataType, const char *inClassName)153{154return OSIsType(static_cast<T *>(nullptr), inArrayDepth, inDataType, inClassName);155}156157/// Define serialization templates for dynamic arrays158template <class T, class A>159bool OSReadData(IObjectStreamIn &ioStream, Array<T, A> &inArray)160{161bool continue_reading = true;162163// Read array length164uint32 array_length;165continue_reading = ioStream.ReadCount(array_length);166167// Read array items168if (continue_reading)169{170inArray.clear();171inArray.resize(array_length);172for (uint32 el = 0; el < array_length && continue_reading; ++el)173continue_reading = OSReadData(ioStream, inArray[el]);174}175176return continue_reading;177}178179/// Define serialization templates for static arrays180template <class T, uint N>181bool OSReadData(IObjectStreamIn &ioStream, StaticArray<T, N> &inArray)182{183bool continue_reading = true;184185// Read array length186uint32 array_length;187continue_reading = ioStream.ReadCount(array_length);188189// Check if we can fit this many elements190if (array_length > N)191return false;192193// Read array items194if (continue_reading)195{196inArray.clear();197inArray.resize(array_length);198for (uint32 el = 0; el < array_length && continue_reading; ++el)199continue_reading = OSReadData(ioStream, inArray[el]);200}201202return continue_reading;203}204205/// Define serialization templates for C style arrays206template <class T, uint N>207bool OSReadData(IObjectStreamIn &ioStream, T (&inArray)[N])208{209bool continue_reading = true;210211// Read array length212uint32 array_length;213continue_reading = ioStream.ReadCount(array_length);214if (array_length != N)215return false;216217// Read array items218for (uint32 el = 0; el < N && continue_reading; ++el)219continue_reading = OSReadData(ioStream, inArray[el]);220221return continue_reading;222}223224/// Define serialization templates for references225template <class T>226bool OSReadData(IObjectStreamIn &ioStream, Ref<T> &inRef)227{228return ioStream.ReadPointerData(JPH_RTTI(T), inRef.InternalGetPointer(), T::sInternalGetRefCountOffset());229}230231template <class T>232bool OSReadData(IObjectStreamIn &ioStream, RefConst<T> &inRef)233{234return ioStream.ReadPointerData(JPH_RTTI(T), inRef.InternalGetPointer(), T::sInternalGetRefCountOffset());235}236237// Define serialization templates for dynamic arrays238template <class T, class A>239void OSWriteDataType(IObjectStreamOut &ioStream, Array<T, A> *)240{241ioStream.WriteDataType(EOSDataType::Array);242OSWriteDataType(ioStream, static_cast<T *>(nullptr));243}244245template <class T, class A>246void OSWriteData(IObjectStreamOut &ioStream, const Array<T, A> &inArray)247{248// Write size of array249ioStream.HintNextItem();250ioStream.WriteCount(static_cast<uint32>(inArray.size()));251252// Write data in array253ioStream.HintIndentUp();254for (const T &v : inArray)255OSWriteData(ioStream, v);256ioStream.HintIndentDown();257}258259/// Define serialization templates for static arrays260template <class T, uint N>261void OSWriteDataType(IObjectStreamOut &ioStream, StaticArray<T, N> *)262{263ioStream.WriteDataType(EOSDataType::Array);264OSWriteDataType(ioStream, static_cast<T *>(nullptr));265}266267template <class T, uint N>268void OSWriteData(IObjectStreamOut &ioStream, const StaticArray<T, N> &inArray)269{270// Write size of array271ioStream.HintNextItem();272ioStream.WriteCount(inArray.size());273274// Write data in array275ioStream.HintIndentUp();276for (const typename StaticArray<T, N>::value_type &v : inArray)277OSWriteData(ioStream, v);278ioStream.HintIndentDown();279}280281/// Define serialization templates for C style arrays282template <class T, uint N>283void OSWriteDataType(IObjectStreamOut &ioStream, T (*)[N])284{285ioStream.WriteDataType(EOSDataType::Array);286OSWriteDataType(ioStream, static_cast<T *>(nullptr));287}288289template <class T, uint N>290void OSWriteData(IObjectStreamOut &ioStream, const T (&inArray)[N])291{292// Write size of array293ioStream.HintNextItem();294ioStream.WriteCount(uint32(N));295296// Write data in array297ioStream.HintIndentUp();298for (const T &v : inArray)299OSWriteData(ioStream, v);300ioStream.HintIndentDown();301}302303/// Define serialization templates for references304template <class T>305void OSWriteDataType(IObjectStreamOut &ioStream, Ref<T> *)306{307OSWriteDataType(ioStream, static_cast<T *>(nullptr));308}309310template <class T>311void OSWriteData(IObjectStreamOut &ioStream, const Ref<T> &inRef)312{313if (inRef != nullptr)314ioStream.WritePointerData(GetRTTI(inRef.GetPtr()), inRef.GetPtr());315else316ioStream.WritePointerData(nullptr, nullptr);317}318319template <class T>320void OSWriteDataType(IObjectStreamOut &ioStream, RefConst<T> *)321{322OSWriteDataType(ioStream, static_cast<T *>(nullptr));323}324325template <class T>326void OSWriteData(IObjectStreamOut &ioStream, const RefConst<T> &inRef)327{328if (inRef != nullptr)329ioStream.WritePointerData(GetRTTI(inRef.GetPtr()), inRef.GetPtr());330else331ioStream.WritePointerData(nullptr, nullptr);332}333334JPH_NAMESPACE_END335336#endif // JPH_OBJECT_STREAM337338339