// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
#pragma once
#include "Engine/Core/Collections/Array.h"
#include "MTypes.h"
///
/// Encapsulates information about a single Mono (managed) fields belonging to some managed class. This object also allows you to access the field data of an object instance.
///
class FLAXENGINE_API MField
{
friend MClass;
protected:
#if USE_MONO
MonoClassField* _monoField;
MonoType* _monoType;
#elif USE_NETCORE
void* _handle;
void* _type;
int32 _fieldOffset;
#endif
MClass* _parentClass;
StringAnsi _name;
MVisibility _visibility;
mutable int32 _hasCachedAttributes : 1;
int32 _isStatic : 1;
mutable Array _attributes;
public:
#if USE_MONO
explicit MField(MonoClassField* monoField, const char* name, MClass* parentClass);
#elif USE_NETCORE
MField(MClass* parentClass, void* handle, const char* name, void* type, int fieldOffset, MFieldAttributes attributes);
#endif
public:
///
/// Gets field name.
///
FORCE_INLINE const StringAnsi& GetName() const
{
return _name;
}
///
/// Returns the parent class that this method is contained with.
///
FORCE_INLINE MClass* GetParentClass() const
{
return _parentClass;
}
///
/// Gets field type class.
///
MType* GetType() const;
///
/// Gets the field offset (in bytes) from the start of the parent object.
///
int32 GetOffset() const;
///
/// Gets field visibility in the class.
///
FORCE_INLINE MVisibility GetVisibility() const
{
return _visibility;
}
///
/// Returns true if field is static.
///
FORCE_INLINE bool IsStatic() const
{
return _isStatic != 0;
}
#if USE_MONO
///
/// Gets mono field handle.
///
FORCE_INLINE MonoClassField* GetNative() const
{
return _monoField;
}
#endif
public:
///
/// Retrieves value currently set in the field on the specified object instance. If field 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.
/// The return value of undefined type.
void GetValue(MObject* instance, void* result) const;
///
/// Retrieves value currently set in the field on the specified object instance. If field is static object instance can be null.
///
///
/// Value will be a pointer.
///
/// The object of given type to get value from.
/// The return value of undefined type.
void GetValueReference(MObject* instance, void* result) const;
///
/// Retrieves value currently set in the field on the specified object instance. If field is static object instance can be null. If returned value is a value type it will be boxed.
///
/// The object of given type to get value from.
/// The boxed value object.
MObject* GetValueBoxed(MObject* instance) const;
///
/// Sets a value for the field on the specified object instance. If field 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.
///
/// The object of given type to set value to.
/// Th value of undefined type.
void SetValue(MObject* instance, void* value) const;
public:
///
/// Checks if field has an attribute of the specified type.
///
/// The attribute class to check.
/// True if has attribute of that class type, otherwise false.
bool HasAttribute(MClass* monoClass) const;
///
/// Checks if field 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 field doesn't have such an attribute.
///
/// The attribute class to take.
/// The attribute object.
MObject* GetAttribute(MClass* monoClass) const;
///
/// Returns an instance of all attributes connected with given field. Returns null if the field doesn't have any attributes.
///
/// The array of attribute objects.
const Array& GetAttributes() const;
};