BsManagedComponent.cpp 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  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)
  12. { }
  13. ManagedComponent::ManagedComponent(const HSceneObject& parent, MonoReflectionType* runtimeType)
  14. :Component(parent), mManagedInstance(nullptr), mRuntimeType(runtimeType), mUpdateThunk(nullptr)
  15. {
  16. MonoType* monoType = mono_reflection_type_get_type(mRuntimeType);
  17. ::MonoClass* monoClass = mono_type_get_class(monoType);
  18. mNamespace = mono_class_get_namespace(monoClass);
  19. mTypeName = mono_class_get_name(monoClass);
  20. MonoClass* managedClass = MonoManager::instance().findClass(mNamespace, mTypeName);
  21. if(managedClass == nullptr)
  22. {
  23. LOGWRN("Cannot create managed component: " + mNamespace + "." + mTypeName + " because that type doesn't exist.");
  24. return;
  25. }
  26. setName(mTypeName);
  27. construct(managedClass->createInstance(), runtimeType, managedClass);
  28. }
  29. void ManagedComponent::construct(MonoObject* object, MonoReflectionType* runtimeType, MonoClass* monoClass)
  30. {
  31. mFullTypeName = mNamespace + "." + mTypeName;
  32. mManagedInstance = object;
  33. mRuntimeType = runtimeType;
  34. mManagedHandle = mono_gchandle_new(mManagedInstance, false);
  35. if (monoClass != nullptr)
  36. {
  37. MonoMethod* updateMethod = monoClass->getMethod("Update", 0);
  38. if (updateMethod != nullptr)
  39. mUpdateThunk = (UpdateThunkDef)updateMethod->getThunk();
  40. }
  41. }
  42. void ManagedComponent::update()
  43. {
  44. if (mUpdateThunk != nullptr && mManagedInstance != nullptr)
  45. {
  46. MonoException* exception = nullptr;
  47. // Note: Not calling virtual methods. Can be easily done if needed but for now doing this
  48. // for some extra speed.
  49. mUpdateThunk(mManagedInstance, &exception);
  50. MonoUtil::throwIfException(exception);
  51. }
  52. }
  53. void ManagedComponent::onDestroyed()
  54. {
  55. if(mManagedInstance != nullptr)
  56. {
  57. mManagedInstance = nullptr;
  58. mono_gchandle_free(mManagedHandle);
  59. }
  60. }
  61. RTTITypeBase* ManagedComponent::getRTTIStatic()
  62. {
  63. return ManagedComponentRTTI::instance();
  64. }
  65. RTTITypeBase* ManagedComponent::getRTTI() const
  66. {
  67. return ManagedComponent::getRTTIStatic();
  68. }
  69. }