99 lines
3.9 KiB
C#
99 lines
3.9 KiB
C#
// 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
|