BsManagedComponent.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. #include "BsManagedComponent.h"
  2. #include "BsManagedComponentRTTI.h"
  3. #include "BsMonoManager.h"
  4. #include "BsMonoClass.h"
  5. #include "BsMonoUtil.h"
  6. #include "BsMonoMethod.h"
  7. #include "BsDebug.h"
  8. namespace BansheeEngine
  9. {
  10. ManagedComponent::ManagedComponent()
  11. :mUpdateThunk(nullptr), mOnDestroyThunk(nullptr), mOnInitializedThunk(nullptr)
  12. { }
  13. ManagedComponent::ManagedComponent(const HSceneObject& parent, MonoReflectionType* runtimeType)
  14. : Component(parent), mManagedInstance(nullptr), mRuntimeType(runtimeType), mUpdateThunk(nullptr),
  15. mOnDestroyThunk(nullptr), mOnInitializedThunk(nullptr)
  16. {
  17. MonoType* monoType = mono_reflection_type_get_type(mRuntimeType);
  18. ::MonoClass* monoClass = mono_type_get_class(monoType);
  19. mNamespace = mono_class_get_namespace(monoClass);
  20. mTypeName = mono_class_get_name(monoClass);
  21. MonoClass* managedClass = MonoManager::instance().findClass(mNamespace, mTypeName);
  22. if(managedClass == nullptr)
  23. {
  24. LOGWRN("Cannot create managed component: " + mNamespace + "." + mTypeName + " because that type doesn't exist.");
  25. return;
  26. }
  27. setName(mTypeName);
  28. initialize(managedClass->createInstance(), runtimeType, managedClass);
  29. }
  30. ManagedComponent::~ManagedComponent()
  31. {
  32. if (mManagedInstance != nullptr)
  33. {
  34. mManagedInstance = nullptr;
  35. mono_gchandle_free(mManagedHandle);
  36. }
  37. }
  38. void ManagedComponent::initialize(MonoObject* object, MonoReflectionType* runtimeType, MonoClass* monoClass)
  39. {
  40. mFullTypeName = mNamespace + "." + mTypeName;
  41. mManagedInstance = object;
  42. mRuntimeType = runtimeType;
  43. mManagedHandle = mono_gchandle_new(mManagedInstance, false);
  44. if (monoClass != nullptr)
  45. {
  46. MonoMethod* onInitializedMethod = monoClass->getMethod("OnInitialize", 0);
  47. if (onInitializedMethod != nullptr)
  48. mOnInitializedThunk = (OnInitializedThunkDef)onInitializedMethod->getThunk();
  49. MonoMethod* updateMethod = monoClass->getMethod("Update", 0);
  50. if (updateMethod != nullptr)
  51. mUpdateThunk = (UpdateThunkDef)updateMethod->getThunk();
  52. MonoMethod* onDestroyMethod = monoClass->getMethod("OnDestroy", 0);
  53. if (onDestroyMethod != nullptr)
  54. mOnDestroyThunk = (OnDestroyedThunkDef)onDestroyMethod->getThunk();
  55. }
  56. }
  57. void ManagedComponent::update()
  58. {
  59. if (mUpdateThunk != nullptr && mManagedInstance != nullptr)
  60. {
  61. MonoException* exception = nullptr;
  62. // Note: Not calling virtual methods. Can be easily done if needed but for now doing this
  63. // for some extra speed.
  64. mUpdateThunk(mManagedInstance, &exception);
  65. MonoUtil::throwIfException(exception);
  66. }
  67. }
  68. void ManagedComponent::onInitialized()
  69. {
  70. assert(mManagedInstance != nullptr);
  71. ScriptComponent* nativeInstance = ScriptComponent::toNative(mManagedInstance);
  72. // Find handle to self
  73. HManagedComponent componentHandle;
  74. if (mParent != nullptr)
  75. {
  76. const Vector<HComponent>& components = mParent->getComponents();
  77. for (auto& component : components)
  78. {
  79. if (component.get() == this)
  80. {
  81. componentHandle = component;
  82. break;
  83. }
  84. }
  85. }
  86. assert(componentHandle != nullptr);
  87. ScriptGameObjectManager::instance().registerScriptComponent(nativeInstance, componentHandle);
  88. if (mOnInitializedThunk != nullptr)
  89. {
  90. MonoException* exception = nullptr;
  91. // Note: Not calling virtual methods. Can be easily done if needed but for now doing this
  92. // for some extra speed.
  93. mOnInitializedThunk(mManagedInstance, &exception);
  94. MonoUtil::throwIfException(exception);
  95. }
  96. }
  97. void ManagedComponent::onDestroyed()
  98. {
  99. assert(mManagedInstance != nullptr);
  100. if (mOnDestroyThunk != nullptr)
  101. {
  102. MonoException* exception = nullptr;
  103. // Note: Not calling virtual methods. Can be easily done if needed but for now doing this
  104. // for some extra speed.
  105. mOnDestroyThunk(mManagedInstance, &exception);
  106. MonoUtil::throwIfException(exception);
  107. }
  108. }
  109. RTTITypeBase* ManagedComponent::getRTTIStatic()
  110. {
  111. return ManagedComponentRTTI::instance();
  112. }
  113. RTTITypeBase* ManagedComponent::getRTTI() const
  114. {
  115. return ManagedComponent::getRTTIStatic();
  116. }
  117. }