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 "Scene/BsGameObject.h"
7#include "Resources/BsResource.h"
8
9namespace bs
10{
11 /** @addtogroup Scene
12 * @{
13 */
14
15 /**
16 * Prefab is a saveable hierarchy of scene objects. In general it can serve as any grouping of scene objects
17 * (for example a level) or be used as a form of a template instantiated and reused throughout the scene.
18 */
19 class BS_CORE_EXPORT Prefab : public Resource
20 {
21 public:
22 Prefab();
23 ~Prefab();
24
25 /**
26 * Creates a new prefab from the provided scene object. If the scene object has an existing prefab link it will
27 * be broken. After the prefab is created the scene object will be automatically linked to it.
28 *
29 * @param[in] sceneObject Scene object to create the prefab from.
30 * @param[in] isScene Determines if the prefab represents a scene or just a generic group of objects.
31 * @see isScene().
32 */
33 static HPrefab create(const HSceneObject& sceneObject, bool isScene = true);
34
35 /**
36 * Instantiates a prefab by creating an instance of the prefab's scene object hierarchy. The returned hierarchy
37 * will be parented to world root by default.
38 *
39 * @return Instantiated clone of the prefab's scene object hierarchy.
40 */
41 HSceneObject instantiate() const { return _instantiate(); }
42
43 /**
44 * Replaces the contents of this prefab with new contents from the provided object. Object will be automatically
45 * linked to this prefab, and its previous prefab link (if any) will be broken.
46 */
47 void update(const HSceneObject& sceneObject);
48
49 /**
50 * Returns a hash value that can be used for determining if a prefab changed by comparing it to a previously saved
51 * hash.
52 */
53 UINT32 getHash() const { return mHash; }
54
55 /**
56 * Determines if the prefab represents a scene or just a generic group of objects. The only difference between the
57 * two is the way root object is handled: scenes are assumed to be saved with the scene root object (which is
58 * hidden), while object group root is a normal scene object (not hidden). This is relevant when when prefabs are
59 * loaded, so the systems knows to append the root object to non-scene prefabs.
60 */
61 bool isScene() const { return mIsScene; }
62
63 public: // ***** INTERNAL ******
64 /** @name Internal
65 * @{
66 */
67
68 /** Updates any prefab child instances by loading their prefabs and making sure they are up to date. */
69 void _updateChildInstances() const;
70
71 /**
72 * Returns a reference to the internal prefab hierarchy. Returned hierarchy is not instantiated and cannot be
73 * interacted with in a manner you would with normal scene objects.
74 */
75 HSceneObject _getRoot() const { return mRoot; }
76
77 /**
78 * Creates the clone of the prefab's current hierarchy but doesn't instantiate it.
79 *
80 * @param[in] preserveUUIDs If false, each cloned game object will be assigned a brand new UUID. Otherwise
81 * the UUID of the original game objects will be preserved. Note that two instantiated
82 * scene objects should never have the same UUID, so if preserving UUID's make sure
83 * the original is destroyed before instantiating.
84 * @return Clone of the prefab's scene object hierarchy.
85 */
86 HSceneObject _clone(bool preserveUUIDs = false) const;
87
88 /**
89 * Instantiates a prefab by creating an instance of the prefab's scene object hierarchy. The returned hierarchy
90 * will be parented to world root by default.
91 *
92 * @param[in] preserveUUIDs If false, each cloned game object will be assigned a brand new UUID. Otherwise
93 * the UUID of the original game objects will be preserved. Note that two instantiated
94 * scene objects should never have the same UUID, so if preserving UUID's make sure
95 * the original is destroyed before instantiating.
96 * @return Instantiated clone of the prefab's scene object hierarchy.
97 */
98 HSceneObject _instantiate(bool preserveUUIDs = false) const;
99
100 /** @} */
101
102 private:
103 using CoreObject::initialize;
104
105 /** Initializes the internal prefab hierarchy. Must be called druing creation. */
106 void initialize(const HSceneObject& sceneObject);
107
108 /** Creates an empty and uninitialized prefab. */
109 static SPtr<Prefab> createEmpty();
110
111 HSceneObject mRoot;
112 UINT32 mHash = 0;
113 UUID mUUID;
114 bool mIsScene = true;
115
116 /************************************************************************/
117 /* RTTI */
118 /************************************************************************/
119
120 public:
121 friend class PrefabRTTI;
122 static RTTITypeBase* getRTTIStatic();
123 RTTITypeBase* getRTTI() const override;
124 };
125
126 /** @} */
127}