214 lines
6.5 KiB
C#
214 lines
6.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using Component = UnityEngine.Component;
|
|
using Object = UnityEngine.Object;
|
|
|
|
namespace MyFrameworkPure
|
|
{
|
|
/// <summary>
|
|
/// 接口工具类
|
|
/// </summary>
|
|
public static class InterfaceTool
|
|
{
|
|
private static Dictionary<Type, List<Type>> _interfaceToComponentMapping;
|
|
private static Type[] _allTypes;
|
|
|
|
static InterfaceTool()
|
|
{
|
|
InitInterfaceToComponentMapping();
|
|
}
|
|
|
|
private static void InitInterfaceToComponentMapping()
|
|
{
|
|
_interfaceToComponentMapping = new Dictionary<Type, List<Type>>();
|
|
|
|
_allTypes = GetAllTypes();
|
|
|
|
foreach (var curInterface in _allTypes)
|
|
{
|
|
//We're interested only in interfaces
|
|
if (!curInterface.IsInterface)
|
|
continue;
|
|
|
|
var typeName = curInterface.ToString().ToLower();
|
|
|
|
//Skip system interfaces
|
|
if (typeName.Contains("unity") || typeName.Contains("system.")
|
|
|| typeName.Contains("mono.") || typeName.Contains("mono.") || typeName.Contains("icsharpcode.")
|
|
|| typeName.Contains("nsubstitute") || typeName.Contains("nunit.") || typeName.Contains("microsoft.")
|
|
|| typeName.Contains("boo.") || typeName.Contains("serializ") || typeName.Contains("json")
|
|
|| typeName.Contains("log.") || typeName.Contains("logging") || typeName.Contains("test")
|
|
|| typeName.Contains("editor") || typeName.Contains("debug"))
|
|
continue;
|
|
|
|
var typesInherited = GetTypesInheritedFromInterface(curInterface);
|
|
|
|
if (typesInherited.Count <= 0)
|
|
continue;
|
|
|
|
var componentsList = new List<Type>();
|
|
|
|
foreach (var curType in typesInherited)
|
|
{
|
|
//Skip interfaces
|
|
if (curType.IsInterface)
|
|
continue;
|
|
|
|
//Ignore non-component classes
|
|
if (!(typeof(Component) == curType || curType.IsSubclassOf(typeof(Component))))
|
|
continue;
|
|
|
|
if (!componentsList.Contains(curType))
|
|
componentsList.Add(curType);
|
|
}
|
|
|
|
_interfaceToComponentMapping.Add(curInterface, componentsList);
|
|
}
|
|
}
|
|
|
|
private static Type[] GetAllTypes()
|
|
{
|
|
var res = new List<Type>();
|
|
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
|
|
{
|
|
res.AddRange(assembly.GetTypes());
|
|
}
|
|
|
|
return res.ToArray();
|
|
}
|
|
|
|
private static IEnumerable<Type> GetTypesInheritedFromInterface<T>() where T : class
|
|
{
|
|
return GetTypesInheritedFromInterface(typeof(T));
|
|
}
|
|
|
|
private static IList<Type> GetTypesInheritedFromInterface(Type type)
|
|
{
|
|
//Caching
|
|
if (null == _allTypes)
|
|
{
|
|
_allTypes = GetAllTypes();
|
|
}
|
|
|
|
var res = new List<Type>();
|
|
|
|
foreach (var curType in _allTypes)
|
|
{
|
|
if (!(type.IsAssignableFrom(curType) && curType.IsSubclassOf(typeof(Component))))
|
|
continue;
|
|
|
|
res.Add(curType);
|
|
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 查找接口
|
|
/// </summary>
|
|
/// <typeparam name="T"></typeparam>
|
|
/// <param name="firstOnly"></param>
|
|
/// <returns></returns>
|
|
public static IList<T> FindObjects<T>(bool firstOnly = false) where T : class
|
|
{
|
|
var resList = new List<T>();
|
|
|
|
var types = _interfaceToComponentMapping[typeof(T)];
|
|
|
|
if (null == types || types.Count <= 0)
|
|
{
|
|
Debug.LogError("No descendants found for type " + typeof(T));
|
|
return null;
|
|
}
|
|
|
|
foreach (var curType in types)
|
|
{
|
|
Object[] objects = firstOnly ?
|
|
new[] { Object.FindObjectOfType(curType) }
|
|
: Object.FindObjectsOfType(curType);
|
|
|
|
if (null == objects || objects.Length <= 0)
|
|
continue;
|
|
|
|
var tList = new List<T>();
|
|
|
|
foreach (var curObj in objects)
|
|
{
|
|
var curObjAsT = curObj as T;
|
|
|
|
if (null == curObjAsT)
|
|
{
|
|
Debug.LogError("Unable to cast '" + curObj.GetType() + "' to '" + typeof(T) + "'");
|
|
continue;
|
|
}
|
|
|
|
tList.Add(curObjAsT);
|
|
}
|
|
|
|
resList.AddRange(tList);
|
|
}
|
|
|
|
return resList;
|
|
}
|
|
|
|
public static T FindObject<T>() where T : class
|
|
{
|
|
var list = FindObjects<T>();
|
|
|
|
return list[0];
|
|
}
|
|
|
|
public static IList<T> GetInterfaceComponents<T>(this Component component, bool firstOnly = false) where T : class
|
|
{
|
|
var types = _interfaceToComponentMapping[typeof(T)];
|
|
|
|
if (null == types || types.Count <= 0)
|
|
{
|
|
Debug.LogError("No descendants found for type " + typeof(T));
|
|
return null;
|
|
}
|
|
|
|
var resList = new List<T>();
|
|
|
|
foreach (var curType in types)
|
|
{
|
|
//Optimization - don't get all objects if we need only one
|
|
Component[] components = firstOnly ?
|
|
new[] { component.GetComponent(curType) }
|
|
: component.GetComponents(curType);
|
|
|
|
if (null == components || components.Length <= 0)
|
|
continue;
|
|
|
|
var tList = new List<T>();
|
|
|
|
foreach (var curComp in components)
|
|
{
|
|
var curCompAsT = curComp as T;
|
|
|
|
if (null == curCompAsT)
|
|
{
|
|
Debug.LogError("Unable to cast '" + curComp.GetType() + "' to '" + typeof(T) + "'");
|
|
continue;
|
|
}
|
|
|
|
tList.Add(curCompAsT);
|
|
}
|
|
|
|
resList.AddRange(tList);
|
|
}
|
|
|
|
return resList;
|
|
}
|
|
|
|
public static T GetInterfaceComponent<T>(this Component component) where T : class
|
|
{
|
|
var list = GetInterfaceComponents<T>(component, true);
|
|
|
|
return list[0];
|
|
}
|
|
}
|
|
}
|