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 "Utility/BsModule.h" |
7 | #include "Scene/BsGameObject.h" |
8 | |
9 | namespace bs |
10 | { |
11 | /** @addtogroup Scene-Internal |
12 | * @{ |
13 | */ |
14 | |
15 | /** Possible modes to use when deserializing game objects. */ |
16 | enum GameObjectDeserializationModeFlags |
17 | { |
18 | /** All handles will point to old ID that were restored from the deserialized file. */ |
19 | GODM_UseOriginalIds = 0x01, |
20 | /** All handles will point to new IDs that were given to the deserialized GameObjects. */ |
21 | GODM_UseNewIds = 0x02, |
22 | /** Handles pointing to GameObjects outside of the currently deserialized set |
23 | will attempt to be restored in case those objects are still active. */ |
24 | GODM_RestoreExternal = 0x04, |
25 | /** Handles pointing to GameObjects outside of the currently deserialized set |
26 | will be broken. */ |
27 | GODM_BreakExternal = 0x08, |
28 | /** Handles pointing to GameObjects that cannot be found will not be set to null. */ |
29 | GODM_KeepMissing = 0x10, |
30 | /** When enabled, new UUIDs will be generated for all deserialized game objects. */ |
31 | GODM_UseNewUUID = 0x20 |
32 | }; |
33 | |
34 | /** |
35 | * Tracks GameObject creation and destructions. Also resolves GameObject references from GameObject handles. |
36 | * |
37 | * @note Sim thread only. |
38 | */ |
39 | class BS_CORE_EXPORT GameObjectManager : public Module<GameObjectManager> |
40 | { |
41 | public: |
42 | GameObjectManager() = default; |
43 | ~GameObjectManager(); |
44 | |
45 | /** |
46 | * Registers a new GameObject and returns the handle to the object. |
47 | * |
48 | * @param[in] object Constructed GameObject to wrap in the handle and initialize. |
49 | * @return Handle to the GameObject. |
50 | * |
51 | * @note Thread safe. |
52 | */ |
53 | GameObjectHandleBase registerObject(const SPtr<GameObject>& object); |
54 | |
55 | /** |
56 | * Unregisters a GameObject. Handles to this object will no longer be valid after this call. This should be called |
57 | * whenever a GameObject is destroyed. |
58 | * |
59 | * @note Thread safe. |
60 | */ |
61 | void unregisterObject(GameObjectHandleBase& object); |
62 | |
63 | /** |
64 | * Attempts to find a GameObject handle based on the GameObject instance ID. Returns empty handle if ID cannot be |
65 | * found. |
66 | * |
67 | * @note Thread safe. |
68 | */ |
69 | GameObjectHandleBase getObject(UINT64 id) const; |
70 | |
71 | /** |
72 | * Attempts to find a GameObject handle based on the GameObject instance ID. Returns true if object with the |
73 | * specified ID is found, false otherwise. |
74 | * |
75 | * @note Thread safe. |
76 | */ |
77 | bool tryGetObject(UINT64 id, GameObjectHandleBase& object) const; |
78 | |
79 | /** |
80 | * Checks if the GameObject with the specified instance ID exists. |
81 | * |
82 | * @note Thread safe. |
83 | */ |
84 | bool objectExists(UINT64 id) const; |
85 | |
86 | /** |
87 | * Changes the instance ID by which an object can be retrieved by. |
88 | * |
89 | * @note Caller is required to update the object itself with the new ID. |
90 | * @note Thread safe. |
91 | */ |
92 | void remapId(UINT64 oldId, UINT64 newId); |
93 | |
94 | /** |
95 | * Allocates a new unique game object ID. |
96 | * |
97 | * @note Thread safe. |
98 | */ |
99 | UINT64 reserveId(); |
100 | |
101 | /** Queues the object to be destroyed at the end of a GameObject update cycle. */ |
102 | void queueForDestroy(const GameObjectHandleBase& object); |
103 | |
104 | /** Destroys any GameObjects that were queued for destruction. */ |
105 | void destroyQueuedObjects(); |
106 | |
107 | /** Triggered when a game object is being destroyed. */ |
108 | Event<void(const HGameObject&)> onDestroyed; |
109 | |
110 | private: |
111 | std::atomic<UINT64> mNextAvailableID = { 1 } ; // 0 is not a valid ID |
112 | Map<UINT64, GameObjectHandleBase> mObjects; |
113 | Map<UINT64, GameObjectHandleBase> mQueuedForDestroy; |
114 | |
115 | mutable Mutex mMutex; |
116 | }; |
117 | |
118 | /** Resolves game object handles and ID during deserialization of a game object hierarchy. */ |
119 | class BS_CORE_EXPORT GameObjectDeserializationState |
120 | { |
121 | private: |
122 | /** Contains data for an yet unresolved game object handle. */ |
123 | struct UnresolvedHandle |
124 | { |
125 | UINT64 originalInstanceId; |
126 | GameObjectHandleBase handle; |
127 | }; |
128 | |
129 | public: |
130 | /** |
131 | * Starts game object deserialization. |
132 | * |
133 | * @param[in] options One or a combination of GameObjectDeserializationModeFlags, controlling how |
134 | * are game objects deserialized. |
135 | */ |
136 | GameObjectDeserializationState(UINT32 options = GODM_UseNewIds | GODM_BreakExternal); |
137 | ~GameObjectDeserializationState(); |
138 | |
139 | /** Queues the specified handle and resolves it when deserialization ends. */ |
140 | void registerUnresolvedHandle(UINT64 originalId, GameObjectHandleBase& object); |
141 | |
142 | /** Notifies the system about a new deserialized game object and its original ID. */ |
143 | void registerObject(UINT64 originalId, GameObjectHandleBase& object); |
144 | |
145 | /** Registers a callback that will be triggered when GameObject serialization ends. */ |
146 | void registerOnDeserializationEndCallback(std::function<void()> callback); |
147 | |
148 | /** Resolves all registered handles and objects, and triggers end callbacks. */ |
149 | void resolve(); |
150 | |
151 | private: |
152 | UnorderedMap<UINT64, UINT64> mIdMapping; |
153 | UnorderedMap<UINT64, SPtr<GameObjectHandleData>> mUnresolvedHandleData; |
154 | UnorderedMap<UINT64, GameObjectHandleBase> mDeserializedObjects; |
155 | Vector<UnresolvedHandle> mUnresolvedHandles; |
156 | Vector<std::function<void()>> mEndCallbacks; |
157 | UINT32 mOptions; |
158 | }; |
159 | |
160 | /** @} */ |
161 | } |