// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved. #pragma once #include "Engine/Core/Collections/Array.h" #include "MTypes.h" /// /// Contains information about a single managed class. /// class FLAXENGINE_API MClass { friend MCore; private: #if USE_MONO MonoClass* _monoClass; mutable void* _attrInfo = nullptr; #elif USE_NETCORE void* _handle; StringAnsi _name; StringAnsi _namespace; uint32 _types = 0; mutable uint32 _size = 0; #endif const MAssembly* _assembly; StringAnsi _fullname; mutable Array _methods; mutable Array _fields; mutable Array _properties; mutable Array _attributes; mutable Array _events; mutable Array _interfaces; MVisibility _visibility; mutable int32 _hasCachedProperties : 1; mutable int32 _hasCachedFields : 1; mutable int32 _hasCachedMethods : 1; mutable int32 _hasCachedAttributes : 1; mutable int32 _hasCachedEvents : 1; mutable int32 _hasCachedInterfaces : 1; int32 _isStatic : 1; int32 _isSealed : 1; int32 _isAbstract : 1; int32 _isInterface : 1; int32 _isValueType : 1; int32 _isEnum : 1; public: #if USE_MONO MClass(const MAssembly* parentAssembly, MonoClass* monoClass, const StringAnsi& fullname); #elif USE_NETCORE MClass(const MAssembly* parentAssembly, void* handle, const char* name, const char* fullname, const char* namespace_, MTypeAttributes typeAttributes); #endif /// /// Finalizes an instance of the class. /// ~MClass(); public: /// /// Gets the parent assembly. /// const MAssembly* GetAssembly() const { return _assembly; } /// /// Gets the full name of the class (namespace and typename). /// FORCE_INLINE const StringAnsi& GetFullName() const { return _fullname; } /// /// Gets the name of the class. /// StringAnsiView GetName() const; /// /// Gets the namespace of the class. /// StringAnsiView GetNamespace() const; #if USE_MONO /// /// Gets the Mono class handle. /// FORCE_INLINE MonoClass* GetNative() const { return _monoClass; } #elif USE_NETCORE FORCE_INLINE void* GetNative() const { return _handle; } #endif /// /// Gets class visibility /// FORCE_INLINE MVisibility GetVisibility() const { return _visibility; } /// /// Gets if class is static /// FORCE_INLINE bool IsStatic() const { return _isStatic != 0; } /// /// Gets if class is abstract /// FORCE_INLINE bool IsAbstract() const { return _isAbstract != 0; } /// /// Gets if class is sealed /// FORCE_INLINE bool IsSealed() const { return _isSealed != 0; } /// /// Gets if class is interface /// FORCE_INLINE bool IsInterface() const { return _isInterface != 0; } /// /// Gets if class is value type (eg. enum or structure) but not reference type (eg. class, string, array, interface) /// FORCE_INLINE bool IsValueType() const { return _isValueType != 0; } /// /// Gets if class is enumeration /// FORCE_INLINE bool IsEnum() const { return _isEnum != 0; } /// /// Gets if class is generic /// bool IsGeneric() const { return _fullname.FindLast('`') != -1; } /// /// Gets the class type. /// MType* GetType() const; /// /// Returns the base class of this class. Null if this class has no base. /// MClass* GetBaseClass() const; /// /// Checks if this class is a sub class of the specified class (including any derived types). /// /// The class. /// True if check interfaces, otherwise just base class. /// True if this class is a sub class of the specified class. bool IsSubClassOf(const MClass* klass, bool checkInterfaces = false) const; /// /// Checks if this class implements the specified interface (including any base types). /// /// The interface class. /// True if this class implements the specified interface. bool HasInterface(const MClass* klass) const; /// /// Checks is the provided object instance of this class' type. /// /// The object to check. /// True if object is an instance the this class. bool IsInstanceOfType(MObject* object) const; /// /// Returns the size of an instance of this class, in bytes. /// uint32 GetInstanceSize() const; /// /// Returns the class of the array type elements. /// MClass* GetElementClass() const; public: /// /// Returns an object referencing a method with the specified name and number of parameters. Optionally checks the base classes. /// /// The method name. /// The method parameters count. /// True if check base classes when searching for the given method. /// The method or null if failed to find it. MMethod* FindMethod(const char* name, int32 numParams, bool checkBaseClasses = true) const { MMethod* method = GetMethod(name, numParams); if (!method && checkBaseClasses) { MClass* base = GetBaseClass(); if (base) method = base->FindMethod(name, numParams, true); } return method; } /// /// Returns an object referencing a method with the specified name and number of parameters. /// /// If the type contains more than one method of the given name and parameters count the returned value can be non-deterministic (one of the matching methods). /// The method name. /// The method parameters count. /// The method or null if failed to get it. MMethod* GetMethod(const char* name, int32 numParams = 0) const; /// /// Returns all methods belonging to this class. /// /// Be aware this will not include the methods of any base classes. /// The list of methods. const Array& GetMethods() const; /// /// Returns an object referencing a field with the specified name. /// /// Does not query base class fields. Returns null if field cannot be found. /// The field name. /// The field or null if failed. MField* GetField(const char* name) const; /// /// Returns all fields belonging to this class. /// /// Be aware this will not include the fields of any base classes. /// The list of fields. const Array& GetFields() const; /// /// Returns an object referencing a event with the specified name. /// /// The event name. /// The event object. MEvent* GetEvent(const char* name) const; /// /// Returns all events belonging to this class. /// /// The list of events. const Array& GetEvents() const; /// /// Returns an object referencing a property with the specified name. /// /// Does not query base class properties. Returns null if property cannot be found. /// The property name. /// The property. MProperty* GetProperty(const char* name) const; /// /// Returns all properties belonging to this class. /// /// Be aware this will not include the properties of any base classes. /// The list of properties. const Array& GetProperties() const; /// /// Returns all interfaces implemented by this class (excluding interfaces from base classes). /// /// Be aware this will not include the interfaces of any base classes. /// The list of interfaces. const Array& GetInterfaces() const; public: /// /// Creates a new instance of this class and constructs it. /// /// The created managed object. MObject* CreateInstance() const; public: /// /// Checks if class 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 class 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 class 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 class. Returns null if the class doesn't have any attributes. /// /// The array of attribute objects. const Array& GetAttributes() const; };