BsGameObjectManager.h 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. #pragma once
  2. #include "BsCorePrerequisites.h"
  3. #include "BsModule.h"
  4. #include "BsGameObject.h"
  5. namespace BansheeEngine
  6. {
  7. /**
  8. * @brief Possible modes to use when deserializing games objects.
  9. */
  10. enum GameObjectHandleDeserializationMode
  11. {
  12. /** All handles will point to old ID that were restored from the deserialized file. */
  13. GODM_UseOriginalIds = 0x01,
  14. /** All handles will point to new IDs that were given to the deserialized GameObjects. */
  15. GODM_UseNewIds = 0x02,
  16. /** Handles pointing to GameObjects outside of the currently deserialized set
  17. will attempt to be restored in case those objects are still active. */
  18. GODM_RestoreExternal = 0x04,
  19. /** Handles pointing to GameObjects outside of the currently deserialized set
  20. will be broken. */
  21. GODM_BreakExternal = 0x08,
  22. /** Handles pointing to GameObjects that cannot be found will not be set to null. */
  23. GODM_KeepMissing = 0x10
  24. };
  25. /**
  26. * @brief Tracks GameObject creation and destructions. Also resolves
  27. * GameObject references from GameObject handles.
  28. *
  29. * @note Sim thread only.
  30. */
  31. class BS_CORE_EXPORT GameObjectManager : public Module<GameObjectManager>
  32. {
  33. /**
  34. * @brief Contains data for an yet unresolved game object handle.
  35. */
  36. struct UnresolvedHandle
  37. {
  38. UINT64 originalInstanceId;
  39. GameObjectHandleBase handle;
  40. };
  41. public:
  42. GameObjectManager();
  43. ~GameObjectManager();
  44. /**
  45. * @brief Registers a new GameObject and returns the handle to the object.
  46. *
  47. * @param object Constructed GameObject to wrap in the handle and initialize.
  48. * @param originalId If the object is being created due to deserialization you must provide the
  49. * original object's ID so that deserialized handles can map to it properly.
  50. *
  51. * @returns Handle to the GameObject.
  52. */
  53. GameObjectHandleBase registerObject(const std::shared_ptr<GameObject>& object, UINT64 originalId = 0);
  54. /**
  55. * @brief Unregisters a GameObject. Handles to this object will no longer be valid after this call.
  56. * This should be called whenever a GameObject is destroyed.
  57. */
  58. void unregisterObject(GameObjectHandleBase& object);
  59. /**
  60. * @brief Attempts to find a GameObject handle based on the GameObject instance ID.
  61. * Returns empty handle if ID cannot be found.
  62. */
  63. GameObjectHandleBase getObject(UINT64 id) const;
  64. /**
  65. * @brief Attempts to find a GameObject handle based on the GameObject instance ID.
  66. * Returns true if object with the specified ID is found, false otherwise.
  67. */
  68. bool tryGetObject(UINT64 id, GameObjectHandleBase& object) const;
  69. /**
  70. * @brief Checks if the GameObject with the specified instance ID exists.
  71. */
  72. bool objectExists(UINT64 id) const;
  73. /**
  74. * @brief Changes the instance ID by which an object can be retrieved by.
  75. *
  76. * @note Caller is required to update the object itself with the new ID.
  77. */
  78. void remapId(UINT64 oldId, UINT64 newId);
  79. /**
  80. * @brief Queues the object to be destroyed at the end of a GameObject update cycle.
  81. */
  82. void queueForDestroy(const GameObjectHandleBase& object);
  83. /**
  84. * @brief Destroys any GameObjects that were queued for destruction.
  85. */
  86. void destroyQueuedObjects();
  87. /**
  88. * @brief Triggered when a game object is being destroyed.
  89. */
  90. Event<void(const HGameObject&)> onDestroyed;
  91. /************************************************************************/
  92. /* DESERIALIZATION */
  93. /************************************************************************/
  94. // Note: GameObjects need a bit of special handling when it comes to deserialization,
  95. // which is what this part of the code is used for. It performs two main actions:
  96. // - 1. Resolves all GameObjectHandles on deserialization
  97. // - We can't just resolve them as we go because during deserialization not all objects
  98. // have necessarily been created.
  99. // - 2. Maps serialized IDs to actual in-engine IDs.
  100. /**
  101. * @brief Needs to be called whenever GameObject deserialization starts. Must be followed
  102. * by endDeserialization call.
  103. */
  104. void startDeserialization();
  105. /**
  106. * @brief Needs to be called whenever GameObject deserialization ends. Must be preceded
  107. * by startDeserialization call.
  108. */
  109. void endDeserialization();
  110. /**
  111. * @brief Returns true if GameObject deserialization is currently in progress.
  112. */
  113. bool isGameObjectDeserializationActive() const { return mIsDeserializationActive; }
  114. /**
  115. * @brief Queues the specified handle and resolves it when deserialization ends.
  116. */
  117. void registerUnresolvedHandle(UINT64 originalId, GameObjectHandleBase& object);
  118. /**
  119. * @brief Registers a callback that will be triggered when GameObject serialization ends.
  120. */
  121. void registerOnDeserializationEndCallback(std::function<void()> callback);
  122. /**
  123. * @brief Changes the deserialization mode for any following GameObject handle.
  124. *
  125. * @param gameObjectDeserializationMode Mode that controls how are GameObjects handles resolved when being deserialized.
  126. */
  127. void setDeserializationMode(UINT32 gameObjectDeserializationMode);
  128. /**
  129. * @brief Attempts to update the ID of the provided handle by mapping its old ID to
  130. * the newly deserialized object and its new ID. Game object deserialization
  131. * must be active.
  132. */
  133. void resolveDeserializedHandle(UnresolvedHandle& data, UINT32 flags);
  134. /**
  135. * @brief Gets the currently active flags that control how are game object handles deserialized.
  136. */
  137. UINT32 getDeserializationFlags() const { return mGODeserializationMode; }
  138. private:
  139. UINT64 mNextAvailableID; // 0 is not a valid ID
  140. Map<UINT64, GameObjectHandleBase> mObjects;
  141. Map<UINT64, GameObjectHandleBase> mQueuedForDestroy;
  142. GameObject* mActiveDeserializedObject;
  143. bool mIsDeserializationActive;
  144. Map<UINT64, UINT64> mIdMapping;
  145. Map<UINT64, SPtr<GameObjectHandleData>> mUnresolvedHandleData;
  146. Vector<UnresolvedHandle> mUnresolvedHandles;
  147. Vector<std::function<void()>> mEndCallbacks;
  148. UINT32 mGODeserializationMode;
  149. };
  150. }