Path: blob/master/thirdparty/jolt_physics/Jolt/ObjectStream/ObjectStream.h
9906 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(Double3 &outPrimitive) = 0;61virtual bool ReadPrimitiveData(Vec3 &outPrimitive) = 0;62virtual bool ReadPrimitiveData(DVec3 &outPrimitive) = 0;63virtual bool ReadPrimitiveData(Vec4 &outPrimitive) = 0;64virtual bool ReadPrimitiveData(Quat &outPrimitive) = 0;65virtual bool ReadPrimitiveData(Mat44 &outPrimitive) = 0;66virtual bool ReadPrimitiveData(DMat44 &outPrimitive) = 0;6768///@name Read compounds69virtual bool ReadClassData(const char *inClassName, void *inInstance) = 0;70virtual bool ReadPointerData(const RTTI *inRTTI, void **inPointer, int inRefCountOffset = -1) = 0;71};7273/// Interface class for writing to an object stream74class JPH_EXPORT IObjectStreamOut : public ObjectStream75{76public:77///@name Output type specific operations78virtual void WriteDataType(EOSDataType inType) = 0;79virtual void WriteName(const char *inName) = 0;80virtual void WriteIdentifier(Identifier inIdentifier) = 0;81virtual void WriteCount(uint32 inCount) = 0;8283///@name Write primitives84virtual void WritePrimitiveData(const uint8 &inPrimitive) = 0;85virtual void WritePrimitiveData(const uint16 &inPrimitive) = 0;86virtual void WritePrimitiveData(const int &inPrimitive) = 0;87virtual void WritePrimitiveData(const uint32 &inPrimitive) = 0;88virtual void WritePrimitiveData(const uint64 &inPrimitive) = 0;89virtual void WritePrimitiveData(const float &inPrimitive) = 0;90virtual void WritePrimitiveData(const double &inPrimitive) = 0;91virtual void WritePrimitiveData(const bool &inPrimitive) = 0;92virtual void WritePrimitiveData(const String &inPrimitive) = 0;93virtual void WritePrimitiveData(const Float3 &inPrimitive) = 0;94virtual void WritePrimitiveData(const Double3 &inPrimitive) = 0;95virtual void WritePrimitiveData(const Vec3 &inPrimitive) = 0;96virtual void WritePrimitiveData(const DVec3 &inPrimitive) = 0;97virtual void WritePrimitiveData(const Vec4 &inPrimitive) = 0;98virtual void WritePrimitiveData(const Quat &inPrimitive) = 0;99virtual void WritePrimitiveData(const Mat44 &inPrimitive) = 0;100virtual void WritePrimitiveData(const DMat44 &inPrimitive) = 0;101102///@name Write compounds103virtual void WritePointerData(const RTTI *inRTTI, const void *inPointer) = 0;104virtual void WriteClassData(const RTTI *inRTTI, const void *inInstance) = 0;105106///@name Layout hints (for text output)107virtual void HintNextItem() { /* Default is do nothing */ }108virtual void HintIndentUp() { /* Default is do nothing */ }109virtual void HintIndentDown() { /* Default is do nothing */ }110};111112// Define macro to declare functions for a specific primitive type113#define JPH_DECLARE_PRIMITIVE(name) \114JPH_EXPORT bool OSIsType(name *, int inArrayDepth, EOSDataType inDataType, const char *inClassName); \115JPH_EXPORT bool OSReadData(IObjectStreamIn &ioStream, name &outPrimitive); \116JPH_EXPORT void OSWriteDataType(IObjectStreamOut &ioStream, name *); \117JPH_EXPORT void OSWriteData(IObjectStreamOut &ioStream, const name &inPrimitive);118119// This file uses the JPH_DECLARE_PRIMITIVE macro to define all types120#include <Jolt/ObjectStream/ObjectStreamTypes.h>121122// Define serialization templates123template <class T, class A>124bool OSIsType(Array<T, A> *, int inArrayDepth, EOSDataType inDataType, const char *inClassName)125{126return (inArrayDepth > 0 && OSIsType(static_cast<T *>(nullptr), inArrayDepth - 1, inDataType, inClassName));127}128129template <class T, uint N>130bool OSIsType(StaticArray<T, N> *, int inArrayDepth, EOSDataType inDataType, const char *inClassName)131{132return (inArrayDepth > 0 && OSIsType(static_cast<T *>(nullptr), inArrayDepth - 1, inDataType, inClassName));133}134135template <class T, uint N>136bool OSIsType(T (*)[N], int inArrayDepth, EOSDataType inDataType, const char *inClassName)137{138return (inArrayDepth > 0 && OSIsType(static_cast<T *>(nullptr), inArrayDepth - 1, inDataType, inClassName));139}140141template <class T>142bool OSIsType(Ref<T> *, int inArrayDepth, EOSDataType inDataType, const char *inClassName)143{144return OSIsType(static_cast<T *>(nullptr), inArrayDepth, inDataType, inClassName);145}146147template <class T>148bool OSIsType(RefConst<T> *, int inArrayDepth, EOSDataType inDataType, const char *inClassName)149{150return OSIsType(static_cast<T *>(nullptr), inArrayDepth, inDataType, inClassName);151}152153/// Define serialization templates for dynamic arrays154template <class T, class A>155bool OSReadData(IObjectStreamIn &ioStream, Array<T, A> &inArray)156{157bool continue_reading = true;158159// Read array length160uint32 array_length;161continue_reading = ioStream.ReadCount(array_length);162163// Read array items164if (continue_reading)165{166inArray.clear();167inArray.resize(array_length);168for (uint32 el = 0; el < array_length && continue_reading; ++el)169continue_reading = OSReadData(ioStream, inArray[el]);170}171172return continue_reading;173}174175/// Define serialization templates for static arrays176template <class T, uint N>177bool OSReadData(IObjectStreamIn &ioStream, StaticArray<T, N> &inArray)178{179bool continue_reading = true;180181// Read array length182uint32 array_length;183continue_reading = ioStream.ReadCount(array_length);184185// Check if we can fit this many elements186if (array_length > N)187return false;188189// Read array items190if (continue_reading)191{192inArray.clear();193inArray.resize(array_length);194for (uint32 el = 0; el < array_length && continue_reading; ++el)195continue_reading = OSReadData(ioStream, inArray[el]);196}197198return continue_reading;199}200201/// Define serialization templates for C style arrays202template <class T, uint N>203bool OSReadData(IObjectStreamIn &ioStream, T (&inArray)[N])204{205bool continue_reading = true;206207// Read array length208uint32 array_length;209continue_reading = ioStream.ReadCount(array_length);210if (array_length != N)211return false;212213// Read array items214for (uint32 el = 0; el < N && continue_reading; ++el)215continue_reading = OSReadData(ioStream, inArray[el]);216217return continue_reading;218}219220/// Define serialization templates for references221template <class T>222bool OSReadData(IObjectStreamIn &ioStream, Ref<T> &inRef)223{224return ioStream.ReadPointerData(JPH_RTTI(T), inRef.InternalGetPointer(), T::sInternalGetRefCountOffset());225}226227template <class T>228bool OSReadData(IObjectStreamIn &ioStream, RefConst<T> &inRef)229{230return ioStream.ReadPointerData(JPH_RTTI(T), inRef.InternalGetPointer(), T::sInternalGetRefCountOffset());231}232233// Define serialization templates for dynamic arrays234template <class T, class A>235void OSWriteDataType(IObjectStreamOut &ioStream, Array<T, A> *)236{237ioStream.WriteDataType(EOSDataType::Array);238OSWriteDataType(ioStream, static_cast<T *>(nullptr));239}240241template <class T, class A>242void OSWriteData(IObjectStreamOut &ioStream, const Array<T, A> &inArray)243{244// Write size of array245ioStream.HintNextItem();246ioStream.WriteCount(static_cast<uint32>(inArray.size()));247248// Write data in array249ioStream.HintIndentUp();250for (const T &v : inArray)251OSWriteData(ioStream, v);252ioStream.HintIndentDown();253}254255/// Define serialization templates for static arrays256template <class T, uint N>257void OSWriteDataType(IObjectStreamOut &ioStream, StaticArray<T, N> *)258{259ioStream.WriteDataType(EOSDataType::Array);260OSWriteDataType(ioStream, static_cast<T *>(nullptr));261}262263template <class T, uint N>264void OSWriteData(IObjectStreamOut &ioStream, const StaticArray<T, N> &inArray)265{266// Write size of array267ioStream.HintNextItem();268ioStream.WriteCount(inArray.size());269270// Write data in array271ioStream.HintIndentUp();272for (const typename StaticArray<T, N>::value_type &v : inArray)273OSWriteData(ioStream, v);274ioStream.HintIndentDown();275}276277/// Define serialization templates for C style arrays278template <class T, uint N>279void OSWriteDataType(IObjectStreamOut &ioStream, T (*)[N])280{281ioStream.WriteDataType(EOSDataType::Array);282OSWriteDataType(ioStream, static_cast<T *>(nullptr));283}284285template <class T, uint N>286void OSWriteData(IObjectStreamOut &ioStream, const T (&inArray)[N])287{288// Write size of array289ioStream.HintNextItem();290ioStream.WriteCount(uint32(N));291292// Write data in array293ioStream.HintIndentUp();294for (const T &v : inArray)295OSWriteData(ioStream, v);296ioStream.HintIndentDown();297}298299/// Define serialization templates for references300template <class T>301void OSWriteDataType(IObjectStreamOut &ioStream, Ref<T> *)302{303OSWriteDataType(ioStream, static_cast<T *>(nullptr));304}305306template <class T>307void OSWriteData(IObjectStreamOut &ioStream, const Ref<T> &inRef)308{309if (inRef != nullptr)310ioStream.WritePointerData(GetRTTI(inRef.GetPtr()), inRef.GetPtr());311else312ioStream.WritePointerData(nullptr, nullptr);313}314315template <class T>316void OSWriteDataType(IObjectStreamOut &ioStream, RefConst<T> *)317{318OSWriteDataType(ioStream, static_cast<T *>(nullptr));319}320321template <class T>322void OSWriteData(IObjectStreamOut &ioStream, const RefConst<T> &inRef)323{324if (inRef != nullptr)325ioStream.WritePointerData(GetRTTI(inRef.GetPtr()), inRef.GetPtr());326else327ioStream.WritePointerData(nullptr, nullptr);328}329330JPH_NAMESPACE_END331332#endif // JPH_OBJECT_STREAM333334335