// Copyright (c) Wojciech Figat. All rights reserved.
#pragma once
#include "Engine/Core/Collections/Array.h"
#include "Engine/Core/Memory/ArenaAllocation.h"
#include "MTypes.h"
///
/// Encapsulates information about a single Mono managed property belonging to some managed class.
/// This object also allows you to set or retrieve values to or from specific instances containing the property.
///
class FLAXENGINE_API MProperty
{
friend MClass;
friend MCore;
protected:
#if USE_MONO
MonoProperty* _monoProperty;
StringAnsi _name;
#elif USE_NETCORE
void* _handle;
StringAnsiView _name;
#else
StringAnsiView _name;
#endif
mutable MMethod* _getMethod;
mutable MMethod* _setMethod;
MClass* _parentClass;
mutable int32 _hasCachedAttributes : 1;
mutable int32 _hasSetMethod : 1;
mutable int32 _hasGetMethod : 1;
mutable Array _attributes;
public:
#if USE_MONO
explicit MProperty(MonoProperty* monoProperty, const char* name, MClass* parentClass);
#elif USE_NETCORE
MProperty(MClass* parentClass, const char* name, void* handle, void* getterHandle, void* setterHandle, MMethodAttributes getterAttributes, MMethodAttributes setterAttributes);
#endif
///
/// Finalizes an instance of the class.
///
~MProperty();
public:
///
/// Gets the property name.
///
FORCE_INLINE StringAnsiView GetName() const
{
return _name;
}
///
/// Returns the parent class that this method is contained with.
///
FORCE_INLINE MClass* GetParentClass() const
{
return _parentClass;
}
///
/// Gets property type class.
///
MType* GetType() const;
///
/// Gets property get method.
///
MMethod* GetGetMethod() const;
///
/// Gets property set method.
///
MMethod* GetSetMethod() const;
///
/// Gets property visibility in the class.
///
MVisibility GetVisibility() const;
///
/// Returns true if property is static.
///
bool IsStatic() const;
public:
///
/// Retrieves value currently set in the property on the specified object instance. If property is static object instance can be null.
///
///
/// Value will be a pointer to raw data type for value types (for example int, float), and a MObject* for reference types.
///
/// The object of given type to get value from.
/// An optional pointer to the exception value to store exception object reference.
/// The returned boxed value object.
MObject* GetValue(MObject* instance, MObject** exception) const;
///
/// Sets a value for the property on the specified object instance. If property is static object instance can be null.
///
///
/// Value should be a pointer to raw data type for value types (for example int, float), and a MObject* for reference types.
///
/// Object of given type to set value to.
/// An optional pointer to the exception value to store exception object reference.
/// The value to set of undefined type.
void SetValue(MObject* instance, void* value, MObject** exception) const;
public:
///
/// Checks if property has an attribute of the specified type.
///
/// The attribute class to check.
/// True if has attribute of that class type, otherwise false.
bool HasAttribute(const MClass* klass) const;
///
/// Checks if property has an attribute of any type.
///
/// True if has any custom attribute, otherwise false.
bool HasAttribute() const;
///
/// Returns an instance of an attribute of the specified type. Returns null if the property doesn't have such an attribute.
///
/// The attribute class to take.
/// The attribute object.
MObject* GetAttribute(const MClass* klass) const;
///
/// Returns an instance of all attributes connected with given property. Returns null if the property doesn't have any attributes.
///
/// The array of attribute objects.
const Array& GetAttributes() const;
};