// 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