Files
LNXSDK/lib/haxejolt/JoltPhysics/Jolt/ObjectStream/ObjectStreamIn.h
2026-03-04 00:50:15 -08:00

149 lines
4.2 KiB
C++

// 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