130 lines
5.3 KiB
C#
130 lines
5.3 KiB
C#
//============= Copyright (c) Ludic GmbH, All rights reserved. ==============
|
|
//
|
|
// Purpose: Part of the My Behaviour Tree Code
|
|
//
|
|
//=============================================================================
|
|
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Reflection;
|
|
using UnityEngine;
|
|
|
|
namespace MyBT {
|
|
[System.Serializable]
|
|
public class MethodImplementation : ScriptableObject {
|
|
bool debug = false;
|
|
|
|
// CANNOT BE SERIALIZED!
|
|
public MemberInfo memberInfo;
|
|
|
|
[SerializeField]
|
|
public object implementation;
|
|
[SerializeField]
|
|
public TaskParameterGroup parameters;
|
|
|
|
[SerializeField]
|
|
public string fullName;
|
|
[SerializeField]
|
|
public string namespaceName;
|
|
[SerializeField]
|
|
public string className;
|
|
[SerializeField]
|
|
public string memberName;
|
|
|
|
public void Init (MemberInfo _memberInfo, Component component) {
|
|
// https://stackoverflow.com/questions/607178/how-enumerate-all-classes-with-custom-class-attribute
|
|
memberInfo = _memberInfo;
|
|
|
|
System.Type classType = memberInfo.DeclaringType;
|
|
string namespaceClassMemberName = classType.FullName + "." + memberInfo.Name;
|
|
|
|
switch (memberInfo.MemberType) {
|
|
case MemberTypes.Method:
|
|
//MethodInfo methodInfo = (MethodInfo)memberInfo;
|
|
|
|
fullName = namespaceClassMemberName;
|
|
namespaceName = classType.Namespace;
|
|
className = classType.Name;
|
|
memberName = memberInfo.Name;
|
|
|
|
parameters = ScriptableObject.CreateInstance<TaskParameterGroup>();
|
|
parameters.Init(memberInfo);
|
|
implementation = component;
|
|
|
|
break;
|
|
default:
|
|
//Debug.LogWarning("TaskImplementation.TaskImplementation: Unknown MemberType " + memberInfo.MemberType);
|
|
break;
|
|
}
|
|
}
|
|
|
|
public bool HasImplementation() {
|
|
return (implementation != null);
|
|
}
|
|
|
|
public override string ToString() {
|
|
return "name='" + this.fullName + "' : implementation " + (this.implementation != null); // + ", task " + (this.task != null);
|
|
}
|
|
|
|
public bool GetAction(TaskParameterGroup taskParameterGroup, out Action returnAction) {
|
|
returnAction = null;
|
|
|
|
if (memberInfo == null) {
|
|
Debug.LogError("undefined memberInfo in MethodImplementation");
|
|
return false;
|
|
}
|
|
|
|
returnAction = null;
|
|
|
|
List<TaskParameter> executionTaskParameters = taskParameterGroup.GetAll();
|
|
if (executionTaskParameters.Count != parameters.Count) {
|
|
Debug.LogWarning("TaskImplementation.ExecuteTask: invalid parameter count: " + this.fullName + " " + executionTaskParameters.Count + " " + parameters.Count);
|
|
return false;
|
|
}
|
|
|
|
// verify and convert parameters
|
|
List<object> parametersList = new List<object>();
|
|
for (int i = 0; i < parameters.Count; i++) {
|
|
if (executionTaskParameters[i].valType == parameters[i].valType) {
|
|
try {
|
|
parametersList.Add(executionTaskParameters[i].valValue);
|
|
}
|
|
catch (Exception e) {
|
|
Debug.LogError("TaskImplementation.ExecuteTask: cannot convert parameter: " + i + " " + executionTaskParameters[i] + " : " + e.ToString());
|
|
return false;
|
|
}
|
|
}
|
|
else {
|
|
//Debug.LogWarning("TaskImplementation.ExecuteTask: trying conversion of parameter: " + i + " " + executionTaskParameters[i] + " " + executionTaskParameters[i].valType + " " + parameterTypesNew[i].valType);
|
|
object convertedValue = Convert.ChangeType(executionTaskParameters[i].valValue, parameters[i].valType);
|
|
parametersList.Add(convertedValue);
|
|
}
|
|
}
|
|
object[] executionParameters = parametersList.ToArray();
|
|
|
|
if (debug) Debug.Log("MethodImplementation.GetAction: member "+memberInfo.Name+" parameters "+taskParameterGroup);
|
|
|
|
// call a method
|
|
MethodInfo methodInfo = (MethodInfo)memberInfo;
|
|
if (methodInfo.ReturnType == typeof(void)) {
|
|
if (this.parameters.Count > 0) {
|
|
returnAction = () => methodInfo.Invoke(implementation, executionParameters);
|
|
}
|
|
else {
|
|
returnAction = System.Delegate.CreateDelegate(typeof(System.Action), implementation, methodInfo) as System.Action;
|
|
}
|
|
}
|
|
else {
|
|
// for the moment dont handle methods with return value differently then the ones without return value
|
|
if (this.parameters.Count > 0) {
|
|
returnAction = () => methodInfo.Invoke(implementation, executionParameters);
|
|
}
|
|
else {
|
|
returnAction = System.Delegate.CreateDelegate(typeof(System.Action), implementation, methodInfo) as System.Action;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
} |