SerializableObject.h 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  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. JPH_NAMESPACE_BEGIN
  7. //////////////////////////////////////////////////////////////////////////////////////////
  8. // Helper macros
  9. //////////////////////////////////////////////////////////////////////////////////////////
  10. #ifdef JPH_OBJECT_STREAM
  11. // JPH_DECLARE_SERIALIZATION_FUNCTIONS
  12. #define JPH_DECLARE_SERIALIZATION_FUNCTIONS(linkage, prefix, class_name) \
  13. linkage prefix bool OSReadData(IObjectStreamIn &ioStream, class_name &inInstance); \
  14. linkage prefix bool OSReadData(IObjectStreamIn &ioStream, class_name *&inPointer); \
  15. linkage prefix bool OSIsType(class_name *, int inArrayDepth, EOSDataType inDataType, const char *inClassName); \
  16. linkage prefix bool OSIsType(class_name **, int inArrayDepth, EOSDataType inDataType, const char *inClassName); \
  17. linkage prefix void OSWriteData(IObjectStreamOut &ioStream, const class_name &inInstance); \
  18. linkage prefix void OSWriteData(IObjectStreamOut &ioStream, class_name *const &inPointer); \
  19. linkage prefix void OSWriteDataType(IObjectStreamOut &ioStream, class_name *); \
  20. linkage prefix void OSWriteDataType(IObjectStreamOut &ioStream, class_name **);
  21. // JPH_IMPLEMENT_SERIALIZATION_FUNCTIONS
  22. #define JPH_IMPLEMENT_SERIALIZATION_FUNCTIONS(class_name) \
  23. bool OSReadData(IObjectStreamIn &ioStream, class_name &inInstance) \
  24. { \
  25. return ioStream.ReadClassData(#class_name, (void *)&inInstance); \
  26. } \
  27. bool OSReadData(IObjectStreamIn &ioStream, class_name *&inPointer) \
  28. { \
  29. return ioStream.ReadPointerData(JPH_RTTI(class_name), (void **)&inPointer); \
  30. } \
  31. bool OSIsType(class_name *, int inArrayDepth, EOSDataType inDataType, const char *inClassName) \
  32. { \
  33. return inArrayDepth == 0 && inDataType == EOSDataType::Instance && strcmp(inClassName, #class_name) == 0; \
  34. } \
  35. bool OSIsType(class_name **, int inArrayDepth, EOSDataType inDataType, const char *inClassName) \
  36. { \
  37. return inArrayDepth == 0 && inDataType == EOSDataType::Pointer && strcmp(inClassName, #class_name) == 0; \
  38. } \
  39. void OSWriteData(IObjectStreamOut &ioStream, const class_name &inInstance) \
  40. { \
  41. ioStream.WriteClassData(JPH_RTTI(class_name), (void *)&inInstance); \
  42. } \
  43. void OSWriteData(IObjectStreamOut &ioStream, class_name *const &inPointer) \
  44. { \
  45. if (inPointer) \
  46. ioStream.WritePointerData(GetRTTI(inPointer), (void *)inPointer); \
  47. else \
  48. ioStream.WritePointerData(nullptr, nullptr); \
  49. } \
  50. void OSWriteDataType(IObjectStreamOut &ioStream, class_name *) \
  51. { \
  52. ioStream.WriteDataType(EOSDataType::Instance); \
  53. ioStream.WriteName(#class_name); \
  54. } \
  55. void OSWriteDataType(IObjectStreamOut &ioStream, class_name **) \
  56. { \
  57. ioStream.WriteDataType(EOSDataType::Pointer); \
  58. ioStream.WriteName(#class_name); \
  59. }
  60. #else
  61. #define JPH_DECLARE_SERIALIZATION_FUNCTIONS(...)
  62. #define JPH_IMPLEMENT_SERIALIZATION_FUNCTIONS(...)
  63. #endif // JPH_OBJECT_STREAM
  64. //////////////////////////////////////////////////////////////////////////////////////////
  65. // Use these macros on non-virtual objects to make them serializable
  66. //////////////////////////////////////////////////////////////////////////////////////////
  67. // JPH_DECLARE_SERIALIZABLE_NON_VIRTUAL
  68. #define JPH_DECLARE_SERIALIZABLE_NON_VIRTUAL(linkage, class_name) \
  69. public: \
  70. JPH_DECLARE_RTTI_NON_VIRTUAL(linkage, class_name) \
  71. JPH_DECLARE_SERIALIZATION_FUNCTIONS(linkage, friend, class_name) \
  72. // JPH_IMPLEMENT_SERIALIZABLE_NON_VIRTUAL
  73. #define JPH_IMPLEMENT_SERIALIZABLE_NON_VIRTUAL(class_name) \
  74. JPH_IMPLEMENT_SERIALIZATION_FUNCTIONS(class_name) \
  75. JPH_IMPLEMENT_RTTI_NON_VIRTUAL(class_name) \
  76. //////////////////////////////////////////////////////////////////////////////////////////
  77. // Same as above, but when you cannot insert the declaration in the class itself
  78. //////////////////////////////////////////////////////////////////////////////////////////
  79. // JPH_DECLARE_SERIALIZABLE_OUTSIDE_CLASS
  80. #define JPH_DECLARE_SERIALIZABLE_OUTSIDE_CLASS(linkage, class_name) \
  81. JPH_DECLARE_RTTI_OUTSIDE_CLASS(linkage, class_name) \
  82. JPH_DECLARE_SERIALIZATION_FUNCTIONS(linkage, extern, class_name) \
  83. // JPH_IMPLEMENT_SERIALIZABLE_OUTSIDE_CLASS
  84. #define JPH_IMPLEMENT_SERIALIZABLE_OUTSIDE_CLASS(class_name) \
  85. JPH_IMPLEMENT_SERIALIZATION_FUNCTIONS(class_name) \
  86. JPH_IMPLEMENT_RTTI_OUTSIDE_CLASS(class_name) \
  87. //////////////////////////////////////////////////////////////////////////////////////////
  88. // Same as above, but for classes that have virtual functions
  89. //////////////////////////////////////////////////////////////////////////////////////////
  90. // JPH_DECLARE_SERIALIZABLE_VIRTUAL - Use for concrete, non-base classes
  91. #define JPH_DECLARE_SERIALIZABLE_VIRTUAL(linkage, class_name) \
  92. public: \
  93. JPH_DECLARE_RTTI_VIRTUAL(linkage, class_name) \
  94. JPH_DECLARE_SERIALIZATION_FUNCTIONS(linkage, friend, class_name) \
  95. // JPH_IMPLEMENT_SERIALIZABLE_VIRTUAL
  96. #define JPH_IMPLEMENT_SERIALIZABLE_VIRTUAL(class_name) \
  97. JPH_IMPLEMENT_SERIALIZATION_FUNCTIONS(class_name) \
  98. JPH_IMPLEMENT_RTTI_VIRTUAL(class_name) \
  99. // JPH_DECLARE_SERIALIZABLE_ABSTRACT - Use for abstract, non-base classes
  100. #define JPH_DECLARE_SERIALIZABLE_ABSTRACT(linkage, class_name) \
  101. public: \
  102. JPH_DECLARE_RTTI_ABSTRACT(linkage, class_name) \
  103. JPH_DECLARE_SERIALIZATION_FUNCTIONS(linkage, friend, class_name) \
  104. // JPH_IMPLEMENT_SERIALIZABLE_ABSTRACT
  105. #define JPH_IMPLEMENT_SERIALIZABLE_ABSTRACT(class_name) \
  106. JPH_IMPLEMENT_SERIALIZATION_FUNCTIONS(class_name) \
  107. JPH_IMPLEMENT_RTTI_ABSTRACT(class_name) \
  108. // JPH_DECLARE_SERIALIZABLE_VIRTUAL_BASE - Use for concrete base classes
  109. #define JPH_DECLARE_SERIALIZABLE_VIRTUAL_BASE(linkage, class_name) \
  110. public: \
  111. JPH_DECLARE_RTTI_VIRTUAL_BASE(linkage, class_name) \
  112. JPH_DECLARE_SERIALIZATION_FUNCTIONS(linkage, friend, class_name) \
  113. // JPH_IMPLEMENT_SERIALIZABLE_VIRTUAL_BASE
  114. #define JPH_IMPLEMENT_SERIALIZABLE_VIRTUAL_BASE(class_name) \
  115. JPH_IMPLEMENT_SERIALIZATION_FUNCTIONS(class_name) \
  116. JPH_IMPLEMENT_RTTI_VIRTUAL_BASE(class_name) \
  117. // JPH_DECLARE_SERIALIZABLE_ABSTRACT_BASE - Use for abstract base class
  118. #define JPH_DECLARE_SERIALIZABLE_ABSTRACT_BASE(linkage, class_name) \
  119. public: \
  120. JPH_DECLARE_RTTI_ABSTRACT_BASE(linkage, class_name) \
  121. JPH_DECLARE_SERIALIZATION_FUNCTIONS(linkage, friend, class_name) \
  122. // JPH_IMPLEMENT_SERIALIZABLE_ABSTRACT_BASE
  123. #define JPH_IMPLEMENT_SERIALIZABLE_ABSTRACT_BASE(class_name) \
  124. JPH_IMPLEMENT_SERIALIZATION_FUNCTIONS(class_name) \
  125. JPH_IMPLEMENT_RTTI_ABSTRACT_BASE(class_name)
  126. /// Classes must be derived from SerializableObject if you want to be able to save pointers or
  127. /// reference counting pointers to objects of this or derived classes. The type will automatically
  128. /// be determined during serialization and upon deserialization it will be restored correctly.
  129. class JPH_EXPORT SerializableObject : public NonCopyable
  130. {
  131. JPH_DECLARE_SERIALIZABLE_ABSTRACT_BASE(JPH_EXPORT, SerializableObject)
  132. public:
  133. /// Constructor
  134. virtual ~SerializableObject() = default;
  135. };
  136. JPH_NAMESPACE_END