Added namespaces and fixed reflection method name bug

This commit is contained in:
Anton Zhernosek
2023-06-21 11:15:52 +02:00
parent 070c261c2f
commit c737bd9aeb
6 changed files with 198 additions and 192 deletions

View File

@@ -4,80 +4,83 @@ using System.Reflection;
using UnityEngine;
using Object = UnityEngine.Object;
[System.Serializable]
public abstract class SerializableFuncBase<TFuncType>
where TFuncType : Delegate
namespace UnityUtilities.SerializableDataHelpers
{
[SerializeField] protected Object targetObject;
[SerializeField] protected string methodName;
private TFuncType func;
private static BindingFlags SuitableMethodsFlags = BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.Instance;
protected TFuncType GetReturnedFunc()
[System.Serializable]
public abstract class SerializableFuncBase<TFuncType>
where TFuncType : Delegate
{
if (func == null)
[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 (targetObject == null)
if (func == null)
{
throw new ArgumentNullException("Target Object is 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);
}
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;
}
return func;
}
#region Utility Functions
#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++)
private bool IsTargetMethodInfo(MethodInfo methodInfo, Type funcType)
{
Type argType = typeArguments[i];
ParameterInfo parameterInfo = parameters[i];
if (argType != parameterInfo.ParameterType) return false;
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;
}
return true;
#endregion
public static implicit operator TFuncType(SerializableFuncBase<TFuncType> func)
{
if (func == null) return null;
TFuncType result = func.GetReturnedFunc();
return result;
}
}
#endregion
public static implicit operator TFuncType(SerializableFuncBase<TFuncType> func)
{
if (func == null) return null;
TFuncType result = func.GetReturnedFunc();
return result;
}
}
}