using System; using System.Linq; using System.Reflection; using Chronos.Reflection.Internal; using UnityEngine; using UnityObject = UnityEngine.Object; namespace Chronos.Reflection { [Serializable] public class UnityMethod : UnityMember, ISerializationCallbackReceiver { /// /// The underlying reflected method. /// public MethodInfo methodInfo { get; private set; } /// /// Whether the reflected method is an extension method. /// public bool isExtension { get; private set; } [SerializeField] private string[] _parameterTypes; private Type[] __parameterTypes; /// /// The types of the method's parameters. /// public Type[] parameterTypes { get { return __parameterTypes; } set { __parameterTypes = value; isReflected = false; } } public void OnAfterDeserialize() { if (_parameterTypes != null) { parameterTypes = _parameterTypes.Select(typeName => TypeSerializer.Deserialize(typeName)).ToArray(); } } public void OnBeforeSerialize() { if (parameterTypes != null) { _parameterTypes = parameterTypes.Select(type => TypeSerializer.Serialize(type)).ToArray(); } } #region Constructors public UnityMethod() { } public UnityMethod(string name) : base(name) { } public UnityMethod(string name, UnityObject target) : base(name, target) { } public UnityMethod(string component, string name) : base(component, name) { } public UnityMethod(string component, string name, UnityObject target) : base(component, name, target) { } public UnityMethod(string name, Type[] parameterTypes) : base(name) { this.parameterTypes = parameterTypes; } public UnityMethod(string name, Type[] parameterTypes, UnityObject target) : this(name, parameterTypes) { this.target = target; Reflect(); } public UnityMethod(string component, string name, Type[] parameterTypes) : base(component, name) { this.parameterTypes = parameterTypes; } public UnityMethod(string component, string name, Type[] parameterTypes, UnityObject target) : this(component, name, parameterTypes) { this.target = target; Reflect(); } #endregion /// public override void Reflect() { EnsureAssigned(); EnsureTargeted(); methodInfo = UnityMemberHelper.ReflectMethod(reflectionTarget, name, parameterTypes); isExtension = methodInfo.IsExtension(); isReflected = true; } /// /// Invokes the method with any number of arguments of any type and returns its return value, or null if there isn't any (void). /// public object Invoke(params object[] parameters) { EnsureReflected(); return UnityMemberHelper.InvokeMethod(reflectionTarget, methodInfo, isExtension, parameters); } /// /// Invokes the method with any number of arguments of any type and returns its return value casted to the specified type, or null if there isn't any (void). /// public T Invoke(params object[] parameters) { return (T)Invoke(parameters); } /// /// The return type of the reflected method. /// public Type returnType { get { EnsureReflected(); return methodInfo.ReturnType; } } public override bool Corresponds(UnityMember other) { return other is UnityMethod && base.Corresponds(other) && parameterTypes.SequenceEqual(((UnityMethod)other).parameterTypes); } } }