BsBinaryDiff.h 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. #pragma once
  2. #include "BsPrerequisitesUtil.h"
  3. namespace BansheeEngine
  4. {
  5. /** @cond INTERNAL */
  6. /** @addtogroup Serialization
  7. * @{
  8. */
  9. /**
  10. * Represents an interface RTTI objects need to implement if they want to provide custom "diff" generation and applying.
  11. */
  12. class BS_UTILITY_EXPORT IDiff
  13. {
  14. public:
  15. virtual ~IDiff() { }
  16. /**
  17. * Generates per-field differences between the provided original and new object. Any field or array entry that is
  18. * different in the new object compared to the original will be output in the resulting object, with a full
  19. * hierarchy of that field.
  20. *
  21. * Will return null if there is no difference.
  22. */
  23. SPtr<SerializedObject> generateDiff(const SPtr<SerializedObject>& orgObj, const SPtr<SerializedObject>& newObj);
  24. /**
  25. * Applies a previously generated per-field differences to the provided object. This will essentially transform the
  26. * original object the differences were generated for into the modified version.
  27. */
  28. void applyDiff(const SPtr<IReflectable>& object, const SPtr<SerializedObject>& diff);
  29. protected:
  30. typedef UnorderedMap<SPtr<SerializedObject>, SPtr<SerializedObject>> ObjectMap;
  31. typedef UnorderedMap<SPtr<SerializedObject>, SPtr<IReflectable>> DiffObjectMap;
  32. /** Types of commands that are used when applying difference field values. */
  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. * A command that is used for delaying writing to an object, it contains all necessary information for setting RTTI
  46. * 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. * 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. * Generates a difference between data of a specific field type indiscriminately of the specific field type.
  69. *
  70. * @see generateDiff(const SPtr<SerializedObject>&, const SPtr<SerializedObject>&)
  71. */
  72. SPtr<SerializedInstance> generateDiff(RTTITypeBase* rtti, UINT32 fieldType, const SPtr<SerializedInstance>& orgData,
  73. const SPtr<SerializedInstance>& newData, ObjectMap& objectMap);
  74. /**
  75. * Recursive version of applyDiff(const SPtr<IReflectable>& object, const SPtr<SerializedObject>& diff). Outputs a
  76. * set of commands that then must be executed in order to actually apply the difference to the provided object.
  77. *
  78. * @see applyDiff(const SPtr<IReflectable>& object, const SPtr<SerializedObject>& diff)
  79. */
  80. virtual void applyDiff(const SPtr<IReflectable>& object, const SPtr<SerializedObject>& diff, DiffObjectMap& objectMap, Vector<DiffCommand>& diffCommands) = 0;
  81. /**
  82. * Applies diff according to the diff handler retrieved from the provided RTTI object.
  83. *
  84. * @see applyDiff(const SPtr<IReflectable>& object, const SPtr<SerializedObject>& diff)
  85. */
  86. void applyDiff(RTTITypeBase* rtti, const SPtr<IReflectable>& object, const SPtr<SerializedObject>& diff, DiffObjectMap& objectMap, Vector<DiffCommand>& diffCommands);
  87. };
  88. /**
  89. * Generates and applies "diffs". Diffs contain per-field differences between an original and new object. These
  90. * differences can be saved and then applied to an original object to transform it to the new version.
  91. *
  92. * @note Objects must be in intermediate serialized format generated by BinarySerializer.
  93. */
  94. class BS_UTILITY_EXPORT BinaryDiff : public IDiff
  95. {
  96. private:
  97. /** @copydoc IDiff::generateDiff(const SPtr<SerializedObject>&, const SPtr<SerializedObject>&, ObjectMap&) */
  98. SPtr<SerializedObject> generateDiff(const SPtr<SerializedObject>& orgObj, const SPtr<SerializedObject>& newObj, ObjectMap& objectMap) override;
  99. /** @copydoc IDiff::applyDiff(const SPtr<IReflectable>&, const SPtr<SerializedObject>&, DiffObjectMap&, Vector<DiffCommand>&) */
  100. void applyDiff(const SPtr<IReflectable>& object, const SPtr<SerializedObject>& diff, DiffObjectMap& objectMap, Vector<DiffCommand>& diffCommands) override;
  101. };
  102. /** @} */
  103. /** @endcond */
  104. }