Added serializable action.
This commit is contained in:
83
Runtime/SerializableAction.cs
Normal file
83
Runtime/SerializableAction.cs
Normal file
@@ -0,0 +1,83 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace SerializableFunc.Runtime
|
||||
{
|
||||
[Serializable]
|
||||
public class SerializableAction
|
||||
{
|
||||
[SerializeField] private Object targetObject;
|
||||
[SerializeField] private string methodName;
|
||||
|
||||
private Action cachedAction;
|
||||
|
||||
private static readonly BindingFlags SuitableMethodsFlags =
|
||||
BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.Instance;
|
||||
|
||||
public Object TargetObject
|
||||
{
|
||||
get => targetObject;
|
||||
set => targetObject = value;
|
||||
}
|
||||
|
||||
public string MethodName
|
||||
{
|
||||
get => methodName;
|
||||
set => methodName = value;
|
||||
}
|
||||
|
||||
private Action GetAction()
|
||||
{
|
||||
if (cachedAction == null)
|
||||
{
|
||||
if (targetObject == null)
|
||||
throw new ArgumentNullException(nameof(targetObject), "Target Object is null!");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(methodName))
|
||||
throw new ArgumentNullException(nameof(methodName), "Target Method is null!");
|
||||
|
||||
MethodInfo info = targetObject
|
||||
.GetType()
|
||||
.GetMethods(SuitableMethodsFlags)
|
||||
.FirstOrDefault(IsTargetMethodInfo);
|
||||
|
||||
if (info == null)
|
||||
{
|
||||
throw new MissingMethodException($"Object \"{targetObject.name}\" is missing target void method: {methodName}");
|
||||
}
|
||||
|
||||
cachedAction = (Action)Delegate.CreateDelegate(typeof(Action), targetObject, methodName);
|
||||
}
|
||||
|
||||
return cachedAction;
|
||||
}
|
||||
|
||||
private bool IsTargetMethodInfo(MethodInfo methodInfo)
|
||||
{
|
||||
if (!string.Equals(methodInfo.Name, methodName, StringComparison.InvariantCulture))
|
||||
return false;
|
||||
|
||||
if (methodInfo.ReturnType != typeof(void))
|
||||
return false;
|
||||
|
||||
// Only allow parameterless void methods for this version
|
||||
if (methodInfo.GetParameters().Length != 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Invoke()
|
||||
{
|
||||
GetAction()?.Invoke();
|
||||
}
|
||||
|
||||
public static implicit operator Action(SerializableAction serializableAction)
|
||||
{
|
||||
return serializableAction?.GetAction();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user