ObjectStreamOut.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  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/RTTI.h>
  7. #include <Jolt/Core/UnorderedMap.h>
  8. #include <Jolt/Core/UnorderedSet.h>
  9. JPH_SUPPRESS_WARNINGS_STD_BEGIN
  10. #include <queue>
  11. #include <fstream>
  12. JPH_SUPPRESS_WARNINGS_STD_END
  13. #ifdef JPH_OBJECT_STREAM
  14. JPH_NAMESPACE_BEGIN
  15. template <class T> using Queue = std::queue<T, std::deque<T, STLAllocator<T>>>;
  16. /// ObjectStreamOut contains all logic for writing an object to disk. It is the base
  17. /// class for the text and binary output streams (ObjectStreamTextOut and ObjectStreamBinaryOut).
  18. class JPH_EXPORT ObjectStreamOut : public IObjectStreamOut
  19. {
  20. private:
  21. struct ObjectInfo;
  22. public:
  23. /// Main function to write an object to a stream
  24. template <class T>
  25. static bool sWriteObject(ostream &inStream, ObjectStream::EStreamType inType, const T &inObject)
  26. {
  27. // Create the output stream
  28. bool result = false;
  29. ObjectStreamOut *stream = ObjectStreamOut::Open(inType, inStream);
  30. if (stream)
  31. {
  32. // Write the object to the stream
  33. result = stream->Write((void *)&inObject, GetRTTI(&inObject));
  34. delete stream;
  35. }
  36. return result;
  37. }
  38. /// Main function to write an object to a file
  39. template <class T>
  40. static bool sWriteObject(const char *inFileName, ObjectStream::EStreamType inType, const T &inObject)
  41. {
  42. std::ofstream stream;
  43. stream.open(inFileName, std::ofstream::out | std::ofstream::trunc | std::ofstream::binary);
  44. if (!stream.is_open())
  45. return false;
  46. return sWriteObject(stream, inType, inObject);
  47. }
  48. //////////////////////////////////////////////////////
  49. // EVERYTHING BELOW THIS SHOULD NOT DIRECTLY BE CALLED
  50. //////////////////////////////////////////////////////
  51. ///@name Serialization operations
  52. bool Write(const void *inObject, const RTTI *inRTTI);
  53. void WriteObject(const void *inObject);
  54. void QueueRTTI(const RTTI *inRTTI);
  55. void WriteRTTI(const RTTI *inRTTI);
  56. virtual void WriteClassData(const RTTI *inRTTI, const void *inInstance) override;
  57. virtual void WritePointerData(const RTTI *inRTTI, const void *inPointer) override;
  58. protected:
  59. /// Static constructor
  60. static ObjectStreamOut * Open(EStreamType inType, ostream &inStream);
  61. /// Constructor
  62. explicit ObjectStreamOut(ostream &inStream);
  63. ostream & mStream;
  64. private:
  65. struct ObjectInfo
  66. {
  67. ObjectInfo() : mIdentifier(0), mRTTI(nullptr) { }
  68. ObjectInfo(Identifier inIdentifier, const RTTI *inRTTI) : mIdentifier(inIdentifier), mRTTI(inRTTI) { }
  69. Identifier mIdentifier;
  70. const RTTI * mRTTI;
  71. };
  72. using IdentifierMap = UnorderedMap<const void *, ObjectInfo>;
  73. using ClassSet = UnorderedSet<const RTTI *>;
  74. using ObjectQueue = Queue<const void *>;
  75. using ClassQueue = Queue<const RTTI *>;
  76. Identifier mNextIdentifier = sNullIdentifier + 1; ///< Next free identifier for this stream
  77. IdentifierMap mIdentifierMap; ///< Links object pointer to an identifier
  78. ObjectQueue mObjectQueue; ///< Queue of objects to be written
  79. ClassSet mClassSet; ///< List of classes already written
  80. ClassQueue mClassQueue; ///< List of classes waiting to be written
  81. };
  82. JPH_NAMESPACE_END
  83. #endif // JPH_OBJECT_STREAM