UP-Viagg-io/Viagg-io/Assets/Packages/MyBT/BT/Compiler/Task/TaskParameter.cs

205 lines
7.7 KiB
C#

//============= 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;
using System.Globalization;
namespace MyBT {
[System.Serializable]
public class TaskParameter : ScriptableObject {
// TypeCode.DBNull is considered invalid or undefined
[SerializeField]
public System.TypeCode valType = TypeCode.DBNull;
// public object valValue = null;
public object valValue {
set {
if (value == null) {
valSerialized = "n";
return;
}
var type = value.GetType();
if (type == typeof(int))
valSerialized = "i"+value.ToString();
else if (type == typeof(float))
valSerialized = "f"+value.ToString();
else if (type == typeof(string))
valSerialized = "s"+value;
// else if (type == typeof(Color)) {
// Color32 c = (Color)valValue;
// uint v = (byte)c.r + (byte)c.g<<8 + (byte)c.b<<16 + (byte)c.a<<24;
// valSerialized = "c" + v;
// }
// else if (type == typeof())
else if (type == typeof(Vector3)) {
Vector3 v = (Vector3)value;
valSerialized = "v" + v.x + "|" +v.y + "|" + v.z;
}
}
get {
if (valSerialized.Length == 0)
return null;
char type = valSerialized[0];
if (type == 'n')
return null;
else if (type == 'i')
return int.Parse(valSerialized.Substring(1));
else if (type == 'f')
return float.Parse(valSerialized.Substring(1));
else if (type == 's')
return valSerialized.Substring(1);
// else if (type == 'c') {
// byte v = byte.Parse(valSerialized.Substring(1));
// Color c = new Color32(v & 0xFF, (v>>8) & 0xFF, (v>>16) & 0xFF,(v>>24) & 0xFF);
// valValue = c;
// }
else if (type == 'v') {
string[] v = valSerialized.Substring(1).Split('|');
return new Vector3(float.Parse(v[0]), float.Parse(v[1]), float.Parse(v[2]));
}
return null;
}
}
[SerializeField, HideInInspector]
private string valSerialized = "";
/// <summary>
/// init taskparameters from string
/// return null on success, return string with error details on error
/// </summary>
/// <param name="stringValue"></param>
/// <returns></returns>
public string Init(string stringValue) {
bool boolValue;
int intValue;
float floatValue;
Type thisType = Type.GetType(stringValue);
if (thisType != null) {
Debug.Log("TaskScriptParser.ParseValue: thisType " + thisType.FullName);
}
NumberStyles style = NumberStyles.Any;
CultureInfo culture = CultureInfo.InvariantCulture;
// Place checks higher in if-else statement to give higher priority to type.
if (bool.TryParse(stringValue, out boolValue)) {
valType = TypeCode.Boolean;
valValue = boolValue;
return null;
}
else if (int.TryParse(stringValue, style, culture, out intValue)) {
valType = TypeCode.Int32;
valValue = intValue;
return null;
}
else if (float.TryParse(stringValue, style, culture, out floatValue)) {
valType = TypeCode.Single;
valValue = floatValue;
return null;
}
// handle string and enum
else {
// is null value
if (stringValue == "null") {
valType = TypeCode.Empty;
valValue = null;
return null;
}
// is empty value
if (stringValue == "") {
// no content
return null;
}
string[] splitValue = stringValue.Split('"');
// is string with ""
if (splitValue.Length == 3) {
valType = TypeCode.String;
valValue = splitValue[1];
return null;
}
// is enum? -> currently dont handle enums
else {
// Debug.Log($"TaskParameter: detected enum: {stringValue}");
string[] enumSplit = stringValue.Split('.');
try {
string enumNamespace = null;
System.Type enumType = null;
string convertValue = null;
// object underlyingValue = Convert.ChangeType(value, Enum.GetUnderlyingType(value.GetType()));
if (enumSplit.Length == 3) {
enumNamespace = enumSplit[0];
enumType = GetEnumType(enumSplit[1]);
convertValue = enumSplit[2];
} else if (enumSplit.Length == 2) {
enumType = GetEnumType(enumSplit[0]);
convertValue = enumSplit[1];
}
object enumValue = Enum.Parse(enumType, convertValue);
valType = TypeCode.Int32;
valValue = (int)enumValue;
// Debug.Log($"TaskParameter: detected enum: {enumType} {enumValue} string: {stringValue} type: {valType} value: {valValue}");
return null;
}
catch (Exception e) {
// Debug.LogError("failed conversion of string '" + stringValue + "' error: " + e.ToString());
return "failed conversion of string '" + stringValue + "' error: " + e.ToString();
}
}
}
}
public bool IsValid() {
return (valType != TypeCode.DBNull);
}
public static Assembly[] GetEnumAssembly (string enumNamespace=null) {
if (enumNamespace != null) {
try {
Assembly assembly = System.Reflection.Assembly.Load(enumNamespace);
if (assembly != null) {
return new Assembly[] {assembly};
}
}
catch { } // ignore load error
}
return AppDomain.CurrentDomain.GetAssemblies();
}
public static Type GetEnumType(string enumName, string enumNamespace=null) {
foreach (var assembly in GetEnumAssembly(enumNamespace)) {
var type = assembly.GetType(enumName);
if (type == null)
continue;
if (type.IsEnum)
return type;
}
return null;
}
public TaskParameter Duplicate () {
TaskParameter tp = ScriptableObject.CreateInstance<TaskParameter>();
tp.valType = valType;
tp.valSerialized = valSerialized;
tp.valValue = valValue;
return tp;
}
}
}