170 lines
5.2 KiB
C#
170 lines
5.2 KiB
C#
// (c) copyright Hutong Games, LLC 2010-2012. All rights reserved.
|
|
|
|
using System;
|
|
using System.Reflection;
|
|
using UnityEngine;
|
|
using System.Collections.Generic;
|
|
|
|
namespace HutongGames.PlayMaker.Actions
|
|
{
|
|
[ActionCategory(ActionCategory.ScriptControl)]
|
|
[Tooltip("Call a static method in a class.")]
|
|
public class CallStaticMethod : FsmStateAction
|
|
{
|
|
[Tooltip("Full path to the class that contains the static method.")]
|
|
public FsmString className;
|
|
|
|
[Tooltip("The static method to call.")]
|
|
public FsmString methodName;
|
|
|
|
[Tooltip("Method parameters. NOTE: these must match the method's signature!")]
|
|
public FsmVar[] parameters;
|
|
|
|
[ActionSection("Store Result")]
|
|
|
|
[UIHint(UIHint.Variable)]
|
|
[Tooltip("Store the result of the method call.")]
|
|
public FsmVar storeResult;
|
|
|
|
[Tooltip("Repeat every frame.")]
|
|
public bool everyFrame;
|
|
|
|
private Type cachedType;
|
|
private string cachedClassName;
|
|
private string cachedMethodName;
|
|
private MethodInfo cachedMethodInfo;
|
|
private ParameterInfo[] cachedParameterInfo;
|
|
private object[] parametersArray;
|
|
private string errorString;
|
|
|
|
public override void OnEnter()
|
|
{
|
|
parametersArray = new object[parameters.Length];
|
|
|
|
DoMethodCall();
|
|
|
|
if (!everyFrame)
|
|
{
|
|
Finish();
|
|
}
|
|
}
|
|
|
|
public override void OnUpdate()
|
|
{
|
|
DoMethodCall();
|
|
}
|
|
|
|
private void DoMethodCall()
|
|
{
|
|
if (className == null || string.IsNullOrEmpty(className.Value))
|
|
{
|
|
Finish();
|
|
return;
|
|
}
|
|
|
|
if (cachedClassName != className.Value || cachedMethodName != methodName.Value)
|
|
{
|
|
errorString = string.Empty;
|
|
if(!DoCache())
|
|
{
|
|
Debug.LogError(errorString);
|
|
Finish();
|
|
return;
|
|
}
|
|
}
|
|
|
|
object result = null;
|
|
if (cachedParameterInfo.Length == 0)
|
|
{
|
|
result = cachedMethodInfo.Invoke(null, null);
|
|
}
|
|
else
|
|
{
|
|
for (var i = 0; i < parameters.Length; i++)
|
|
{
|
|
var parameter = parameters[i];
|
|
parameter.UpdateValue();
|
|
parametersArray[i] = parameter.GetValue();
|
|
}
|
|
|
|
result = cachedMethodInfo.Invoke(null, parametersArray);
|
|
}
|
|
storeResult.SetValue(result);
|
|
}
|
|
|
|
private bool DoCache()
|
|
{
|
|
cachedType = ReflectionUtils.GetGlobalType(className.Value);
|
|
if (cachedType == null)
|
|
{
|
|
errorString += "Class is invalid: " + className.Value + "\n";
|
|
Finish();
|
|
return false;
|
|
}
|
|
cachedClassName = className.Value;
|
|
|
|
#if NETFX_CORE
|
|
cachedMethodInfo = cachedType.GetTypeInfo().GetDeclaredMethod(methodName.Value);
|
|
#else
|
|
var types = new List<Type>( capacity: parameters.Length );
|
|
foreach ( var each in parameters ) {
|
|
types.Add( each.RealType );
|
|
}
|
|
|
|
cachedMethodInfo = cachedType.GetMethod(methodName.Value, types.ToArray());
|
|
#endif
|
|
if (cachedMethodInfo == null)
|
|
{
|
|
errorString += "Invalid Method Name or Parameters: " + methodName.Value +"\n";
|
|
Finish();
|
|
return false;
|
|
}
|
|
|
|
cachedMethodName = methodName.Value;
|
|
cachedParameterInfo = cachedMethodInfo.GetParameters();
|
|
return true;
|
|
}
|
|
|
|
public override string ErrorCheck()
|
|
{
|
|
errorString = string.Empty;
|
|
DoCache();
|
|
|
|
if (!string.IsNullOrEmpty(errorString))
|
|
{
|
|
return errorString;
|
|
}
|
|
|
|
if (parameters.Length != cachedParameterInfo.Length)
|
|
{
|
|
return "Parameter count does not match method.\nMethod has " + cachedParameterInfo.Length + " parameters.\nYou specified " +parameters.Length + " paramaters.";
|
|
}
|
|
|
|
for (var i = 0; i < parameters.Length; i++)
|
|
{
|
|
var p = parameters[i];
|
|
var paramType = p.RealType;
|
|
var paramInfoType = cachedParameterInfo[i].ParameterType;
|
|
if (!ReferenceEquals(paramType, paramInfoType ))
|
|
{
|
|
return "Parameters do not match method signature.\nParameter " + (i + 1) + " (" + paramType + ") should be of type: " + paramInfoType;
|
|
}
|
|
}
|
|
|
|
if (ReferenceEquals(cachedMethodInfo.ReturnType, typeof(void)))
|
|
{
|
|
if (!string.IsNullOrEmpty(storeResult.variableName))
|
|
{
|
|
return "Method does not have return.\nSpecify 'none' in Store Result.";
|
|
}
|
|
}
|
|
else if (!ReferenceEquals(cachedMethodInfo.ReturnType,storeResult.RealType))
|
|
{
|
|
return "Store Result is of the wrong type.\nIt should be of type: " + cachedMethodInfo.ReturnType;
|
|
}
|
|
|
|
return string.Empty;
|
|
}
|
|
}
|
|
}
|