BsSceneObjectRTTI.h 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. #pragma once
  2. #include "BsCorePrerequisites.h"
  3. #include "BsRTTIType.h"
  4. #include "BsSceneObject.h"
  5. #include "BsGameObjectHandle.h"
  6. #include "BsGameObjectManager.h"
  7. #include "BsComponent.h"
  8. #include "BsGameObjectRTTI.h"
  9. #include "BsPrefabDiff.h"
  10. namespace BansheeEngine
  11. {
  12. /** @cond RTTI */
  13. /** @addtogroup RTTI-Impl-Core
  14. * @{
  15. */
  16. /** Provides temporary storage for data used during SceneObject deserialization. */
  17. struct SODeserializationData
  18. {
  19. Vector<SPtr<SceneObject>> children;
  20. Vector<SPtr<Component>> components;
  21. };
  22. class BS_CORE_EXPORT SceneObjectRTTI : public RTTIType<SceneObject, GameObject, SceneObjectRTTI>
  23. {
  24. private:
  25. Vector3& getPosition(SceneObject* obj) { return obj->mPosition; }
  26. void setPosition(SceneObject* obj, Vector3& value) { obj->mPosition = value; }
  27. Quaternion& getRotation(SceneObject* obj) { return obj->mRotation; }
  28. void setRotation(SceneObject* obj, Quaternion& value) { obj->mRotation = value; }
  29. Vector3& getScale(SceneObject* obj) { return obj->mScale; }
  30. void setScale(SceneObject* obj, Vector3& value) { obj->mScale = value; }
  31. bool& getActive(SceneObject* obj) { return obj->mActiveSelf; }
  32. void setActive(SceneObject* obj, bool& value) { obj->mActiveSelf = value; }
  33. // NOTE - These can only be set sequentially, specific array index is ignored
  34. std::shared_ptr<SceneObject> getChild(SceneObject* obj, UINT32 idx) { return obj->mChildren[idx].getInternalPtr(); }
  35. void setChild(SceneObject* obj, UINT32 idx, SPtr<SceneObject> param)
  36. {
  37. SceneObject* so = static_cast<SceneObject*>(obj);
  38. GODeserializationData& goDeserializationData = any_cast_ref<GODeserializationData>(so->mRTTIData);
  39. SODeserializationData& soDeserializationData = any_cast_ref<SODeserializationData>(goDeserializationData.moreData);
  40. soDeserializationData.children.push_back(param);
  41. }
  42. UINT32 getNumChildren(SceneObject* obj) { return (UINT32)obj->mChildren.size(); }
  43. void setNumChildren(SceneObject* obj, UINT32 size) { /* DO NOTHING */ }
  44. // NOTE - These can only be set sequentially, specific array index is ignored
  45. std::shared_ptr<Component> getComponent(SceneObject* obj, UINT32 idx) { return obj->mComponents[idx].getInternalPtr(); }
  46. void setComponent(SceneObject* obj, UINT32 idx, SPtr<Component> param)
  47. {
  48. SceneObject* so = static_cast<SceneObject*>(obj);
  49. GODeserializationData& goDeserializationData = any_cast_ref<GODeserializationData>(so->mRTTIData);
  50. SODeserializationData& soDeserializationData = any_cast_ref<SODeserializationData>(goDeserializationData.moreData);
  51. soDeserializationData.components.push_back(param);
  52. }
  53. UINT32 getNumComponents(SceneObject* obj) { return (UINT32)obj->mComponents.size(); }
  54. void setNumComponents(SceneObject* obj, UINT32 size) { /* DO NOTHING */ }
  55. String& getPrefabLink(SceneObject* obj) { return obj->mPrefabLinkUUID; }
  56. void setPrefabLink(SceneObject* obj, String& value) { obj->mPrefabLinkUUID = value; }
  57. PrefabDiffPtr getPrefabDiff(SceneObject* obj) { return obj->mPrefabDiff; }
  58. void setPrefabDiff(SceneObject* obj, PrefabDiffPtr value) { obj->mPrefabDiff = value; }
  59. UINT32& getFlags(SceneObject* obj) { return obj->mFlags; }
  60. void setFlags(SceneObject* obj, UINT32& value) { obj->mFlags = value; }
  61. UINT32& getPrefabHash(SceneObject* obj) { return obj->mPrefabHash; }
  62. void setPrefabHash(SceneObject* obj, UINT32& value) { obj->mPrefabHash = value; }
  63. public:
  64. SceneObjectRTTI()
  65. {
  66. addReflectablePtrArrayField("mChildren", 0, &SceneObjectRTTI::getChild,
  67. &SceneObjectRTTI::getNumChildren, &SceneObjectRTTI::setChild, &SceneObjectRTTI::setNumChildren);
  68. addReflectablePtrArrayField("mComponents", 1, &SceneObjectRTTI::getComponent,
  69. &SceneObjectRTTI::getNumComponents, &SceneObjectRTTI::setComponent, &SceneObjectRTTI::setNumComponents);
  70. addPlainField("mPrefabLink", 2, &SceneObjectRTTI::getPrefabLink, &SceneObjectRTTI::setPrefabLink);
  71. addPlainField("mFlags", 3, &SceneObjectRTTI::getFlags, &SceneObjectRTTI::setFlags);
  72. addReflectablePtrField("mPrefabDiff", 4, &SceneObjectRTTI::getPrefabDiff, &SceneObjectRTTI::setPrefabDiff);
  73. addPlainField("mPrefabHash", 5, &SceneObjectRTTI::getPrefabHash, &SceneObjectRTTI::setPrefabHash);
  74. addPlainField("mPosition", 6, &SceneObjectRTTI::getPosition, &SceneObjectRTTI::setPosition);
  75. addPlainField("mRotation", 7, &SceneObjectRTTI::getRotation, &SceneObjectRTTI::setRotation);
  76. addPlainField("mScale", 8, &SceneObjectRTTI::getScale, &SceneObjectRTTI::setScale);
  77. addPlainField("mActiveSelf", 9, &SceneObjectRTTI::getActive, &SceneObjectRTTI::setActive);
  78. }
  79. void onDeserializationStarted(IReflectable* obj) override
  80. {
  81. // If this is the root scene object we're deserializing, activate game object deserialization so the system
  82. // can resolve deserialized handles to the newly created objects
  83. SceneObject* so = static_cast<SceneObject*>(obj);
  84. GODeserializationData& deserializationData = any_cast_ref<GODeserializationData>(so->mRTTIData);
  85. if (!GameObjectManager::instance().isGameObjectDeserializationActive())
  86. {
  87. GameObjectManager::instance().startDeserialization();
  88. // Mark it as the object that started the GO deserialization so it knows to end it
  89. deserializationData.isDeserializationParent = true;
  90. }
  91. else
  92. deserializationData.isDeserializationParent = false;
  93. }
  94. void onDeserializationEnded(IReflectable* obj) override
  95. {
  96. SceneObject* so = static_cast<SceneObject*>(obj);
  97. GODeserializationData& goDeserializationData = any_cast_ref<GODeserializationData>(so->mRTTIData);
  98. // Register the newly created SO with the GameObjectManager and provide it with the original ID so that
  99. // deserialized handles pointing to this object can be resolved.
  100. SceneObjectPtr soPtr = std::static_pointer_cast<SceneObject>(goDeserializationData.ptr);
  101. SceneObject::createInternal(soPtr, goDeserializationData.originalId);
  102. // We stored all components and children in a temporary structure because they rely on the SceneObject being
  103. // initialized with the GameObjectManager. Now that it is, we add them.
  104. SODeserializationData& soDeserializationData = any_cast_ref<SODeserializationData>(goDeserializationData.moreData);
  105. for (auto& component : soDeserializationData.components)
  106. so->addComponentInternal(component);
  107. for (auto& child : soDeserializationData.children)
  108. child->_setParent(so->mThisHandle);
  109. // If this is the deserialization parent, end deserialization (which resolves all game object handles, if we
  110. // provided valid IDs), and instantiate (i.e. activate) the deserialized hierarchy.
  111. if (goDeserializationData.isDeserializationParent)
  112. {
  113. GameObjectManager::instance().endDeserialization();
  114. if ((so->mFlags & SOF_DontInstantiate) == 0)
  115. so->_instantiate();
  116. }
  117. so->mRTTIData = nullptr;
  118. }
  119. const String& getRTTIName() override
  120. {
  121. static String name = "SceneObject";
  122. return name;
  123. }
  124. UINT32 getRTTIId() override
  125. {
  126. return TID_SceneObject;
  127. }
  128. std::shared_ptr<IReflectable> newRTTIObject() override
  129. {
  130. SPtr<SceneObject> sceneObjectPtr =
  131. SPtr<SceneObject>(new (bs_alloc<SceneObject>()) SceneObject("", SOF_DontInstantiate),
  132. &bs_delete<SceneObject>, StdAlloc<SceneObject>());
  133. // Every GameObject must store GODeserializationData in its RTTI data field during deserialization
  134. sceneObjectPtr->mRTTIData = GODeserializationData();
  135. GODeserializationData& deserializationData = any_cast_ref<GODeserializationData>(sceneObjectPtr->mRTTIData);
  136. // Store shared pointer since the system only provides us with raw ones
  137. deserializationData.ptr = sceneObjectPtr;
  138. // We delay adding children/components and instead store them here
  139. deserializationData.moreData = SODeserializationData();
  140. return sceneObjectPtr;
  141. }
  142. };
  143. /** @} */
  144. /** @endcond */
  145. }