using System; using System.Linq; using System.Reflection; using UnityEditor; using UnityEngine.UIElements; namespace Alchemy.Editor { /// /// Base class for extending drawing processing for fields with Alchemy attributes. /// public abstract class AlchemyAttributeDrawer { SerializedObject serializedObject; SerializedProperty serializedProperty; object target; MemberInfo memberInfo; Attribute attribute; VisualElement targetElement; /// /// Target serialized object. /// public SerializedObject SerializedObject => serializedObject; /// /// Target serialized property. /// public SerializedProperty SerializedProperty => serializedProperty; /// /// Target object. /// public object Target => target; /// /// MemberInfo of the target member. /// public MemberInfo MemberInfo => memberInfo; /// /// Target attribute. /// public Attribute Attribute => attribute; /// /// Target visual element. /// public VisualElement TargetElement => targetElement; /// /// Called when the target visual element is created. /// public abstract void OnCreateElement(); internal static void ExecutePropertyDrawers(SerializedObject serializedObject, SerializedProperty property, object target, MemberInfo memberInfo, VisualElement memberElement) { var attributes = memberInfo.GetCustomAttributes(); var processorTypes = TypeCache.GetTypesWithAttribute(typeof(CustomAttributeDrawerAttribute)); foreach (var attribute in attributes) { var processorType = processorTypes.FirstOrDefault(x => x.IsSubclassOf(typeof(AlchemyAttributeDrawer)) && x.GetCustomAttribute().targetAttributeType == attribute.GetType()); if (processorType == null) continue; var processor = (AlchemyAttributeDrawer)Activator.CreateInstance(processorType); processor.serializedObject = serializedObject; processor.serializedProperty = property; processor.target = target; processor.memberInfo = memberInfo; processor.attribute = attribute; processor.targetElement = memberElement; processor.OnCreateElement(); } } } }