SerializableObject.h 7.8 KB

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