You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
92 lines
3.6 KiB
92 lines
3.6 KiB
2 years ago
|
// This code is part of the Fungus library (https://github.com/snozbot/fungus)
|
||
|
// It is released for free under the MIT open source license (https://github.com/snozbot/fungus/blob/master/LICENSE)
|
||
|
|
||
|
using UnityEngine;
|
||
|
using System.Collections.Generic;
|
||
|
using System.Linq;
|
||
|
using UnityEditor;
|
||
|
|
||
|
namespace Fungus.EditorUtils
|
||
|
{
|
||
|
public static class EditorExtensions
|
||
|
{
|
||
|
/// <summary>
|
||
|
/// FindDerivedTypesFromAssembly allows a user to query all of types derived from a
|
||
|
/// particular Type at runtime.
|
||
|
/// Example usage:
|
||
|
/// foreach (System.Type st in EditorUtility.FindDerivedTypesFromAssembly(System.Reflection.Assembly.GetAssembly(typeof(BaseTimelineEvent)), typeof(BaseTimelineEvent), true))
|
||
|
/// </summary>
|
||
|
/// <param name="assembly">The assembly to search in</param>
|
||
|
/// <param name="baseType">The base Type from which all returned Types derive</param>
|
||
|
/// <param name="classOnly">If true, only class Types will be returned</param>
|
||
|
/// <returns></returns>
|
||
|
public static System.Type[] FindDerivedTypesFromAssembly(this System.Reflection.Assembly assembly, System.Type baseType, bool classOnly = true)
|
||
|
{
|
||
|
if (assembly == null)
|
||
|
Debug.LogError("Assembly must be defined");
|
||
|
if (baseType == null)
|
||
|
Debug.LogError("Base type must be defined");
|
||
|
|
||
|
// Iterate through all available types in the assembly
|
||
|
var types = assembly.GetTypes().Where(type =>
|
||
|
{
|
||
|
if (classOnly && !type.IsClass)
|
||
|
return false;
|
||
|
|
||
|
if (baseType.IsInterface)
|
||
|
{
|
||
|
var it = type.GetInterface(baseType.FullName);
|
||
|
|
||
|
if (it != null)
|
||
|
return true;
|
||
|
}
|
||
|
else if (type.IsSubclassOf(baseType))
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
);
|
||
|
|
||
|
return types.ToArray();
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// A convenient method for calling the above, but for ALL assemblies.
|
||
|
/// Example usage:
|
||
|
/// List<System.Type> subTypes = EditorUtility.FindDerivedTypes(typeof(BaseTimelineEvent)).ToList();
|
||
|
/// </summary>
|
||
|
/// <param name="baseType"></param>
|
||
|
/// <param name="classOnly"></param>
|
||
|
/// <returns></returns>
|
||
|
public static System.Type[] FindDerivedTypes(System.Type baseType, bool classOnly = true)
|
||
|
{
|
||
|
#if UNITY_2019_2_OR_NEWER
|
||
|
var results = TypeCache.GetTypesDerivedFrom(baseType).ToArray();
|
||
|
if (classOnly)
|
||
|
return results.Where(x => x.IsClass).ToArray();
|
||
|
else
|
||
|
return results.ToArray();
|
||
|
#else
|
||
|
System.Type[] typeArray = new System.Type[0];
|
||
|
var retval = typeArray.Concat(typeArray);
|
||
|
foreach (var assem in System.AppDomain.CurrentDomain.GetAssemblies())
|
||
|
{
|
||
|
retval = retval.Concat(FindDerivedTypesFromAssembly(assem, baseType, classOnly));
|
||
|
}
|
||
|
return retval.ToArray();
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Find and return all Unity.Objects that have the target interface
|
||
|
/// </summary>
|
||
|
/// <typeparam name="T">Intended to be an interface but will work for any</typeparam>
|
||
|
/// <returns></returns>
|
||
|
public static List<T> FindObjectsOfInterface<T>()
|
||
|
{
|
||
|
return Object.FindObjectsOfType<Object>().OfType<T>().ToList();
|
||
|
}
|
||
|
}
|
||
|
}
|