2
0

ObjectStreamIn.h 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. // Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
  2. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  3. // SPDX-License-Identifier: MIT
  4. #pragma once
  5. #include <Jolt/ObjectStream/ObjectStream.h>
  6. #include <Jolt/Core/Reference.h>
  7. #include <Jolt/Core/RTTI.h>
  8. #include <Jolt/Core/UnorderedMap.h>
  9. JPH_SUPPRESS_WARNINGS_STD_BEGIN
  10. #include <fstream>
  11. JPH_SUPPRESS_WARNINGS_STD_END
  12. JPH_NAMESPACE_BEGIN
  13. /// ObjectStreamIn contains all logic for reading an object from disk. It is the base
  14. /// class for the text and binary input streams (ObjectStreamTextIn and ObjectStreamBinaryIn).
  15. class JPH_EXPORT ObjectStreamIn : public IObjectStreamIn
  16. {
  17. private:
  18. struct ClassDescription;
  19. public:
  20. /// Main function to read an object from a stream
  21. template <class T>
  22. static bool sReadObject(istream &inStream, T *&outObject)
  23. {
  24. // Create the input stream
  25. bool result = false;
  26. ObjectStreamIn *stream = ObjectStreamIn::Open(inStream);
  27. if (stream)
  28. {
  29. // Read the object
  30. outObject = (T *)stream->Read(JPH_RTTI(T));
  31. result = (outObject != nullptr);
  32. delete stream;
  33. }
  34. return result;
  35. }
  36. /// Main function to read an object from a stream (reference counting pointer version)
  37. template <class T>
  38. static bool sReadObject(istream &inStream, Ref<T> &outObject)
  39. {
  40. T *object = nullptr;
  41. bool result = sReadObject(inStream, object);
  42. outObject = object;
  43. return result;
  44. }
  45. /// Main function to read an object from a file
  46. template <class T>
  47. static bool sReadObject(const char *inFileName, T *&outObject)
  48. {
  49. std::ifstream stream;
  50. stream.open(inFileName, std::ifstream::in | std::ifstream::binary);
  51. if (!stream.is_open())
  52. return false;
  53. return sReadObject(stream, outObject);
  54. }
  55. /// Main function to read an object from a file (reference counting pointer version)
  56. template <class T>
  57. static bool sReadObject(const char *inFileName, Ref<T> &outObject)
  58. {
  59. T *object = nullptr;
  60. bool result = sReadObject(inFileName, object);
  61. outObject = object;
  62. return result;
  63. }
  64. //////////////////////////////////////////////////////
  65. // EVERYTHING BELOW THIS SHOULD NOT DIRECTLY BE CALLED
  66. //////////////////////////////////////////////////////
  67. ///@name Serialization operations
  68. void * Read(const RTTI *inRTTI);
  69. void * ReadObject(const RTTI *& outRTTI);
  70. bool ReadRTTI();
  71. virtual bool ReadClassData(const char *inClassName, void *inInstance) override;
  72. bool ReadClassData(const ClassDescription &inClassDesc, void *inInstance);
  73. virtual bool ReadPointerData(const RTTI *inRTTI, void **inPointer, int inRefCountOffset = -1) override;
  74. bool SkipAttributeData(int inArrayDepth, EOSDataType inDataType, const char *inClassName);
  75. protected:
  76. /// Constructor
  77. explicit ObjectStreamIn(istream &inStream);
  78. /// Determine the type and version of an object stream
  79. static bool GetInfo(istream &inStream, EStreamType &outType, int &outVersion, int &outRevision);
  80. /// Static constructor
  81. static ObjectStreamIn * Open(istream &inStream);
  82. istream & mStream;
  83. private:
  84. /// Class descriptions
  85. struct AttributeDescription
  86. {
  87. int mArrayDepth = 0;
  88. EOSDataType mSourceType = EOSDataType::Invalid;
  89. EOSDataType mDestinationType = EOSDataType::Invalid;
  90. String mClassName;
  91. int mIndex = -1;
  92. };
  93. struct ClassDescription
  94. {
  95. ClassDescription() = default;
  96. explicit ClassDescription(const RTTI *inRTTI) : mRTTI(inRTTI) { }
  97. const RTTI * mRTTI = nullptr;
  98. Array<AttributeDescription> mAttributes;
  99. };
  100. struct ObjectInfo
  101. {
  102. ObjectInfo() = default;
  103. ObjectInfo(void *inInstance, const RTTI *inRTTI) : mInstance(inInstance), mRTTI(inRTTI) { }
  104. void * mInstance = nullptr;
  105. const RTTI * mRTTI = nullptr;
  106. };
  107. struct Link
  108. {
  109. void ** mPointer;
  110. int mRefCountOffset;
  111. Identifier mIdentifier;
  112. const RTTI * mRTTI;
  113. };
  114. using IdentifierMap = UnorderedMap<Identifier, ObjectInfo>;
  115. using ClassDescriptionMap = UnorderedMap<String, ClassDescription>;
  116. ClassDescriptionMap mClassDescriptionMap;
  117. IdentifierMap mIdentifierMap; ///< Links identifier to an object pointer
  118. Array<Link> mUnresolvedLinks; ///< All pointers (links) are resolved after reading the entire file, e.g. when all object exist
  119. };
  120. JPH_NAMESPACE_END