ObjectStreamOut.h 3.2 KB

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