// Animancer // https://kybernetik.com.au/animancer // Copyright 2018-2024 Kybernetik // #if UNITY_EDITOR using Animancer.Editor; using System; using System.Collections.Generic; namespace Animancer.Editor { /// [Editor-Only] /// An assembly attribute for configuring how the /// displays a particular type. /// [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] public sealed class PolymorphicDrawerDetails : Attribute { /************************************************************************************************************************/ /// A default instance. public static readonly PolymorphicDrawerDetails Default = new(null); /************************************************************************************************************************/ /// The this attribute applies to. public readonly Type Type; /// Creates a new . public PolymorphicDrawerDetails(Type type) => Type = type; /************************************************************************************************************************/ /// /// Should the label and /// be drawn on a separate line before the field's regular GUI? /// public bool SeparateHeader { get; set; } /************************************************************************************************************************/ private static readonly Dictionary TypeToDetails = new(); /// Gathers all instances of this attribute in all currently loaded assemblies. static PolymorphicDrawerDetails() { var assemblies = AppDomain.CurrentDomain.GetAssemblies(); for (int iAssembly = 0; iAssembly < assemblies.Length; iAssembly++) { var assembly = assemblies[iAssembly]; if (!assembly.IsDefined(typeof(PolymorphicDrawerDetails), false)) continue; var attributes = assemblies[iAssembly].GetCustomAttributes(typeof(PolymorphicDrawerDetails), false); for (int iAttribute = 0; iAttribute < attributes.Length; iAttribute++) { var attribute = (PolymorphicDrawerDetails)attributes[iAttribute]; TypeToDetails.Add(attribute.Type, attribute); } } } /************************************************************************************************************************/ /// /// Returns the associated with the `type` or any of its base types. /// Returns null if none of them have any details. /// public static PolymorphicDrawerDetails Get(Type type) { if (TypeToDetails.TryGetValue(type, out var details)) return details; if (type.BaseType != null) details = Get(type.BaseType); else details = Default; TypeToDetails.Add(type, details); return details; } /// /// Returns the associated with the `obj` or any of its base types. /// Returns null if none of them have any details. /// public static PolymorphicDrawerDetails Get(object obj) => obj == null ? Default : Get(obj.GetType()); /************************************************************************************************************************/ } } #endif