Files
FlaxEngine/Source/Engine/Scripting/ManagedCLR/MProperty.Mono.cpp
2021-01-02 14:28:49 +01:00

188 lines
4.8 KiB
C++

// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
#include "MProperty.h"
#if USE_MONO
#include "Engine/Core/Math/Math.h"
#include "MMethod.h"
#include "MClass.h"
#include "MType.h"
#include <ThirdParty/mono-2.0/mono/metadata/mono-debug.h>
MProperty::MProperty(MonoProperty* monoProperty, const char* name, MClass* parentClass)
: _monoProperty(monoProperty)
, _getMethod(nullptr)
, _setMethod(nullptr)
, _parentClass(parentClass)
, _name(name)
, _hasCachedAttributes(false)
, _hasSetMethod(true)
, _hasGetMethod(true)
{
#if BUILD_DEBUG
// Validate input name
ASSERT(StringUtils::Compare(name, mono_property_get_name(monoProperty)) == 0);
#endif
GetGetMethod();
GetSetMethod();
}
MProperty::~MProperty()
{
if (_getMethod)
Delete(_getMethod);
if (_setMethod)
Delete(_setMethod);
}
MType MProperty::GetType()
{
if (GetGetMethod() != nullptr)
return GetGetMethod()->GetReturnType();
return GetSetMethod()->GetReturnType();
}
MMethod* MProperty::GetGetMethod()
{
if (!_hasGetMethod)
return nullptr;
if (_getMethod == nullptr)
{
auto method = mono_property_get_get_method(_monoProperty);
if (method != nullptr)
{
_hasGetMethod = true;
return _getMethod = New<MMethod>(method, _parentClass);
}
return nullptr;
}
return _getMethod;
}
MMethod* MProperty::GetSetMethod()
{
if (!_hasSetMethod)
return nullptr;
if (_setMethod == nullptr)
{
auto method = mono_property_get_set_method(_monoProperty);
if (method != nullptr)
{
_hasSetMethod = true;
return _setMethod = New<MMethod>(method, _parentClass);
}
return nullptr;
}
return _setMethod;
}
MVisibility MProperty::GetVisibility()
{
if (GetGetMethod() && GetSetMethod())
{
return static_cast<MVisibility>(
Math::Max(
static_cast<int>(GetGetMethod()->GetVisibility()),
static_cast<int>(GetSetMethod()->GetVisibility())
));
}
if (GetGetMethod())
{
return GetGetMethod()->GetVisibility();
}
return GetSetMethod()->GetVisibility();
}
bool MProperty::IsStatic()
{
if (GetGetMethod())
{
return GetGetMethod()->IsStatic();
}
if (GetSetMethod())
{
return GetSetMethod()->IsStatic();
}
return false;
}
MonoObject* MProperty::GetValue(MonoObject* instance, MonoObject** exception)
{
return mono_property_get_value(_monoProperty, instance, nullptr, exception);
}
void MProperty::SetValue(MonoObject* instance, void* value, MonoObject** exception)
{
void* params[1];
params[0] = value;
mono_property_set_value(_monoProperty, instance, params, exception);
}
bool MProperty::HasAttribute(MClass* monoClass) const
{
MonoClass* parentClass = mono_property_get_parent(_monoProperty);
MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_property(parentClass, _monoProperty);
if (attrInfo == nullptr)
return false;
const bool hasAttr = mono_custom_attrs_has_attr(attrInfo, monoClass->GetNative()) != 0;
mono_custom_attrs_free(attrInfo);
return hasAttr;
}
bool MProperty::HasAttribute() const
{
MonoClass* parentClass = mono_property_get_parent(_monoProperty);
MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_property(parentClass, _monoProperty);
if (attrInfo == nullptr)
return false;
if (attrInfo->num_attrs > 0)
{
mono_custom_attrs_free(attrInfo);
return true;
}
mono_custom_attrs_free(attrInfo);
return false;
}
MonoObject* MProperty::GetAttribute(MClass* monoClass) const
{
MonoClass* parentClass = mono_property_get_parent(_monoProperty);
MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_property(parentClass, _monoProperty);
if (attrInfo == nullptr)
return nullptr;
MonoObject* foundAttr = mono_custom_attrs_get_attr(attrInfo, monoClass->GetNative());
mono_custom_attrs_free(attrInfo);
return foundAttr;
}
const Array<MonoObject*>& MProperty::GetAttributes()
{
if (_hasCachedAttributes)
return _attributes;
_hasCachedAttributes = true;
MonoClass* parentClass = mono_property_get_parent(_monoProperty);
MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_property(parentClass, _monoProperty);
if (attrInfo == nullptr)
return _attributes;
MonoArray* monoAttributesArray = mono_custom_attrs_construct(attrInfo);
const auto length = (uint32)mono_array_length(monoAttributesArray);
_attributes.Resize(length);
for (uint32 i = 0; i < length; i++)
_attributes[i] = mono_array_get(monoAttributesArray, MonoObject*, i);
mono_custom_attrs_free(attrInfo);
return _attributes;
}
#endif