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

113 lines
5.5 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.Reflection;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace MyBT
{
[System.Serializable]
public class MethodScanner {
public static bool debugActive = false;
public static readonly BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy | BindingFlags.Instance | BindingFlags.Static | BindingFlags.InvokeMethod | BindingFlags.GetField;
private static bool IsGenerated (DictionaryOfStringAndDictionaryOfStringAndMethodImplementation methods) {
if (methods != null) {
int count = 0;
foreach (KeyValuePair<string, DictionaryOfStringAndMethodImplementation> fileKvp in methods) {
if (fileKvp.Value != null) {
foreach (KeyValuePair<string, MethodImplementation> functionKvp in fileKvp.Value) {
count += 1;
}
}
}
return (count > 0);
}
return false;
}
public static void Reset(ref DictionaryOfStringAndDictionaryOfStringAndMethodImplementation methods) {
if (methods != null) {
foreach (KeyValuePair<string, DictionaryOfStringAndMethodImplementation> fileKvp in methods) {
if (fileKvp.Value != null) {
foreach (KeyValuePair<string, MethodImplementation> functionKvp in fileKvp.Value) {
#if UNITY_EDITOR
UnityEngine.Object.DestroyImmediate(functionKvp.Value);
#else
UnityEngine.Object.Destroy(functionKvp.Value);
#endif
}
}
}
methods = null;
}
}
public static bool CheckComponents(GameObject checkObject, bool readAllComponents, ref DictionaryOfStringAndDictionaryOfStringAndMethodImplementation methods) {
bool success = true;
methods = new DictionaryOfStringAndDictionaryOfStringAndMethodImplementation();
foreach (Component component in checkObject.GetComponents<Component>()) {
if (debugActive) Debug.Log("MethodScanner.CheckComponents: Checking Component "+component.GetType().Name+" on "+component.gameObject.name);
if (component != null) {
MemberInfo[] members = component.GetType().GetMembers(bindingFlags);
foreach (MemberInfo memberInfo in members) {
if (memberInfo.IsDefined(typeof(Task), true)) {
MethodImplementation methodImplementation = ScriptableObject.CreateInstance<MethodImplementation>();
methodImplementation.Init(memberInfo, component);
if (debugActive) Debug.Log("MethodScanner.CheckComponents: Method found with name "+methodImplementation.fullName + " " + methodImplementation.parameters);
if (methodImplementation.HasImplementation()) {
success &= AddTaskImplementation(methodImplementation, ref methods);
}
}
else {
if (readAllComponents) {
MethodImplementation methodImplementation = ScriptableObject.CreateInstance<MethodImplementation>();
methodImplementation.Init(memberInfo, component);
if (debugActive) Debug.Log("MethodScanner.CheckComponents: Method found with name "+methodImplementation.fullName + " " + methodImplementation.parameters);
if (methodImplementation.HasImplementation()) {
success &= AddTaskImplementation(methodImplementation, ref methods);
}
}
}
}
}
}
return IsGenerated(methods) && success;
}
public static bool AddTaskImplementation(MethodImplementation methodImplementation, ref DictionaryOfStringAndDictionaryOfStringAndMethodImplementation methods) {
string taskName = methodImplementation.fullName;
string paramtersAsString = methodImplementation.parameters.ToString();
// generate unique key dictionarys
if (!methods.ContainsKey(taskName)) {
methods[taskName] = new DictionaryOfStringAndMethodImplementation(); //Dictionary<string, MethodImplementation>();
}
// add the list
if (!methods[taskName].ContainsKey(paramtersAsString)) {
methods[taskName][paramtersAsString] = methodImplementation;
}
// we have this exact implementation already in the dict, should normally not happen, maybe if you have 2 scripts of the same type on the object?
else {
Debug.LogWarning("Duplicate function: " + taskName + " with parms: " + paramtersAsString);
return false;
}
return true;
}
}
}