Added serializable action.

This commit is contained in:
2025-11-03 20:34:21 +01:00
parent b0cd87be7d
commit 21b9cdc77c
11 changed files with 125 additions and 51 deletions

View File

@@ -5,6 +5,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
using SerializableFunc.Runtime;
using UnityEditor; using UnityEditor;
using UnityEditor.UIElements; using UnityEditor.UIElements;
using UnityEditorInternal; using UnityEditorInternal;
@@ -12,11 +13,11 @@ using UnityEngine;
using UnityEngine.UIElements; using UnityEngine.UIElements;
using Utilities.Extensions.SystemExtensions; using Utilities.Extensions.SystemExtensions;
using Utilities.Extensions.UIToolkit; using Utilities.Extensions.UIToolkit;
using UnityUtilities.SerializableDataHelpers;
using Object = UnityEngine.Object; using Object = UnityEngine.Object;
namespace UnityUtilities.SerializableDataHelpers.UnityEditorUtilities namespace UnityUtilities.SerializableDataHelpers.UnityEditorUtilities
{ {
[CustomPropertyDrawer(typeof(SerializableAction), true)]
[CustomPropertyDrawer(typeof(SerializableFuncBase<>), true)] [CustomPropertyDrawer(typeof(SerializableFuncBase<>), true)]
public class SerializableFuncBasePropertyDrawer : PropertyDrawer public class SerializableFuncBasePropertyDrawer : PropertyDrawer
{ {
@@ -169,7 +170,11 @@ namespace UnityUtilities.SerializableDataHelpers.UnityEditorUtilities
|| string.IsNullOrWhiteSpace(targetMethodProperty.stringValue)) return false; || string.IsNullOrWhiteSpace(targetMethodProperty.stringValue)) return false;
Type[] funcArguments = GetFuncTypeArguments(funcProperty); Type[] funcArguments = GetFuncTypeArguments(funcProperty);
Type returnType = funcArguments.Last(); Type returnType = typeof(void);
if (funcArguments.Length > 0)
{
returnType = funcArguments.Last();
}
MethodInfo targetMethod = targetObjectProperty.objectReferenceValue MethodInfo targetMethod = targetObjectProperty.objectReferenceValue
.GetType() .GetType()
@@ -561,8 +566,15 @@ namespace UnityUtilities.SerializableDataHelpers.UnityEditorUtilities
{ {
if (info.IsSpecialName) return false; if (info.IsSpecialName) return false;
if (funcParameters.Length > 0)
{
Type returnType = funcParameters.Last(); Type returnType = funcParameters.Last();
if (info.ReturnType != returnType) return false; if (info.ReturnType != returnType) return false;
}
else
{
if (info.ReturnType == typeof(void)) return true;
}
ParameterInfo[] parameters = info.GetParameters(); ParameterInfo[] parameters = info.GetParameters();
if (parameters.Length != (funcParameters.Length - 1)) return false; if (parameters.Length != (funcParameters.Length - 1)) return false;

View 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();
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 2ba5aa5c8f7c474fbaba429c733d8d7c
timeCreated: 1762160974

View File

@@ -1,6 +1,6 @@
{ {
"name": "SerializableFunc.Runtime", "name": "SerializableFunc.Runtime",
"rootNamespace": "", "rootNamespace": "SerializableFunc.Runtime",
"references": [], "references": [],
"includePlatforms": [], "includePlatforms": [],
"excludePlatforms": [], "excludePlatforms": [],

View File

@@ -1,8 +1,8 @@
namespace UnityUtilities.SerializableDataHelpers
{
using System; using System;
[System.Serializable] namespace SerializableFunc.Runtime
{
[Serializable]
public class SerializableFunc<TReturn> : SerializableFuncBase<Func<TReturn>> public class SerializableFunc<TReturn> : SerializableFuncBase<Func<TReturn>>
{ {
public TReturn Invoke() public TReturn Invoke()
@@ -12,7 +12,7 @@ namespace UnityUtilities.SerializableDataHelpers
} }
} }
[System.Serializable] [Serializable]
public class SerializableFunc<TArg0, TReturn> : SerializableFuncBase<Func<TArg0, TReturn>> public class SerializableFunc<TArg0, TReturn> : SerializableFuncBase<Func<TArg0, TReturn>>
{ {
public TReturn Invoke(TArg0 arg0) public TReturn Invoke(TArg0 arg0)
@@ -22,7 +22,7 @@ namespace UnityUtilities.SerializableDataHelpers
} }
} }
[System.Serializable] [Serializable]
public class SerializableFunc<TArg0, TArg1, TReturn> : SerializableFuncBase<Func<TArg0, TArg1, TReturn>> public class SerializableFunc<TArg0, TArg1, TReturn> : SerializableFuncBase<Func<TArg0, TArg1, TReturn>>
{ {
public TReturn Invoke(TArg0 arg0, TArg1 arg1) public TReturn Invoke(TArg0 arg0, TArg1 arg1)
@@ -32,7 +32,7 @@ namespace UnityUtilities.SerializableDataHelpers
} }
} }
[System.Serializable] [Serializable]
public class SerializableFunc<TArg0, TArg1, TArg2, TReturn> : SerializableFuncBase<Func<TArg0, TArg1, TArg2, TReturn>> public class SerializableFunc<TArg0, TArg1, TArg2, TReturn> : SerializableFuncBase<Func<TArg0, TArg1, TArg2, TReturn>>
{ {
public TReturn Invoke(TArg0 arg0, TArg1 arg1, TArg2 arg2) public TReturn Invoke(TArg0 arg0, TArg1 arg1, TArg2 arg2)
@@ -42,7 +42,7 @@ namespace UnityUtilities.SerializableDataHelpers
} }
} }
[System.Serializable] [Serializable]
public class SerializableFunc<TArg0, TArg1, TArg2, TArg3, TReturn> : SerializableFuncBase<Func<TArg0, TArg1, TArg2, TArg3, TReturn>> public class SerializableFunc<TArg0, TArg1, TArg2, TArg3, TReturn> : SerializableFuncBase<Func<TArg0, TArg1, TArg2, TArg3, TReturn>>
{ {
public TReturn Invoke(TArg0 arg0, TArg1 arg1, TArg2 arg2, TArg3 arg3) public TReturn Invoke(TArg0 arg0, TArg1 arg1, TArg2 arg2, TArg3 arg3)
@@ -52,7 +52,7 @@ namespace UnityUtilities.SerializableDataHelpers
} }
} }
[System.Serializable] [Serializable]
public class SerializableFunc<TArg0, TArg1, TArg2, TArg3, TArg4, TReturn> : SerializableFuncBase<Func<TArg0, TArg1, TArg2, TArg3, TArg4, TReturn>> public class SerializableFunc<TArg0, TArg1, TArg2, TArg3, TArg4, TReturn> : SerializableFuncBase<Func<TArg0, TArg1, TArg2, TArg3, TArg4, TReturn>>
{ {
public TReturn Invoke(TArg0 arg0, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4) public TReturn Invoke(TArg0 arg0, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4)
@@ -62,7 +62,7 @@ namespace UnityUtilities.SerializableDataHelpers
} }
} }
[System.Serializable] [Serializable]
public class SerializableFunc<TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TReturn> : SerializableFuncBase<Func<TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TReturn>> public class SerializableFunc<TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TReturn> : SerializableFuncBase<Func<TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TReturn>>
{ {
public TReturn Invoke(TArg0 arg0, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5) public TReturn Invoke(TArg0 arg0, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5)
@@ -72,7 +72,7 @@ namespace UnityUtilities.SerializableDataHelpers
} }
} }
[System.Serializable] [Serializable]
public class SerializableFunc<TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TReturn> : SerializableFuncBase<Func<TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TReturn>> public class SerializableFunc<TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TReturn> : SerializableFuncBase<Func<TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TReturn>>
{ {
public TReturn Invoke(TArg0 arg0, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6) public TReturn Invoke(TArg0 arg0, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6)
@@ -82,7 +82,7 @@ namespace UnityUtilities.SerializableDataHelpers
} }
} }
[System.Serializable] [Serializable]
public class SerializableFunc<TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TReturn> : SerializableFuncBase<Func<TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TReturn>> public class SerializableFunc<TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TReturn> : SerializableFuncBase<Func<TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TReturn>>
{ {
public TReturn Invoke(TArg0 arg0, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7) public TReturn Invoke(TArg0 arg0, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7)
@@ -92,7 +92,7 @@ namespace UnityUtilities.SerializableDataHelpers
} }
} }
[System.Serializable] [Serializable]
public class SerializableFunc<TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TReturn> : SerializableFuncBase<Func<TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TReturn>> public class SerializableFunc<TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TReturn> : SerializableFuncBase<Func<TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TReturn>>
{ {
public TReturn Invoke(TArg0 arg0, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8) public TReturn Invoke(TArg0 arg0, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8)
@@ -102,7 +102,7 @@ namespace UnityUtilities.SerializableDataHelpers
} }
} }
[System.Serializable] [Serializable]
public class SerializableFunc<TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TReturn> : SerializableFuncBase<Func<TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TReturn>> public class SerializableFunc<TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TReturn> : SerializableFuncBase<Func<TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TReturn>>
{ {
public TReturn Invoke(TArg0 arg0, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8, TArg9 arg9) public TReturn Invoke(TArg0 arg0, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8, TArg9 arg9)
@@ -112,7 +112,7 @@ namespace UnityUtilities.SerializableDataHelpers
} }
} }
[System.Serializable] [Serializable]
public class SerializableFunc<TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TReturn> : SerializableFuncBase<Func<TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TReturn>> public class SerializableFunc<TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TReturn> : SerializableFuncBase<Func<TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TReturn>>
{ {
public TReturn Invoke(TArg0 arg0, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8, TArg9 arg9, TArg10 arg10) public TReturn Invoke(TArg0 arg0, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8, TArg9 arg9, TArg10 arg10)
@@ -122,7 +122,7 @@ namespace UnityUtilities.SerializableDataHelpers
} }
} }
[System.Serializable] [Serializable]
public class SerializableFunc<TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TReturn> : SerializableFuncBase<Func<TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TReturn>> public class SerializableFunc<TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TReturn> : SerializableFuncBase<Func<TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TReturn>>
{ {
public TReturn Invoke(TArg0 arg0, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8, TArg9 arg9, TArg10 arg10, TArg11 arg11) public TReturn Invoke(TArg0 arg0, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, TArg6 arg6, TArg7 arg7, TArg8 arg8, TArg9 arg9, TArg10 arg10, TArg11 arg11)
@@ -132,7 +132,7 @@ namespace UnityUtilities.SerializableDataHelpers
} }
} }
[System.Serializable] [Serializable]
public class SerializableFunc<TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TReturn> : public class SerializableFunc<TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TReturn> :
SerializableFuncBase<Func<TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TReturn>> SerializableFuncBase<Func<TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TReturn>>
{ {
@@ -143,7 +143,7 @@ namespace UnityUtilities.SerializableDataHelpers
} }
} }
[System.Serializable] [Serializable]
public class SerializableFunc<TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TReturn> : public class SerializableFunc<TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TReturn> :
SerializableFuncBase<Func<TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TReturn>> SerializableFuncBase<Func<TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TReturn>>
{ {
@@ -154,7 +154,7 @@ namespace UnityUtilities.SerializableDataHelpers
} }
} }
[System.Serializable] [Serializable]
public class SerializableFunc<TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TReturn> : public class SerializableFunc<TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TReturn> :
SerializableFuncBase<Func<TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TReturn>> SerializableFuncBase<Func<TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TReturn>>
{ {
@@ -165,7 +165,7 @@ namespace UnityUtilities.SerializableDataHelpers
} }
} }
[System.Serializable] [Serializable]
public class SerializableFunc<TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15, TReturn> : public class SerializableFunc<TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15, TReturn> :
SerializableFuncBase<Func<TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15, TReturn>> SerializableFuncBase<Func<TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15, TReturn>>
{ {

View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: fe4625ec820a55848834d700960d1a9f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 4bd647a4a04c7f947afa36dc0ab3e8bf
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: a05eff3308be0b2489425421e455c65f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -4,9 +4,9 @@ using System.Reflection;
using UnityEngine; using UnityEngine;
using Object = UnityEngine.Object; using Object = UnityEngine.Object;
namespace UnityUtilities.SerializableDataHelpers namespace SerializableFunc.Runtime
{ {
[System.Serializable] [Serializable]
public abstract class SerializableFuncBase<TFuncType> public abstract class SerializableFuncBase<TFuncType>
where TFuncType : Delegate where TFuncType : Delegate
{ {