2020-08-22 00:16:05 +10:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Reflection;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using MelonLoader;
|
|
|
|
|
using UnhollowerBaseLib;
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
|
|
|
|
|
namespace Explorer
|
|
|
|
|
{
|
2020-08-29 21:15:54 +10:00
|
|
|
|
public abstract class CacheObjectBase
|
2020-08-22 00:16:05 +10:00
|
|
|
|
{
|
|
|
|
|
public object Value;
|
2020-09-01 18:03:44 +10:00
|
|
|
|
public string ValueTypeName;
|
2020-09-06 16:55:39 +10:00
|
|
|
|
public Type ValueType;
|
2020-08-22 00:16:05 +10:00
|
|
|
|
|
2020-09-01 18:03:44 +10:00
|
|
|
|
public MemberInfo MemInfo { get; set; }
|
2020-08-22 00:16:05 +10:00
|
|
|
|
public Type DeclaringType { get; set; }
|
|
|
|
|
public object DeclaringInstance { get; set; }
|
2020-09-09 19:15:47 +10:00
|
|
|
|
|
|
|
|
|
public bool HasParameters => m_arguments != null && m_arguments.Length > 0;
|
|
|
|
|
public bool m_evaluated = false;
|
|
|
|
|
public bool m_isEvaluating;
|
|
|
|
|
public ParameterInfo[] m_arguments = new ParameterInfo[0];
|
|
|
|
|
public string[] m_argumentInput = new string[0];
|
2020-09-01 18:03:44 +10:00
|
|
|
|
|
2020-09-07 17:05:37 +10:00
|
|
|
|
public string ReflectionException { get; set; }
|
|
|
|
|
|
2020-09-01 18:03:44 +10:00
|
|
|
|
public string RichTextName => m_richTextName ?? GetRichTextName();
|
|
|
|
|
private string m_richTextName;
|
2020-08-22 00:16:05 +10:00
|
|
|
|
|
2020-08-24 01:42:19 +10:00
|
|
|
|
public bool CanWrite
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
2020-09-01 18:03:44 +10:00
|
|
|
|
if (MemInfo is FieldInfo fi)
|
2020-08-24 01:42:19 +10:00
|
|
|
|
return !(fi.IsLiteral && !fi.IsInitOnly);
|
2020-09-01 18:03:44 +10:00
|
|
|
|
else if (MemInfo is PropertyInfo pi)
|
2020-08-24 01:42:19 +10:00
|
|
|
|
return pi.CanWrite;
|
|
|
|
|
else
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public virtual void Init() { }
|
2020-08-22 00:16:05 +10:00
|
|
|
|
|
2020-09-10 18:02:41 +10:00
|
|
|
|
public abstract void DrawValue(Rect window, float width);
|
2020-09-01 18:03:44 +10:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Get CacheObject from only an object instance
|
|
|
|
|
/// Calls GetCacheObject(obj, memberInfo, declaringInstance) with (obj, null, null)</summary>
|
2020-08-29 21:15:54 +10:00
|
|
|
|
public static CacheObjectBase GetCacheObject(object obj)
|
2020-08-22 00:16:05 +10:00
|
|
|
|
{
|
|
|
|
|
return GetCacheObject(obj, null, null);
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-22 17:17:11 +10:00
|
|
|
|
/// <summary>
|
2020-09-01 18:03:44 +10:00
|
|
|
|
/// Get CacheObject from an object instance and provide the value type
|
|
|
|
|
/// Calls GetCacheObjectImpl directly</summary>
|
|
|
|
|
public static CacheObjectBase GetCacheObject(object obj, Type valueType)
|
|
|
|
|
{
|
|
|
|
|
return GetCacheObjectImpl(obj, null, null, valueType);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Get CacheObject from only a MemberInfo and declaring instance
|
|
|
|
|
/// Calls GetCacheObject(obj, memberInfo, declaringInstance) with (null, memberInfo, declaringInstance)</summary>
|
|
|
|
|
public static CacheObjectBase GetCacheObject(MemberInfo memberInfo, object declaringInstance)
|
2020-08-22 00:16:05 +10:00
|
|
|
|
{
|
2020-09-01 18:03:44 +10:00
|
|
|
|
return GetCacheObject(null, memberInfo, declaringInstance);
|
|
|
|
|
}
|
2020-08-29 21:15:54 +10:00
|
|
|
|
|
2020-09-01 18:03:44 +10:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Get CacheObject from either an object or MemberInfo, and don't provide the type.
|
|
|
|
|
/// This gets the type and then calls GetCacheObjectImpl</summary>
|
|
|
|
|
public static CacheObjectBase GetCacheObject(object obj, MemberInfo memberInfo, object declaringInstance)
|
|
|
|
|
{
|
2020-08-29 21:15:54 +10:00
|
|
|
|
Type type = null;
|
|
|
|
|
|
2020-09-06 16:55:39 +10:00
|
|
|
|
if (memberInfo != null)
|
2020-08-29 21:15:54 +10:00
|
|
|
|
{
|
|
|
|
|
if (memberInfo is FieldInfo fi)
|
|
|
|
|
{
|
|
|
|
|
type = fi.FieldType;
|
|
|
|
|
}
|
|
|
|
|
else if (memberInfo is PropertyInfo pi)
|
|
|
|
|
{
|
|
|
|
|
type = pi.PropertyType;
|
|
|
|
|
}
|
|
|
|
|
else if (memberInfo is MethodInfo mi)
|
|
|
|
|
{
|
|
|
|
|
type = mi.ReturnType;
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-09-06 16:55:39 +10:00
|
|
|
|
else if (obj != null)
|
|
|
|
|
{
|
|
|
|
|
type = ReflectionHelpers.GetActualType(obj);
|
|
|
|
|
}
|
2020-08-22 00:16:05 +10:00
|
|
|
|
|
2020-08-24 01:42:19 +10:00
|
|
|
|
if (type == null)
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-01 18:03:44 +10:00
|
|
|
|
return GetCacheObjectImpl(obj, memberInfo, declaringInstance, type);
|
2020-08-24 01:42:19 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2020-09-01 18:03:44 +10:00
|
|
|
|
/// Actual GetCacheObject implementation (private)
|
2020-08-24 01:42:19 +10:00
|
|
|
|
/// </summary>
|
2020-09-01 18:03:44 +10:00
|
|
|
|
private static CacheObjectBase GetCacheObjectImpl(object obj, MemberInfo memberInfo, object declaringInstance, Type valueType)
|
2020-08-24 01:42:19 +10:00
|
|
|
|
{
|
2020-08-29 21:15:54 +10:00
|
|
|
|
CacheObjectBase holder;
|
2020-08-24 01:42:19 +10:00
|
|
|
|
|
2020-09-09 19:15:47 +10:00
|
|
|
|
var pi = memberInfo as PropertyInfo;
|
|
|
|
|
var mi = memberInfo as MethodInfo;
|
|
|
|
|
|
|
|
|
|
// if PropertyInfo, check if can process args
|
|
|
|
|
if (pi != null && !CanProcessArgs(pi.GetIndexParameters()))
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-06 21:33:09 +10:00
|
|
|
|
// This is pretty ugly, could probably make a cleaner implementation.
|
|
|
|
|
// However, the only cleaner ways I can think of are slower and probably not worth it.
|
|
|
|
|
|
|
|
|
|
// Note: the order is somewhat important.
|
|
|
|
|
|
2020-09-09 19:15:47 +10:00
|
|
|
|
if (mi != null)
|
2020-08-29 21:15:54 +10:00
|
|
|
|
{
|
|
|
|
|
if (CacheMethod.CanEvaluate(mi))
|
|
|
|
|
{
|
|
|
|
|
holder = new CacheMethod();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (valueType == typeof(GameObject) || valueType == typeof(Transform))
|
2020-08-22 00:16:05 +10:00
|
|
|
|
{
|
2020-08-24 01:42:19 +10:00
|
|
|
|
holder = new CacheGameObject();
|
2020-08-22 00:16:05 +10:00
|
|
|
|
}
|
2020-08-28 00:45:34 +10:00
|
|
|
|
else if (valueType.IsPrimitive || valueType == typeof(string))
|
2020-08-22 00:16:05 +10:00
|
|
|
|
{
|
2020-08-24 01:42:19 +10:00
|
|
|
|
holder = new CachePrimitive();
|
2020-08-22 00:16:05 +10:00
|
|
|
|
}
|
2020-08-28 00:45:34 +10:00
|
|
|
|
else if (valueType.IsEnum)
|
2020-08-22 17:17:11 +10:00
|
|
|
|
{
|
2020-08-24 01:42:19 +10:00
|
|
|
|
holder = new CacheEnum();
|
2020-08-22 17:17:11 +10:00
|
|
|
|
}
|
2020-09-05 20:27:00 +10:00
|
|
|
|
else if (valueType == typeof(Vector2) || valueType == typeof(Vector3) || valueType == typeof(Vector4))
|
|
|
|
|
{
|
|
|
|
|
holder = new CacheVector();
|
|
|
|
|
}
|
|
|
|
|
else if (valueType == typeof(Quaternion))
|
|
|
|
|
{
|
|
|
|
|
holder = new CacheQuaternion();
|
|
|
|
|
}
|
|
|
|
|
else if (valueType == typeof(Color))
|
|
|
|
|
{
|
|
|
|
|
holder = new CacheColor();
|
|
|
|
|
}
|
|
|
|
|
else if (valueType == typeof(Rect))
|
|
|
|
|
{
|
|
|
|
|
holder = new CacheRect();
|
|
|
|
|
}
|
2020-09-06 21:33:09 +10:00
|
|
|
|
// must check this before IsEnumerable
|
2020-08-29 21:15:54 +10:00
|
|
|
|
else if (ReflectionHelpers.IsDictionary(valueType))
|
|
|
|
|
{
|
|
|
|
|
holder = new CacheDictionary();
|
|
|
|
|
}
|
2020-09-11 00:17:13 +10:00
|
|
|
|
else if (ReflectionHelpers.IsEnumerable(valueType) || ReflectionHelpers.IsCppEnumerable(valueType))
|
2020-09-06 21:33:09 +10:00
|
|
|
|
{
|
|
|
|
|
holder = new CacheList();
|
|
|
|
|
}
|
2020-08-22 17:17:11 +10:00
|
|
|
|
else
|
2020-08-22 00:16:05 +10:00
|
|
|
|
{
|
2020-08-22 17:17:11 +10:00
|
|
|
|
holder = new CacheOther();
|
2020-08-22 00:16:05 +10:00
|
|
|
|
}
|
|
|
|
|
|
2020-08-24 01:42:19 +10:00
|
|
|
|
holder.Value = obj;
|
2020-09-06 16:55:39 +10:00
|
|
|
|
holder.ValueType = valueType;
|
2020-09-01 18:03:44 +10:00
|
|
|
|
holder.ValueTypeName = valueType.FullName;
|
2020-08-24 01:42:19 +10:00
|
|
|
|
|
2020-08-22 00:16:05 +10:00
|
|
|
|
if (memberInfo != null)
|
|
|
|
|
{
|
2020-09-01 18:03:44 +10:00
|
|
|
|
holder.MemInfo = memberInfo;
|
2020-08-22 00:16:05 +10:00
|
|
|
|
holder.DeclaringType = memberInfo.DeclaringType;
|
2020-08-22 17:17:11 +10:00
|
|
|
|
holder.DeclaringInstance = declaringInstance;
|
2020-09-09 19:15:47 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pi != null)
|
|
|
|
|
{
|
|
|
|
|
holder.m_arguments = pi.GetIndexParameters();
|
|
|
|
|
}
|
|
|
|
|
else if (mi != null)
|
|
|
|
|
{
|
|
|
|
|
holder.m_arguments = mi.GetParameters();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
holder.m_argumentInput = new string[holder.m_arguments.Length];
|
2020-09-10 18:02:41 +10:00
|
|
|
|
|
|
|
|
|
holder.UpdateValue();
|
2020-08-22 00:16:05 +10:00
|
|
|
|
|
2020-08-24 01:42:19 +10:00
|
|
|
|
holder.Init();
|
2020-08-22 00:16:05 +10:00
|
|
|
|
|
|
|
|
|
return holder;
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-09 19:15:47 +10:00
|
|
|
|
public static bool CanProcessArgs(ParameterInfo[] parameters)
|
|
|
|
|
{
|
|
|
|
|
foreach (var param in parameters)
|
|
|
|
|
{
|
|
|
|
|
if (!param.ParameterType.IsPrimitive && param.ParameterType != typeof(string))
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-10 18:02:41 +10:00
|
|
|
|
public float CalcWhitespace(Rect window)
|
|
|
|
|
{
|
|
|
|
|
if (!(this is IExpandHeight)) return 0f;
|
|
|
|
|
|
|
|
|
|
float whitespace = (this as IExpandHeight).WhiteSpace;
|
|
|
|
|
if (whitespace > 0)
|
|
|
|
|
{
|
|
|
|
|
ClampLabelWidth(window, ref whitespace);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return whitespace;
|
|
|
|
|
}
|
2020-08-22 00:16:05 +10:00
|
|
|
|
|
2020-09-09 19:15:47 +10:00
|
|
|
|
public object[] ParseArguments()
|
|
|
|
|
{
|
|
|
|
|
var parsedArgs = new List<object>();
|
|
|
|
|
for (int i = 0; i < m_arguments.Length; i++)
|
|
|
|
|
{
|
|
|
|
|
var input = m_argumentInput[i];
|
|
|
|
|
var type = m_arguments[i].ParameterType;
|
|
|
|
|
|
2020-09-10 20:31:09 +10:00
|
|
|
|
if (!string.IsNullOrEmpty(input))
|
2020-09-09 19:15:47 +10:00
|
|
|
|
{
|
2020-09-10 20:31:09 +10:00
|
|
|
|
// strings can obviously just be used directly
|
|
|
|
|
if (type == typeof(string))
|
2020-09-09 19:15:47 +10:00
|
|
|
|
{
|
2020-09-10 20:31:09 +10:00
|
|
|
|
parsedArgs.Add(input);
|
|
|
|
|
continue;
|
2020-09-09 19:15:47 +10:00
|
|
|
|
}
|
2020-09-10 20:31:09 +10:00
|
|
|
|
else
|
2020-09-09 19:15:47 +10:00
|
|
|
|
{
|
2020-09-10 20:31:09 +10:00
|
|
|
|
// try to invoke the parse method and use that.
|
|
|
|
|
try
|
2020-09-10 18:02:41 +10:00
|
|
|
|
{
|
2020-09-10 20:31:09 +10:00
|
|
|
|
parsedArgs.Add(type.GetMethod("Parse", new Type[] { typeof(string) })
|
|
|
|
|
.Invoke(null, new object[] { input }));
|
|
|
|
|
|
|
|
|
|
continue;
|
2020-09-10 18:02:41 +10:00
|
|
|
|
}
|
2020-09-10 20:31:09 +10:00
|
|
|
|
catch
|
2020-09-10 18:02:41 +10:00
|
|
|
|
{
|
2020-09-10 20:31:09 +10:00
|
|
|
|
MelonLogger.Log($"Argument #{i} '{m_arguments[i].Name}' ({type.Name}), could not parse input '{input}'.");
|
2020-09-10 18:02:41 +10:00
|
|
|
|
}
|
2020-09-09 19:15:47 +10:00
|
|
|
|
}
|
|
|
|
|
}
|
2020-09-10 20:31:09 +10:00
|
|
|
|
|
|
|
|
|
// Didn't use input, see if there is a default value.
|
|
|
|
|
if (m_arguments[i].HasDefaultValue)
|
|
|
|
|
{
|
|
|
|
|
parsedArgs.Add(m_arguments[i].DefaultValue);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Try add a null arg I guess
|
|
|
|
|
parsedArgs.Add(null);
|
2020-09-09 19:15:47 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return parsedArgs.ToArray();
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-22 17:17:11 +10:00
|
|
|
|
public virtual void UpdateValue()
|
2020-08-22 00:16:05 +10:00
|
|
|
|
{
|
2020-09-09 19:15:47 +10:00
|
|
|
|
if (MemInfo == null)
|
2020-08-22 00:16:05 +10:00
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-10 18:02:41 +10:00
|
|
|
|
if (HasParameters && !m_isEvaluating)
|
|
|
|
|
{
|
|
|
|
|
// Need to enter parameters first
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-22 00:16:05 +10:00
|
|
|
|
try
|
|
|
|
|
{
|
2020-09-01 18:03:44 +10:00
|
|
|
|
if (MemInfo.MemberType == MemberTypes.Field)
|
2020-08-22 00:16:05 +10:00
|
|
|
|
{
|
2020-09-01 18:03:44 +10:00
|
|
|
|
var fi = MemInfo as FieldInfo;
|
2020-08-22 00:16:05 +10:00
|
|
|
|
Value = fi.GetValue(fi.IsStatic ? null : DeclaringInstance);
|
|
|
|
|
}
|
2020-09-01 18:03:44 +10:00
|
|
|
|
else if (MemInfo.MemberType == MemberTypes.Property)
|
2020-08-22 00:16:05 +10:00
|
|
|
|
{
|
2020-09-01 18:03:44 +10:00
|
|
|
|
var pi = MemInfo as PropertyInfo;
|
2020-09-09 19:15:47 +10:00
|
|
|
|
var target = pi.GetAccessors()[0].IsStatic ? null : DeclaringInstance;
|
2020-09-01 18:03:44 +10:00
|
|
|
|
|
2020-09-09 19:15:47 +10:00
|
|
|
|
if (HasParameters)
|
2020-09-01 18:03:44 +10:00
|
|
|
|
{
|
2020-09-09 19:15:47 +10:00
|
|
|
|
Value = pi.GetValue(target, ParseArguments());
|
2020-09-01 18:03:44 +10:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Value = pi.GetValue(target, null);
|
|
|
|
|
}
|
2020-08-22 00:16:05 +10:00
|
|
|
|
}
|
2020-09-01 18:03:44 +10:00
|
|
|
|
|
|
|
|
|
ReflectionException = null;
|
2020-09-09 19:15:47 +10:00
|
|
|
|
m_evaluated = true;
|
|
|
|
|
m_isEvaluating = false;
|
2020-08-22 00:16:05 +10:00
|
|
|
|
}
|
2020-08-22 17:17:11 +10:00
|
|
|
|
catch (Exception e)
|
2020-08-22 00:16:05 +10:00
|
|
|
|
{
|
2020-08-22 17:17:11 +10:00
|
|
|
|
ReflectionException = ReflectionHelpers.ExceptionToString(e);
|
2020-08-22 00:16:05 +10:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-24 01:42:19 +10:00
|
|
|
|
public void SetValue()
|
2020-08-22 00:16:05 +10:00
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2020-09-01 18:03:44 +10:00
|
|
|
|
if (MemInfo.MemberType == MemberTypes.Field)
|
2020-08-22 00:16:05 +10:00
|
|
|
|
{
|
2020-09-01 18:03:44 +10:00
|
|
|
|
var fi = MemInfo as FieldInfo;
|
2020-08-24 01:42:19 +10:00
|
|
|
|
fi.SetValue(fi.IsStatic ? null : DeclaringInstance, Value);
|
2020-08-22 00:16:05 +10:00
|
|
|
|
}
|
2020-09-01 18:03:44 +10:00
|
|
|
|
else if (MemInfo.MemberType == MemberTypes.Property)
|
2020-08-22 00:16:05 +10:00
|
|
|
|
{
|
2020-09-01 18:03:44 +10:00
|
|
|
|
var pi = MemInfo as PropertyInfo;
|
|
|
|
|
|
2020-09-09 19:15:47 +10:00
|
|
|
|
if (HasParameters)
|
2020-09-01 18:03:44 +10:00
|
|
|
|
{
|
2020-09-09 19:15:47 +10:00
|
|
|
|
pi.SetValue(pi.GetAccessors()[0].IsStatic ? null : DeclaringInstance, Value, ParseArguments());
|
2020-09-01 18:03:44 +10:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
pi.SetValue(pi.GetAccessors()[0].IsStatic ? null : DeclaringInstance, Value);
|
|
|
|
|
}
|
2020-08-22 00:16:05 +10:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
{
|
|
|
|
|
MelonLogger.LogWarning($"Error setting value: {e.GetType()}, {e.Message}");
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-08-31 23:28:44 +10:00
|
|
|
|
|
2020-09-10 18:02:41 +10:00
|
|
|
|
// ========= Gui Draw ==========
|
2020-08-31 23:28:44 +10:00
|
|
|
|
|
|
|
|
|
public const float MAX_LABEL_WIDTH = 400f;
|
2020-09-09 19:15:47 +10:00
|
|
|
|
public const string EVALUATE_LABEL = "<color=lime>Evaluate</color>";
|
2020-08-31 23:28:44 +10:00
|
|
|
|
|
|
|
|
|
public static void ClampLabelWidth(Rect window, ref float labelWidth)
|
|
|
|
|
{
|
|
|
|
|
float min = window.width * 0.37f;
|
|
|
|
|
if (min > MAX_LABEL_WIDTH) min = MAX_LABEL_WIDTH;
|
|
|
|
|
|
|
|
|
|
labelWidth = Mathf.Clamp(labelWidth, min, MAX_LABEL_WIDTH);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Draw(Rect window, float labelWidth = 215f)
|
|
|
|
|
{
|
|
|
|
|
if (labelWidth > 0)
|
|
|
|
|
{
|
|
|
|
|
ClampLabelWidth(window, ref labelWidth);
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-01 18:03:44 +10:00
|
|
|
|
if (MemInfo != null)
|
2020-08-31 23:28:44 +10:00
|
|
|
|
{
|
2020-09-14 20:25:38 +10:00
|
|
|
|
GUILayout.Label(RichTextName, new GUILayoutOption[] { GUILayout.Width(labelWidth) });
|
2020-08-31 23:28:44 +10:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2020-09-12 00:59:59 +10:00
|
|
|
|
GUIUnstrip.Space(labelWidth);
|
2020-08-31 23:28:44 +10:00
|
|
|
|
}
|
|
|
|
|
|
2020-09-09 19:15:47 +10:00
|
|
|
|
var cm = this as CacheMethod;
|
|
|
|
|
|
|
|
|
|
if (HasParameters)
|
2020-08-31 23:28:44 +10:00
|
|
|
|
{
|
2020-09-14 20:25:38 +10:00
|
|
|
|
GUILayout.BeginVertical(null);
|
2020-09-09 19:15:47 +10:00
|
|
|
|
|
|
|
|
|
if (m_isEvaluating)
|
2020-09-01 18:03:44 +10:00
|
|
|
|
{
|
2020-09-09 19:15:47 +10:00
|
|
|
|
for (int i = 0; i < m_arguments.Length; i++)
|
|
|
|
|
{
|
|
|
|
|
var name = m_arguments[i].Name;
|
|
|
|
|
var input = m_argumentInput[i];
|
|
|
|
|
var type = m_arguments[i].ParameterType.Name;
|
|
|
|
|
|
2020-09-10 18:02:41 +10:00
|
|
|
|
var label = "<color=#2df7b2>" + type + "</color> <color=#a6e9e9>" + name + "</color>";
|
|
|
|
|
if (m_arguments[i].HasDefaultValue)
|
|
|
|
|
{
|
|
|
|
|
label = $"<i>[{label} = {m_arguments[i].DefaultValue}]</i>";
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-14 20:25:38 +10:00
|
|
|
|
GUILayout.BeginHorizontal(null);
|
2020-09-10 18:02:41 +10:00
|
|
|
|
|
2020-09-14 20:25:38 +10:00
|
|
|
|
GUILayout.Label(i.ToString(), new GUILayoutOption[] { GUILayout.Width(20) });
|
|
|
|
|
m_argumentInput[i] = GUILayout.TextField(input, new GUILayoutOption[] { GUILayout.Width(150) });
|
|
|
|
|
GUILayout.Label(label, null);
|
2020-09-10 18:02:41 +10:00
|
|
|
|
|
2020-09-14 20:25:38 +10:00
|
|
|
|
GUILayout.EndHorizontal();
|
2020-09-09 19:15:47 +10:00
|
|
|
|
}
|
2020-09-01 18:03:44 +10:00
|
|
|
|
|
2020-09-14 20:25:38 +10:00
|
|
|
|
GUILayout.BeginHorizontal(null);
|
|
|
|
|
if (GUILayout.Button(EVALUATE_LABEL, new GUILayoutOption[] { GUILayout.Width(70) }))
|
2020-09-01 18:03:44 +10:00
|
|
|
|
{
|
2020-09-13 17:29:01 +10:00
|
|
|
|
if (cm != null)
|
2020-09-01 18:03:44 +10:00
|
|
|
|
{
|
2020-09-09 19:15:47 +10:00
|
|
|
|
cm.Evaluate();
|
2020-09-01 18:03:44 +10:00
|
|
|
|
}
|
2020-09-13 17:29:01 +10:00
|
|
|
|
else
|
2020-09-01 18:03:44 +10:00
|
|
|
|
{
|
2020-09-09 19:15:47 +10:00
|
|
|
|
UpdateValue();
|
2020-09-01 18:03:44 +10:00
|
|
|
|
}
|
|
|
|
|
}
|
2020-09-14 20:25:38 +10:00
|
|
|
|
if (GUILayout.Button("Cancel", new GUILayoutOption[] { GUILayout.Width(70) }))
|
2020-09-09 19:15:47 +10:00
|
|
|
|
{
|
|
|
|
|
m_isEvaluating = false;
|
|
|
|
|
}
|
2020-09-14 20:25:38 +10:00
|
|
|
|
GUILayout.EndHorizontal();
|
2020-09-09 19:15:47 +10:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2020-09-14 20:25:38 +10:00
|
|
|
|
if (GUILayout.Button($"Evaluate ({m_arguments.Length} params)", new GUILayoutOption[] { GUILayout.Width(150) }))
|
2020-09-09 19:15:47 +10:00
|
|
|
|
{
|
|
|
|
|
m_isEvaluating = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-14 20:25:38 +10:00
|
|
|
|
GUILayout.EndVertical();
|
2020-09-09 19:15:47 +10:00
|
|
|
|
|
|
|
|
|
// new line and space
|
2020-09-14 20:25:38 +10:00
|
|
|
|
GUILayout.EndHorizontal();
|
|
|
|
|
GUILayout.BeginHorizontal(null);
|
2020-09-12 00:59:59 +10:00
|
|
|
|
GUIUnstrip.Space(labelWidth);
|
2020-09-09 19:15:47 +10:00
|
|
|
|
}
|
|
|
|
|
else if (cm != null)
|
|
|
|
|
{
|
2020-09-14 20:25:38 +10:00
|
|
|
|
//GUILayout.BeginHorizontal(null);
|
2020-09-09 19:15:47 +10:00
|
|
|
|
|
2020-09-14 20:25:38 +10:00
|
|
|
|
if (GUILayout.Button(EVALUATE_LABEL, new GUILayoutOption[] { GUILayout.Width(70) }))
|
2020-09-09 19:15:47 +10:00
|
|
|
|
{
|
|
|
|
|
cm.Evaluate();
|
2020-09-01 18:03:44 +10:00
|
|
|
|
}
|
|
|
|
|
|
2020-09-09 19:15:47 +10:00
|
|
|
|
// new line and space
|
2020-09-14 20:25:38 +10:00
|
|
|
|
GUILayout.EndHorizontal();
|
|
|
|
|
GUILayout.BeginHorizontal(null);
|
2020-09-12 00:59:59 +10:00
|
|
|
|
GUIUnstrip.Space(labelWidth);
|
2020-09-09 19:15:47 +10:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!string.IsNullOrEmpty(ReflectionException))
|
|
|
|
|
{
|
2020-09-14 20:25:38 +10:00
|
|
|
|
GUILayout.Label("<color=red>Reflection failed!</color> (" + ReflectionException + ")", null);
|
2020-09-09 19:15:47 +10:00
|
|
|
|
}
|
2020-09-10 18:02:41 +10:00
|
|
|
|
else if ((HasParameters || this is CacheMethod) && !m_evaluated)
|
|
|
|
|
{
|
2020-09-14 20:25:38 +10:00
|
|
|
|
GUILayout.Label($"<color=grey><i>Not yet evaluated</i></color> (<color=#2df7b2>{ValueTypeName}</color>)", null);
|
2020-09-10 18:02:41 +10:00
|
|
|
|
}
|
|
|
|
|
else if (Value == null && !(this is CacheMethod))
|
2020-09-09 19:15:47 +10:00
|
|
|
|
{
|
2020-09-14 20:25:38 +10:00
|
|
|
|
GUILayout.Label("<i>null (" + ValueTypeName + ")</i>", null);
|
2020-09-09 19:15:47 +10:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2020-08-31 23:28:44 +10:00
|
|
|
|
DrawValue(window, window.width - labelWidth - 90);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-01 18:03:44 +10:00
|
|
|
|
private string GetRichTextName()
|
2020-08-31 23:28:44 +10:00
|
|
|
|
{
|
|
|
|
|
string memberColor = "";
|
2020-09-01 18:03:44 +10:00
|
|
|
|
switch (MemInfo.MemberType)
|
2020-08-31 23:28:44 +10:00
|
|
|
|
{
|
|
|
|
|
case MemberTypes.Field:
|
|
|
|
|
memberColor = "#c266ff"; break;
|
|
|
|
|
case MemberTypes.Property:
|
|
|
|
|
memberColor = "#72a6a6"; break;
|
|
|
|
|
case MemberTypes.Method:
|
|
|
|
|
memberColor = "#ff8000"; break;
|
|
|
|
|
};
|
|
|
|
|
|
2020-09-01 18:03:44 +10:00
|
|
|
|
m_richTextName = $"<color=#2df7b2>{MemInfo.DeclaringType.Name}</color>.<color={memberColor}>{MemInfo.Name}</color>";
|
2020-08-31 23:28:44 +10:00
|
|
|
|
|
2020-09-10 18:02:41 +10:00
|
|
|
|
if (m_arguments.Length > 0 || this is CacheMethod)
|
2020-08-31 23:28:44 +10:00
|
|
|
|
{
|
|
|
|
|
m_richTextName += "(";
|
|
|
|
|
var _params = "";
|
2020-09-09 19:15:47 +10:00
|
|
|
|
foreach (var param in m_arguments)
|
2020-08-31 23:28:44 +10:00
|
|
|
|
{
|
|
|
|
|
if (_params != "") _params += ", ";
|
|
|
|
|
|
2020-09-09 19:15:47 +10:00
|
|
|
|
_params += $"<color=#2df7b2>{param.ParameterType.Name}</color> <color=#a6e9e9>{param.Name}</color>";
|
2020-08-31 23:28:44 +10:00
|
|
|
|
}
|
|
|
|
|
m_richTextName += _params;
|
|
|
|
|
m_richTextName += ")";
|
|
|
|
|
}
|
2020-09-01 18:03:44 +10:00
|
|
|
|
|
|
|
|
|
return m_richTextName;
|
2020-08-31 23:28:44 +10:00
|
|
|
|
}
|
2020-08-22 00:16:05 +10:00
|
|
|
|
}
|
|
|
|
|
}
|