BsBinaryDiff.h 4.8 KB

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