BsPrefabDiff.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #pragma once
  4. #include "BsCorePrerequisites.h"
  5. #include "Reflection/BsIReflectable.h"
  6. #include "Scene/BsGameObject.h"
  7. #include "Math/BsVector3.h"
  8. #include "Math/BsQuaternion.h"
  9. namespace bs
  10. {
  11. /** @addtogroup Scene-Internal
  12. * @{
  13. */
  14. /**
  15. * Contains differences between two components of the same type.
  16. *
  17. * @see PrefabDiff
  18. */
  19. struct BS_CORE_EXPORT PrefabComponentDiff : public IReflectable
  20. {
  21. INT32 id;
  22. SPtr<SerializedObject> data;
  23. /************************************************************************/
  24. /* RTTI */
  25. /************************************************************************/
  26. public:
  27. friend class PrefabComponentDiffRTTI;
  28. static RTTITypeBase* getRTTIStatic();
  29. RTTITypeBase* getRTTI() const override;
  30. };
  31. /** Flags that mark which portion of a scene-object is modified. */
  32. enum class SceneObjectDiffFlags
  33. {
  34. Name = 0x01,
  35. Position = 0x02,
  36. Rotation = 0x04,
  37. Scale = 0x08,
  38. Active = 0x10
  39. };
  40. /**
  41. * Contains a set of prefab differences for a single scene object.
  42. *
  43. * @see PrefabDiff
  44. */
  45. struct BS_CORE_EXPORT PrefabObjectDiff : public IReflectable
  46. {
  47. PrefabObjectDiff() { }
  48. UINT32 id = 0;
  49. String name;
  50. Vector3 position = Vector3::ZERO;
  51. Quaternion rotation = Quaternion::IDENTITY;
  52. Vector3 scale = Vector3::ZERO;
  53. bool isActive = false;
  54. UINT32 soFlags = 0;
  55. Vector<SPtr<PrefabComponentDiff>> componentDiffs;
  56. Vector<UINT32> removedComponents;
  57. Vector<SPtr<SerializedObject>> addedComponents;
  58. Vector<SPtr<PrefabObjectDiff>> childDiffs;
  59. Vector<UINT32> removedChildren;
  60. Vector<SPtr<SerializedObject>> addedChildren;
  61. /************************************************************************/
  62. /* RTTI */
  63. /************************************************************************/
  64. public:
  65. friend class PrefabObjectDiffRTTI;
  66. static RTTITypeBase* getRTTIStatic();
  67. RTTITypeBase* getRTTI() const override;
  68. };
  69. /**
  70. * Contains modifications between an prefab and its instance. The modifications are a set of added/removed children or
  71. * components and per-field "diffs" of their components.
  72. */
  73. class BS_CORE_EXPORT PrefabDiff : public IReflectable
  74. {
  75. public:
  76. /**
  77. * Creates a new prefab diff by comparing the provided instanced scene object hierarchy with the prefab scene
  78. * object hierarchy.
  79. */
  80. static SPtr<PrefabDiff> create(const HSceneObject& prefab, const HSceneObject& instance);
  81. /**
  82. * Applies the internal prefab diff to the provided object. The object should have similar hierarchy as the prefab
  83. * the diff was created for, otherwise the results are undefined.
  84. *
  85. * @note Be aware that this method will not instantiate newly added components or scene objects. It's expected
  86. * that this method will be called on a fresh copy of a scene object hierarchy, and everything to be
  87. * instantiated at once after diff is applied.
  88. */
  89. void apply(const HSceneObject& object);
  90. private:
  91. /** A reference to a renamed game object instance data, and its original ID so it may be restored later. */
  92. struct RenamedGameObject
  93. {
  94. GameObjectInstanceDataPtr instanceData;
  95. UINT64 originalId;
  96. };
  97. /**
  98. * Recurses over every scene object in the prefab a generates differences between itself and the instanced version.
  99. *
  100. * @see create
  101. */
  102. static SPtr<PrefabObjectDiff> generateDiff(const HSceneObject& prefab, const HSceneObject& instance);
  103. /**
  104. * Recursively applies a per-object set of prefab differences to a specific object.
  105. *
  106. * @see apply
  107. */
  108. static void applyDiff(const SPtr<PrefabObjectDiff>& diff, const HSceneObject& object);
  109. /**
  110. * Renames all game objects in the provided instance so that IDs of the objects will match the IDs of their
  111. * counterparts in the prefab.
  112. *
  113. * @note
  114. * This is a temporary action and should be undone by calling restoreInstanceIds() and providing it with the
  115. * output of this method.
  116. * @note
  117. * By doing this before calling generateDiff() we ensure that any game object handles pointing to objects within
  118. * the prefab instance hierarchy aren't recorded by the diff system, since we want those to remain as they are
  119. * after applying the diff.
  120. */
  121. static void renameInstanceIds(const HSceneObject& prefab, const HSceneObject& instance, Vector<RenamedGameObject>& output);
  122. /**
  123. * Restores any instance IDs that were modified by the renameInstanceIds() method.
  124. *
  125. * @see renameInstanceIds
  126. */
  127. static void restoreInstanceIds(const Vector<RenamedGameObject>& renamedObjects);
  128. SPtr<PrefabObjectDiff> mRoot;
  129. /************************************************************************/
  130. /* RTTI */
  131. /************************************************************************/
  132. public:
  133. friend class PrefabDiffRTTI;
  134. static RTTITypeBase* getRTTIStatic();
  135. RTTITypeBase* getRTTI() const override;
  136. };
  137. /** @} */
  138. }