BsGameObjectRTTI.h 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. #pragma once
  2. #include "BsCorePrerequisites.h"
  3. #include "BsRTTIType.h"
  4. #include "BsGameObject.h"
  5. #include "BsSceneObject.h"
  6. #include "BsGameObjectManager.h"
  7. namespace BansheeEngine
  8. {
  9. /**
  10. * @brief Provides temporary storage for data used during GameObject deserialization.
  11. */
  12. struct GODeserializationData
  13. {
  14. GODeserializationData()
  15. :isDeserializationParent(false), originalId(0)
  16. { }
  17. GameObjectPtr ptr;
  18. bool isDeserializationParent;
  19. UINT64 originalId;
  20. Any moreData;
  21. };
  22. class BS_CORE_EXPORT GameObjectRTTI : public RTTIType<GameObject, IReflectable, GameObjectRTTI>
  23. {
  24. private:
  25. String& getName(GameObject* obj) { return obj->mName; }
  26. void setName(GameObject* obj, String& name) { obj->mName = name; }
  27. UINT64& getInstanceID(GameObject* obj) { return obj->mInstanceData->mInstanceId; }
  28. void setInstanceID(GameObject* obj, UINT64& instanceId)
  29. {
  30. // We record the ID for later use. Any child RTTI of GameObject must call GameObjectManager::registerObject
  31. // with this ID, so we know how to map deserialized GO handles to live objects, otherwise the handle
  32. // references will get broken.
  33. GameObject* go = static_cast<GameObject*>(obj);
  34. GODeserializationData& deserializationData = any_cast_ref<GODeserializationData>(go->mRTTIData);
  35. deserializationData.originalId = instanceId;
  36. }
  37. UINT32& getLinkId(GameObject* obj) { return obj->mLinkId; }
  38. void setLinkId(GameObject* obj, UINT32& linkId) { obj->mLinkId = linkId; }
  39. public:
  40. /**
  41. * @brief Helper method used for creating Component objects used during deserialization.
  42. */
  43. template <typename T>
  44. static std::shared_ptr<T> createGameObject()
  45. {
  46. SPtr<T> component = SceneObject::createEmptyComponent<T>();
  47. // Every GameObject must store GODeserializationData in its RTTI data field during deserialization
  48. component->mRTTIData = GODeserializationData();
  49. GODeserializationData& deserializationData = any_cast_ref<GODeserializationData>(component->mRTTIData);
  50. // Store shared pointer since the system only provides us with raw ones
  51. deserializationData.ptr = component;
  52. return component;
  53. }
  54. public:
  55. GameObjectRTTI()
  56. {
  57. addPlainField("mInstanceID", 0, &GameObjectRTTI::getInstanceID, &GameObjectRTTI::setInstanceID);
  58. addPlainField("mName", 1, &GameObjectRTTI::getName, &GameObjectRTTI::setName);
  59. addPlainField("mLinkId", 2, &GameObjectRTTI::getLinkId, &GameObjectRTTI::setLinkId);
  60. }
  61. virtual const String& getRTTIName() override
  62. {
  63. static String name = "GameObject";
  64. return name;
  65. }
  66. virtual UINT32 getRTTIId() override
  67. {
  68. return TID_GameObject;
  69. }
  70. virtual std::shared_ptr<IReflectable> newRTTIObject() override
  71. {
  72. BS_EXCEPT(InternalErrorException, "Cannot instantiate an abstract class.");
  73. }
  74. };
  75. }