UP-Viagg-io/Viagg-io/Assets/Packages/MyBT/BT/Compiler/Function/MethodImplementation.cs

130 lines
5.3 KiB
C#
Raw Normal View History

2024-01-19 16:30:05 +01:00
//============= 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;
}
}
}