BsMonoProperty.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "BsMonoProperty.h"
  4. #include "BsMonoMethod.h"
  5. #include "BsMonoManager.h"
  6. #include "BsMonoClass.h"
  7. #include <mono/jit/jit.h>
  8. #include <mono/metadata/class.h>
  9. namespace bs
  10. {
  11. MonoProperty::MonoProperty(::MonoProperty* monoProp)
  12. :mProperty(monoProp), mReturnType(nullptr), mIsIndexed(false), mIsFullyInitialized(false)
  13. {
  14. mGetMethod = mono_property_get_get_method(mProperty);
  15. mSetMethod = mono_property_get_set_method(mProperty);
  16. mName = mono_property_get_name(mProperty);
  17. }
  18. MonoObject* MonoProperty::get(MonoObject* instance) const
  19. {
  20. if (mGetMethod == nullptr)
  21. return nullptr;
  22. return mono_runtime_invoke(mGetMethod, instance, nullptr, nullptr);
  23. }
  24. void MonoProperty::set(MonoObject* instance, void* value) const
  25. {
  26. if (mSetMethod == nullptr)
  27. return;
  28. void* args[1];
  29. args[0] = value;
  30. mono_runtime_invoke(mSetMethod, instance, args, nullptr);
  31. }
  32. MonoObject* MonoProperty::getIndexed(MonoObject* instance, UINT32 index) const
  33. {
  34. void* args[1];
  35. args[0] = &index;
  36. return mono_runtime_invoke(mGetMethod, instance, args, nullptr);
  37. }
  38. void MonoProperty::setIndexed(MonoObject* instance, UINT32 index, void* value) const
  39. {
  40. void* args[2];
  41. args[0] = &index;
  42. args[1] = value;
  43. mono_runtime_invoke(mSetMethod, instance, args, nullptr);
  44. }
  45. bool MonoProperty::isIndexed() const
  46. {
  47. if (!mIsFullyInitialized)
  48. initializeDeferred();
  49. return mIsIndexed;
  50. }
  51. MonoClass* MonoProperty::getReturnType() const
  52. {
  53. if (!mIsFullyInitialized)
  54. initializeDeferred();
  55. return mReturnType;
  56. }
  57. bool MonoProperty::hasAttribute(MonoClass* monoClass)
  58. {
  59. // TODO - Consider caching custom attributes or just initializing them all at load
  60. ::MonoClass* parentClass = mono_property_get_parent(mProperty);
  61. MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_property(parentClass, mProperty);
  62. if (attrInfo == nullptr)
  63. return false;
  64. bool hasAttr = mono_custom_attrs_has_attr(attrInfo, monoClass->_getInternalClass()) != 0;
  65. mono_custom_attrs_free(attrInfo);
  66. return hasAttr;
  67. }
  68. MonoObject* MonoProperty::getAttribute(MonoClass* monoClass)
  69. {
  70. // TODO - Consider caching custom attributes or just initializing them all at load
  71. ::MonoClass* parentClass = mono_property_get_parent(mProperty);
  72. MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_property(parentClass, mProperty);
  73. if (attrInfo == nullptr)
  74. return nullptr;
  75. MonoObject* foundAttr = mono_custom_attrs_get_attr(attrInfo, monoClass->_getInternalClass());
  76. mono_custom_attrs_free(attrInfo);
  77. return foundAttr;
  78. }
  79. MonoMemberVisibility MonoProperty::getVisibility()
  80. {
  81. MonoMemberVisibility getterVisibility = MonoMemberVisibility::Public;
  82. if(mGetMethod)
  83. {
  84. MonoMethod getterWrapper(mGetMethod);
  85. getterVisibility = getterWrapper.getVisibility();
  86. }
  87. MonoMemberVisibility setterVisibility = MonoMemberVisibility::Public;
  88. if (mSetMethod)
  89. {
  90. MonoMethod setterWrapper(mSetMethod);
  91. setterVisibility = setterWrapper.getVisibility();
  92. }
  93. if (getterVisibility < setterVisibility)
  94. return getterVisibility;
  95. return setterVisibility;
  96. }
  97. void MonoProperty::initializeDeferred() const
  98. {
  99. if (mGetMethod != nullptr)
  100. {
  101. MonoMethodSignature* signature = mono_method_signature(mGetMethod);
  102. MonoType* returnType = mono_signature_get_return_type(signature);
  103. if (returnType != nullptr)
  104. {
  105. ::MonoClass* returnClass = mono_class_from_mono_type(returnType);
  106. if (returnClass != nullptr)
  107. mReturnType = MonoManager::instance().findClass(returnClass);
  108. }
  109. UINT32 numParams = mono_signature_get_param_count(signature);
  110. mIsIndexed = numParams == 1;
  111. }
  112. else if(mSetMethod != nullptr)
  113. {
  114. MonoMethodSignature* signature = mono_method_signature(mSetMethod);
  115. MonoType* returnType = mono_signature_get_return_type(signature);
  116. if (returnType != nullptr)
  117. {
  118. ::MonoClass* returnClass = mono_class_from_mono_type(returnType);
  119. if (returnClass != nullptr)
  120. mReturnType = MonoManager::instance().findClass(returnClass);
  121. }
  122. UINT32 numParams = mono_signature_get_param_count(signature);
  123. mIsIndexed = numParams == 2;
  124. }
  125. mIsFullyInitialized = true;
  126. }
  127. }