using System;
using System.Linq;
using UnityEngine;
using Object = UnityEngine.Object;
namespace SerializableCallback
{
///
/// https://github.com/Siccity/SerializableCallback
///
///
public abstract class SerializableCallbackBase : SerializableCallbackBase
{
///
/// https://github.com/Siccity/SerializableCallback
///
public InvokableCallbackBase func;
///
/// https://github.com/Siccity/SerializableCallback
///
public override void ClearCache()
{
base.ClearCache();
func = null;
}
///
/// https://github.com/Siccity/SerializableCallback
///
///
protected InvokableCallbackBase GetPersistentMethod()
{
Type[] types = new Type[ArgTypes.Length + 1];
Array.Copy(ArgTypes, types, ArgTypes.Length);
types[types.Length - 1] = typeof(TReturn);
Type genericType = null;
switch (types.Length)
{
case 1:
genericType = typeof(InvokableCallback<>).MakeGenericType(types);
break;
case 2:
genericType = typeof(InvokableCallback<,>).MakeGenericType(types);
break;
case 3:
genericType = typeof(InvokableCallback<, ,>).MakeGenericType(types);
break;
case 4:
genericType = typeof(InvokableCallback<, , ,>).MakeGenericType(types);
break;
case 5:
genericType = typeof(InvokableCallback<, , , ,>).MakeGenericType(types);
break;
default:
throw new ArgumentException(types.Length + "args");
}
return Activator.CreateInstance(genericType, new object[] { target, methodName }) as InvokableCallbackBase;
}
}
/// An inspector-friendly serializable function
[System.Serializable]
public abstract class SerializableCallbackBase : ISerializationCallbackReceiver
{
/// Target object
public Object target { get { return _target; } set { _target = value; ClearCache(); } }
/// Target method name
public string methodName { get { return _methodName; } set { _methodName = value; ClearCache(); } }
///
/// https://github.com/Siccity/SerializableCallback
///
public object[] Args { get { return args != null ? args : args = _args.Select(x => x.GetValue()).ToArray(); } }
///
/// https://github.com/Siccity/SerializableCallback
///
public object[] args;
///
/// https://github.com/Siccity/SerializableCallback
///
public Type[] ArgTypes { get { return argTypes != null ? argTypes : argTypes = _args.Select(x => Arg.RealType(x.argType)).ToArray(); } }
///
/// https://github.com/Siccity/SerializableCallback
///
public Type[] argTypes;
///
/// https://github.com/Siccity/SerializableCallback
///
public bool dynamic { get { return _dynamic; } set { _dynamic = value; ClearCache(); } }
///
/// https://github.com/Siccity/SerializableCallback
///
[SerializeField] protected Object _target;
///
/// https://github.com/Siccity/SerializableCallback
///
[SerializeField] protected string _methodName;
///
/// https://github.com/Siccity/SerializableCallback
///
[SerializeField] protected Arg[] _args;
///
/// https://github.com/Siccity/SerializableCallback
///
[SerializeField] protected bool _dynamic;
#pragma warning disable 0414
[SerializeField] private string _typeName;
#pragma warning restore 0414
[SerializeField] private bool dirty;
#if UNITY_EDITOR
///
/// https://github.com/Siccity/SerializableCallback
///
protected SerializableCallbackBase()
{
_typeName = base.GetType().AssemblyQualifiedName;
}
#endif
///
/// https://github.com/Siccity/SerializableCallback
///
public virtual void ClearCache()
{
argTypes = null;
args = null;
}
///
/// https://github.com/Siccity/SerializableCallback
///
///
///
///
///
public void SetMethod(Object target, string methodName, bool dynamic, params Arg[] args)
{
_target = target;
_methodName = methodName;
_dynamic = dynamic;
_args = args;
ClearCache();
}
///
/// https://github.com/Siccity/SerializableCallback
///
protected abstract void Cache();
///
/// https://github.com/Siccity/SerializableCallback
///
public void OnBeforeSerialize()
{
#if UNITY_EDITOR
if (dirty) { ClearCache(); dirty = false; }
#endif
}
///
/// https://github.com/Siccity/SerializableCallback
///
public void OnAfterDeserialize()
{
#if UNITY_EDITOR
_typeName = base.GetType().AssemblyQualifiedName;
#endif
}
}
///
/// https://github.com/Siccity/SerializableCallback
///
[System.Serializable]
public struct Arg
{
///
/// https://github.com/Siccity/SerializableCallback
///
public enum ArgType
{
///
/// https://github.com/Siccity/SerializableCallback
///
Unsupported,
///
/// https://github.com/Siccity/SerializableCallback
///
Bool,
///
/// https://github.com/Siccity/SerializableCallback
///
Int,
///
/// https://github.com/Siccity/SerializableCallback
///
Float,
///
/// https://github.com/Siccity/SerializableCallback
///
String,
///
/// https://github.com/Siccity/SerializableCallback
///
Object
}
///
/// https://github.com/Siccity/SerializableCallback
///
public bool boolValue;
///
/// https://github.com/Siccity/SerializableCallback
///
public int intValue;
///
/// https://github.com/Siccity/SerializableCallback
///
public float floatValue;
///
/// https://github.com/Siccity/SerializableCallback
///
public string stringValue;
///
/// https://github.com/Siccity/SerializableCallback
///
public Object objectValue;
///
/// https://github.com/Siccity/SerializableCallback
///
public ArgType argType;
///
/// https://github.com/Siccity/SerializableCallback
///
///
public object GetValue()
{
return GetValue(argType);
}
///
/// https://github.com/Siccity/SerializableCallback
///
///
///
public object GetValue(ArgType type)
{
switch (type)
{
case ArgType.Bool:
return boolValue;
case ArgType.Int:
return intValue;
case ArgType.Float:
return floatValue;
case ArgType.String:
return stringValue;
case ArgType.Object:
return objectValue;
default:
return null;
}
}
///
/// https://github.com/Siccity/SerializableCallback
///
///
///
public static Type RealType(ArgType type)
{
switch (type)
{
case ArgType.Bool:
return typeof(bool);
case ArgType.Int:
return typeof(int);
case ArgType.Float:
return typeof(float);
case ArgType.String:
return typeof(string);
case ArgType.Object:
return typeof(Object);
default:
return null;
}
}
///
/// https://github.com/Siccity/SerializableCallback
///
///
///
public static ArgType FromRealType(Type type)
{
if (type == typeof(bool)) return ArgType.Bool;
else if (type == typeof(int)) return ArgType.Int;
else if (type == typeof(float)) return ArgType.Float;
else if (type == typeof(String)) return ArgType.String;
else if (type == typeof(Object)) return ArgType.Object;
else return ArgType.Unsupported;
}
///
/// https://github.com/Siccity/SerializableCallback
///
///
///
public static bool IsSupported(Type type)
{
return FromRealType(type) != ArgType.Unsupported;
}
}
}