您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

139 行
3.6 KiB

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using UnityEngine;
namespace RMGUI.GraphView
{
// types of port to adapt
class PortSource<T>
{
}
// attribute to declare and adapter
class TypeAdapter : Attribute
{
}
// TODO: This is a straight port from Canvas2D. I don't think that having to check for types in the assembly using reflection is the way we want to go.
public class NodeAdapter
{
private static List<MethodInfo> s_TypeAdapters;
private static Dictionary<int, MethodInfo> s_NodeAdapterDictionary;
public bool CanAdapt(object a, object b)
{
if (a == b)
return false; // self connections are not permitted
if (a == null || b == null)
return false;
MethodInfo mi = GetAdapter(a, b);
if (mi == null)
{
Debug.Log("adapter node not found for: " + a.GetType() + " -> " + b.GetType());
}
return mi != null;
}
public bool Connect(object a, object b)
{
MethodInfo mi = GetAdapter(a, b);
if (mi == null)
{
Debug.LogError("Attempt to connect 2 unadaptable types: " + a.GetType() + " -> " + b.GetType());
return false;
}
object retVal = mi.Invoke(this, new[] { this, a, b });
return (bool)retVal;
}
IEnumerable<MethodInfo> GetExtensionMethods(Assembly assembly, Type extendedType)
{
return assembly.GetTypes()
.Where(t => t.IsSealed && !t.IsGenericType && !t.IsNested)
.SelectMany(t => t.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic))
.Where(m => m.IsDefined(typeof(ExtensionAttribute), false) && m.GetParameters()[0].ParameterType == extendedType);
}
public MethodInfo GetAdapter(object a, object b)
{
if (a == null || b == null)
return null;
if (s_NodeAdapterDictionary == null)
{
s_NodeAdapterDictionary = new Dictionary<int, MethodInfo>();
// add extension methods
AppDomain currentDomain = AppDomain.CurrentDomain;
foreach (Assembly assembly in currentDomain.GetAssemblies())
{
foreach (MethodInfo method in GetExtensionMethods(assembly, typeof(NodeAdapter)))
{
var methodParams = method.GetParameters();
if (methodParams.Length == 3)
{
string pa = methodParams[1].ParameterType + methodParams[2].ParameterType.ToString();
s_NodeAdapterDictionary.Add(pa.GetHashCode(), method);
}
}
}
}
string s = a.GetType().ToString() + b.GetType();
MethodInfo methodInfo;
return s_NodeAdapterDictionary.TryGetValue(s.GetHashCode(), out methodInfo) ? methodInfo : null;
}
public MethodInfo GetTypeAdapter(Type from, Type to)
{
if (s_TypeAdapters == null)
{
s_TypeAdapters = new List<MethodInfo>();
AppDomain currentDomain = AppDomain.CurrentDomain;
foreach (Assembly assembly in currentDomain.GetAssemblies())
{
try
{
foreach (Type temptype in assembly.GetTypes())
{
MethodInfo[] methodInfos = temptype.GetMethods(BindingFlags.Public | BindingFlags.Static);
foreach (MethodInfo i in methodInfos)
{
object[] allAttrs = i.GetCustomAttributes(typeof(TypeAdapter), false);
if (allAttrs.Any())
{
s_TypeAdapters.Add(i);
}
}
}
}
catch (Exception ex)
{
Debug.Log(ex);
}
}
}
foreach (MethodInfo i in s_TypeAdapters)
{
if (i.ReturnType == to)
{
ParameterInfo[] allParams = i.GetParameters();
if (allParams.Length == 1)
{
if (allParams[0].ParameterType == from)
return i;
}
}
}
return null;
}
}
}