Version 1.1. Generic parameters support

This commit is contained in:
Anton Zhernosek
2023-06-03 22:09:15 +02:00
parent 90b433967e
commit e7648cb9d9
13 changed files with 1022 additions and 767 deletions

View File

@@ -0,0 +1,83 @@
using System;
using System.Linq;
using System.Reflection;
using UnityEngine;
using Object = UnityEngine.Object;
[System.Serializable]
public abstract class SerializableFuncBase<TFuncType>
where TFuncType : Delegate
{
[SerializeField] protected Object targetObject;
[SerializeField] protected string methodName;
private TFuncType func;
private static BindingFlags SuitableMethodsFlags = BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.Instance;
protected TFuncType GetReturnedFunc()
{
if (func == null)
{
if (targetObject == null)
{
throw new ArgumentNullException("Target Object is null!");
}
if (string.IsNullOrWhiteSpace(methodName))
{
throw new ArgumentNullException("Target Method is null!");
}
Type funcType = typeof(TFuncType);
MethodInfo info = targetObject
.GetType()
.GetMethods(SuitableMethodsFlags)
.FirstOrDefault(x => IsTargetMethodInfo(x, funcType));
if (info == null)
{
throw new MissingMethodException($"Object \"{targetObject.name}\" is missing target method: {methodName}");
}
func = (TFuncType)Delegate.CreateDelegate(funcType, targetObject, methodName);
}
return func;
}
#region Utility Functions
private bool IsTargetMethodInfo(MethodInfo methodInfo, Type funcType)
{
if (string.Equals(methodInfo.Name, methodName, StringComparison.InvariantCulture)) return false;
Type[] typeArguments = funcType.GetGenericArguments();
if (methodInfo.ReturnType != typeArguments.Last()) return false;
ParameterInfo[] parameters = methodInfo.GetParameters();
if (parameters.Length != (typeArguments.Length - 1)) return false;
for (int i = 0; i < parameters.Length; i++)
{
Type argType = typeArguments[i];
ParameterInfo parameterInfo = parameters[i];
if (argType != parameterInfo.ParameterType) return false;
}
return true;
}
#endregion
public static implicit operator TFuncType(SerializableFuncBase<TFuncType> func)
{
if (func == null) return null;
TFuncType result = func.GetReturnedFunc();
return result;
}
}