BsBinaryDiff.h 4.8 KB

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