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