1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 |
- // 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
- {
- /// <summary>[Editor-Only]
- /// An assembly attribute for configuring how the <see cref="PolymorphicDrawer"/>
- /// displays a particular type.
- /// </summary>
- [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
- public sealed class PolymorphicDrawerDetails : Attribute
- {
- /************************************************************************************************************************/
- /// <summary>A default instance.</summary>
- public static readonly PolymorphicDrawerDetails
- Default = new(null);
- /************************************************************************************************************************/
- /// <summary>The <see cref="System.Type"/> this attribute applies to.</summary>
- public readonly Type Type;
- /// <summary>Creates a new <see cref="PolymorphicDrawerDetails"/>.</summary>
- public PolymorphicDrawerDetails(Type type)
- => Type = type;
- /************************************************************************************************************************/
- /// <summary>
- /// Should the label and <see cref="TypeSelectionButton"/>
- /// be drawn on a separate line before the field's regular GUI?
- /// </summary>
- public bool SeparateHeader { get; set; }
- /************************************************************************************************************************/
- private static readonly Dictionary<Type, PolymorphicDrawerDetails>
- TypeToDetails = new();
- /// <summary>Gathers all instances of this attribute in all currently loaded assemblies.</summary>
- 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);
- }
- }
- }
- /************************************************************************************************************************/
- /// <summary>
- /// Returns the <see cref="PolymorphicDrawerDetails"/> associated with the `type` or any of its base types.
- /// Returns <c>null</c> if none of them have any details.
- /// </summary>
- 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;
- }
- /// <summary>
- /// Returns the <see cref="PolymorphicDrawerDetails"/> associated with the `obj` or any of its base types.
- /// Returns <c>null</c> if none of them have any details.
- /// </summary>
- public static PolymorphicDrawerDetails Get(object obj)
- => obj == null
- ? Default
- : Get(obj.GetType());
- /************************************************************************************************************************/
- }
- }
- #endif
|