BsSceneObjectRTTI.h 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  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/BsRTTIType.h"
  6. #include "Scene/BsSceneObject.h"
  7. #include "Scene/BsGameObjectHandle.h"
  8. #include "Scene/BsGameObjectManager.h"
  9. #include "Scene/BsComponent.h"
  10. #include "RTTI/BsGameObjectRTTI.h"
  11. #include "Scene/BsPrefabDiff.h"
  12. namespace bs
  13. {
  14. /** @cond RTTI */
  15. /** @addtogroup RTTI-Impl-Core
  16. * @{
  17. */
  18. /** Provides temporary storage for data used during SceneObject deserialization. */
  19. struct SODeserializationData
  20. {
  21. Vector<SPtr<SceneObject>> children;
  22. Vector<SPtr<Component>> components;
  23. };
  24. class BS_CORE_EXPORT SceneObjectRTTI : public RTTIType<SceneObject, GameObject, SceneObjectRTTI>
  25. {
  26. private:
  27. Transform& getTransform(SceneObject* obj) { return obj->mWorldTfrm; }
  28. void setTransform(SceneObject* obj, Transform& value) { obj->mWorldTfrm = value; }
  29. Transform& getLocalTransform(SceneObject* obj) { return obj->mLocalTfrm; }
  30. void setLocalTransform(SceneObject* obj, Transform& value) { obj->mLocalTfrm = value; }
  31. bool& getActive(SceneObject* obj) { return obj->mActiveSelf; }
  32. void setActive(SceneObject* obj, bool& value) { obj->mActiveSelf = value; }
  33. SPtr<SceneObject> getChild(SceneObject* obj, UINT32 idx) { return obj->mChildren[idx].getInternalPtr(); }
  34. void setChild(SceneObject* obj, UINT32 idx, SPtr<SceneObject> param)
  35. {
  36. SceneObject* so = static_cast<SceneObject*>(obj);
  37. GODeserializationData& goDeserializationData = any_cast_ref<GODeserializationData>(so->mRTTIData);
  38. SODeserializationData& soDeserializationData = any_cast_ref<SODeserializationData>(goDeserializationData.moreData);
  39. // It's important that child indices remain the same after deserialization, as some systems (like SO
  40. // record/restore) depend on it
  41. if(idx >= soDeserializationData.children.size())
  42. soDeserializationData.children.resize(idx + 1);
  43. soDeserializationData.children[idx] = param;
  44. }
  45. UINT32 getNumChildren(SceneObject* obj) { return (UINT32)obj->mChildren.size(); }
  46. void setNumChildren(SceneObject* obj, UINT32 size) { /* DO NOTHING */ }
  47. // NOTE - These can only be set sequentially, specific array index is ignored
  48. SPtr<Component> getComponent(SceneObject* obj, UINT32 idx) { return obj->mComponents[idx].getInternalPtr(); }
  49. void setComponent(SceneObject* obj, UINT32 idx, SPtr<Component> param)
  50. {
  51. SceneObject* so = static_cast<SceneObject*>(obj);
  52. GODeserializationData& goDeserializationData = any_cast_ref<GODeserializationData>(so->mRTTIData);
  53. SODeserializationData& soDeserializationData = any_cast_ref<SODeserializationData>(goDeserializationData.moreData);
  54. // It's important that child indices remain the same after deserialization, as some systems (like SO
  55. // record/restore) depend on it
  56. if(idx >= soDeserializationData.components.size())
  57. soDeserializationData.components.resize(idx + 1);
  58. soDeserializationData.components[idx] = param;
  59. }
  60. UINT32 getNumComponents(SceneObject* obj) { return (UINT32)obj->mComponents.size(); }
  61. void setNumComponents(SceneObject* obj, UINT32 size) { /* DO NOTHING */ }
  62. UUID& getPrefabLink(SceneObject* obj) { return obj->mPrefabLinkUUID; }
  63. void setPrefabLink(SceneObject* obj, UUID& value) { obj->mPrefabLinkUUID = value; }
  64. SPtr<PrefabDiff> getPrefabDiff(SceneObject* obj) { return obj->mPrefabDiff; }
  65. void setPrefabDiff(SceneObject* obj, SPtr<PrefabDiff> value) { obj->mPrefabDiff = value; }
  66. UINT32& getFlags(SceneObject* obj) { return obj->mFlags; }
  67. void setFlags(SceneObject* obj, UINT32& value) { obj->mFlags = value; }
  68. UINT32& getPrefabHash(SceneObject* obj) { return obj->mPrefabHash; }
  69. void setPrefabHash(SceneObject* obj, UINT32& value) { obj->mPrefabHash = value; }
  70. ObjectMobility& getMobility(SceneObject* obj) { return obj->mMobility; }
  71. void setMobility(SceneObject* obj, ObjectMobility& value) { obj->mMobility = value; }
  72. public:
  73. SceneObjectRTTI()
  74. {
  75. addReflectablePtrArrayField("mChildren", 0, &SceneObjectRTTI::getChild,
  76. &SceneObjectRTTI::getNumChildren, &SceneObjectRTTI::setChild, &SceneObjectRTTI::setNumChildren);
  77. addReflectablePtrArrayField("mComponents", 1, &SceneObjectRTTI::getComponent,
  78. &SceneObjectRTTI::getNumComponents, &SceneObjectRTTI::setComponent, &SceneObjectRTTI::setNumComponents);
  79. addPlainField("mPrefabLink", 2, &SceneObjectRTTI::getPrefabLink, &SceneObjectRTTI::setPrefabLink);
  80. addPlainField("mFlags", 3, &SceneObjectRTTI::getFlags, &SceneObjectRTTI::setFlags);
  81. addReflectablePtrField("mPrefabDiff", 4, &SceneObjectRTTI::getPrefabDiff, &SceneObjectRTTI::setPrefabDiff);
  82. addPlainField("mPrefabHash", 5, &SceneObjectRTTI::getPrefabHash, &SceneObjectRTTI::setPrefabHash);
  83. addPlainField("mActiveSelf", 9, &SceneObjectRTTI::getActive, &SceneObjectRTTI::setActive);
  84. addPlainField("mMobility", 10, &SceneObjectRTTI::getMobility, &SceneObjectRTTI::setMobility);
  85. addReflectableField("mWorldTfrm", 11, &SceneObjectRTTI::getTransform, &SceneObjectRTTI::setTransform);
  86. addReflectableField("mLocalTfrm", 12, &SceneObjectRTTI::getLocalTransform, &SceneObjectRTTI::setLocalTransform);
  87. }
  88. void onDeserializationStarted(IReflectable* obj, const UnorderedMap<String, UINT64>& params) override
  89. {
  90. // If this is the root scene object we're deserializing, activate game object deserialization so the system
  91. // can resolve deserialized handles to the newly created objects
  92. SceneObject* so = static_cast<SceneObject*>(obj);
  93. // It's possible we're just accessing the game object fields, in which case the process below is not needed
  94. // (it's only required for new scene objects).
  95. if (so->mRTTIData.empty())
  96. return;
  97. // Every GameObject must store GODeserializationData in its RTTI data field during deserialization
  98. GODeserializationData& deserializationData = any_cast_ref<GODeserializationData>(so->mRTTIData);
  99. // We delay adding children/components and instead store them here
  100. deserializationData.moreData = SODeserializationData();
  101. if (!GameObjectManager::instance().isGameObjectDeserializationActive())
  102. {
  103. GameObjectManager::instance().startDeserialization();
  104. // Mark it as the object that started the GO deserialization so it knows to end it
  105. deserializationData.isDeserializationParent = true;
  106. }
  107. else
  108. deserializationData.isDeserializationParent = false;
  109. }
  110. void onDeserializationEnded(IReflectable* obj, const UnorderedMap<String, UINT64>& params) override
  111. {
  112. SceneObject* so = static_cast<SceneObject*>(obj);
  113. // It's possible we're just accessing the game object fields, in which case the process below is not needed
  114. // (it's only required for new scene objects).
  115. if (so->mRTTIData.empty())
  116. return;
  117. GODeserializationData& goDeserializationData = any_cast_ref<GODeserializationData>(so->mRTTIData);
  118. // Register the newly created SO with the GameObjectManager and provide it with the original ID so that
  119. // deserialized handles pointing to this object can be resolved.
  120. SPtr<SceneObject> soPtr = std::static_pointer_cast<SceneObject>(goDeserializationData.ptr);
  121. SceneObject::createInternal(soPtr, goDeserializationData.originalId);
  122. // We stored all components and children in a temporary structure because they rely on the SceneObject being
  123. // initialized with the GameObjectManager. Now that it is, we add them.
  124. SODeserializationData& soDeserializationData = any_cast_ref<SODeserializationData>(goDeserializationData.moreData);
  125. for (auto& component : soDeserializationData.components)
  126. so->addComponentInternal(component);
  127. for (auto& child : soDeserializationData.children)
  128. {
  129. if(child != nullptr)
  130. child->_setParent(so->mThisHandle, false);
  131. }
  132. // If this is the deserialization parent, end deserialization (which resolves all game object handles, if we
  133. // provided valid IDs), and instantiate (i.e. activate) the deserialized hierarchy.
  134. if (goDeserializationData.isDeserializationParent)
  135. {
  136. GameObjectManager::instance().endDeserialization();
  137. bool parentActive = true;
  138. if (so->getParent() != nullptr)
  139. parentActive = so->getParent()->getActive();
  140. so->setActiveHierarchy(parentActive, false);
  141. if ((so->mFlags & SOF_DontInstantiate) == 0)
  142. so->_instantiate();
  143. }
  144. so->mRTTIData = nullptr;
  145. }
  146. const String& getRTTIName() override
  147. {
  148. static String name = "SceneObject";
  149. return name;
  150. }
  151. UINT32 getRTTIId() override
  152. {
  153. return TID_SceneObject;
  154. }
  155. SPtr<IReflectable> newRTTIObject() override
  156. {
  157. SPtr<SceneObject> sceneObject = SPtr<SceneObject>(new (bs_alloc<SceneObject>()) SceneObject("", SOF_DontInstantiate),
  158. &bs_delete<SceneObject>, StdAlloc<SceneObject>());
  159. sceneObject->mRTTIData = sceneObject;
  160. return sceneObject;
  161. }
  162. };
  163. /** @} */
  164. /** @endcond */
  165. }