BsBinaryDiff.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. #pragma once
  2. #include "BsPrerequisitesUtil.h"
  3. namespace BansheeEngine
  4. {
  5. /**
  6. * @brief Represents an interface RTTI objects need to implement if they
  7. * want to provide custom "diff" generation and applying.
  8. */
  9. class BS_UTILITY_EXPORT IDiff
  10. {
  11. public:
  12. virtual ~IDiff() { }
  13. /**
  14. * @brief Generates per-field differences between the provided original and new object. Any field
  15. * or array entry that is different in the new object compared to the original will be output
  16. * in the resulting object, with a full hierarchy of that field.
  17. *
  18. * Will return null if there is no difference.
  19. */
  20. SPtr<SerializedObject> generateDiff(const SPtr<SerializedObject>& orgObj, const SPtr<SerializedObject>& newObj);
  21. /**
  22. * @brief Applies a previously generated per-field differences to the provided object. This will
  23. * essentially transform the original object the differences were generated for into the modified
  24. * version.
  25. */
  26. void applyDiff(const SPtr<IReflectable>& object, const SPtr<SerializedObject>& diff);
  27. protected:
  28. typedef UnorderedMap<SPtr<SerializedObject>, SPtr<SerializedObject>> ObjectMap;
  29. typedef UnorderedMap<SPtr<SerializedObject>, SPtr<IReflectable>> DiffObjectMap;
  30. /**
  31. * @brief Types of commands that are used when applying difference field values.
  32. */
  33. enum DiffCommandType
  34. {
  35. Diff_Plain = 0x01,
  36. Diff_Reflectable = 0x02,
  37. Diff_ReflectablePtr = 0x03,
  38. Diff_DataBlock = 0x04,
  39. Diff_ArraySize = 0x05,
  40. Diff_ObjectStart = 0x06,
  41. Diff_ObjectEnd = 0x07,
  42. Diff_ArrayFlag = 0x10
  43. };
  44. /**
  45. * @brief A command that is used for delaying writing to an object, it contains
  46. * all necessary information for setting RTTI field values on an object.
  47. */
  48. struct DiffCommand
  49. {
  50. RTTIField* field;
  51. UINT32 type;
  52. SPtr<IReflectable> object;
  53. UINT8* value;
  54. UINT32 size;
  55. union
  56. {
  57. UINT32 arrayIdx;
  58. UINT32 arraySize;
  59. };
  60. };
  61. /**
  62. * @brief Recursive version of generateDiff(const SPtr<SerializedObject>&, const SPtr<SerializedObject>&).
  63. *
  64. * @see generateDiff(const SPtr<SerializedObject>&, const SPtr<SerializedObject>&)
  65. */
  66. virtual SPtr<SerializedObject> generateDiff(const SPtr<SerializedObject>& orgObj, const SPtr<SerializedObject>& newObj, ObjectMap& objectMap) = 0;
  67. /**
  68. * @brief Generates a difference between data of a specific field type indiscriminately of the
  69. * specific field type.
  70. *
  71. * @see generateDiff(const SPtr<SerializedObject>&, const SPtr<SerializedObject>&)
  72. */
  73. SPtr<SerializedInstance> generateDiff(RTTITypeBase* rtti, UINT32 fieldType, const SPtr<SerializedInstance>& orgData,
  74. const SPtr<SerializedInstance>& newData, ObjectMap& objectMap);
  75. /**
  76. * @brief Recursive version of applyDiff(const SPtr<IReflectable>& object, const SPtr<SerializedObject>& diff).
  77. * Outputs a set of commands that then must be executed in order to actually apply the difference to the
  78. * provided object.
  79. *
  80. * @see applyDiff(const SPtr<IReflectable>& object, const SPtr<SerializedObject>& diff)
  81. */
  82. virtual void applyDiff(const SPtr<IReflectable>& object, const SPtr<SerializedObject>& diff, DiffObjectMap& objectMap, Vector<DiffCommand>& diffCommands) = 0;
  83. /**
  84. * @brief Applies diff according to the diff handler retrieved from the provided RTTI object.
  85. *
  86. * @see applyDiff(const SPtr<IReflectable>& object, const SPtr<SerializedObject>& diff)
  87. */
  88. void applyDiff(RTTITypeBase* rtti, const SPtr<IReflectable>& object, const SPtr<SerializedObject>& diff, DiffObjectMap& objectMap, Vector<DiffCommand>& diffCommands);
  89. };
  90. /**
  91. * @brief Generates and applies "diffs". Diffs contain per-field differences between
  92. * an original and new object. These differences can be saved and then applied
  93. * to an original object to transform it to the new version.
  94. *
  95. * @note Objects must be in intermediate serialized format generated by BinarySerializer.
  96. */
  97. class BS_UTILITY_EXPORT BinaryDiff : public IDiff
  98. {
  99. private:
  100. /**
  101. * @copydoc IDiff::generateDiff(const SPtr<SerializedObject>&, const SPtr<SerializedObject>&, ObjectMap&)
  102. */
  103. SPtr<SerializedObject> generateDiff(const SPtr<SerializedObject>& orgObj, const SPtr<SerializedObject>& newObj, ObjectMap& objectMap) override;
  104. /**
  105. * @copydoc IDiff::applyDiff(const SPtr<IReflectable>&, const SPtr<SerializedObject>&, DiffObjectMap&, Vector<DiffCommand>&)
  106. */
  107. void applyDiff(const SPtr<IReflectable>& object, const SPtr<SerializedObject>& diff, DiffObjectMap& objectMap, Vector<DiffCommand>& diffCommands) override;
  108. };
  109. }