Lots of fixes, everything basically done except Reflection Inspector

This commit is contained in:
sinaioutlander
2020-11-11 20:16:43 +11:00
parent 70a1570441
commit e4d38af4f5
27 changed files with 569 additions and 428 deletions

View File

@ -24,7 +24,7 @@ namespace UnityExplorer.Inspectors.Reflection
// return ret;
//}
public static CacheMember GetCacheObject(MemberInfo member, object declaringInstance)
public static CacheMember GetCacheObject(MemberInfo member, object declaringInstance, GameObject parentUIContent)
{
CacheMember ret;
@ -45,6 +45,8 @@ namespace UnityExplorer.Inspectors.Reflection
return null;
}
ret.m_parentContent = parentUIContent;
return ret;
}

View File

@ -19,23 +19,17 @@ namespace UnityExplorer.Inspectors.Reflection
UpdateValue();
}
public override void UpdateValue()
public override void UpdateReflection()
{
//if (IValue is InteractiveDictionary iDict)
//{
// if (!iDict.EnsureDictionaryIsSupported())
// {
// ReflectionException = "Not supported due to TypeInitializationException";
// return;
// }
//}
try
{
var fi = MemInfo as FieldInfo;
IValue.Value = fi.GetValue(fi.IsStatic ? null : DeclaringInstance);
base.UpdateValue();
//base.UpdateValue();
m_evaluated = true;
ReflectionException = null;
}
catch (Exception e)
{

View File

@ -3,12 +3,16 @@ using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.UI;
using UnityExplorer.UI.Shared;
#if CPP
using UnhollowerBaseLib;
#endif
namespace UnityExplorer.Inspectors.Reflection
{
public class CacheMember : CacheObjectBase
public abstract class CacheMember : CacheObjectBase
{
public MemberInfo MemInfo { get; set; }
public Type DeclaringType { get; set; }
@ -18,6 +22,7 @@ namespace UnityExplorer.Inspectors.Reflection
public override bool HasParameters => m_arguments != null && m_arguments.Length > 0;
public override bool IsMember => true;
public override bool HasEvaluated => m_evaluated;
public string RichTextName => m_richTextName ?? GetRichTextName();
private string m_richTextName;
@ -39,21 +44,25 @@ namespace UnityExplorer.Inspectors.Reflection
DeclaringInstance = declaringInstance;
}
//public virtual void InitMember(MemberInfo member, object declaringInstance)
//{
// MemInfo = member;
// DeclaringInstance = declaringInstance;
// DeclaringType = member.DeclaringType;
//}
public override void UpdateValue()
{
#if CPP
if (!IsReflectionSupported())
this.ReflectionException = "Type not supported with Reflection!";
else
UpdateReflection();
#else
UpdateReflection();
#endif
base.UpdateValue();
}
public abstract void UpdateReflection();
public override void SetValue()
{
// ...
// no implementation for base class
}
public object[] ParseArguments()
@ -114,25 +123,6 @@ namespace UnityExplorer.Inspectors.Reflection
public static bool HasDefaultValue(ParameterInfo arg) => arg.DefaultValue != DBNull.Value;
//public void DrawArgsInput()
//{
// for (int i = 0; i < this.m_arguments.Length; i++)
// {
// var name = this.m_arguments[i].Name;
// var input = this.m_argumentInput[i];
// var type = this.m_arguments[i].ParameterType.Name;
// var label = $"<color={SyntaxColors.Class_Instance}>{type}</color> ";
// label += $"<color={SyntaxColors.Local}>{name}</color>";
// if (HasDefaultValue(this.m_arguments[i]))
// {
// label = $"<i>[{label} = {this.m_arguments[i].DefaultValue ?? "null"}]</i>";
// }
// }
//}
private bool GetCanWrite()
{
if (MemInfo is FieldInfo fi)
@ -218,5 +208,78 @@ namespace UnityExplorer.Inspectors.Reflection
return m_richTextName;
}
#if CPP
internal bool IsReflectionSupported()
{
try
{
var baseType = this.IValue.ValueType;
var gArgs = baseType.GetGenericArguments();
if (gArgs.Length < 1)
return true;
foreach (var arg in gArgs)
{
if (!Check(arg))
return false;
}
return true;
bool Check(Type type)
{
if (!typeof(Il2CppSystem.Object).IsAssignableFrom(type))
return true;
var ptr = (IntPtr)typeof(Il2CppClassPointerStore<>)
.MakeGenericType(type)
.GetField("NativeClassPtr")
.GetValue(null);
if (ptr == IntPtr.Zero)
return false;
return Il2CppSystem.Type.internal_from_handle(IL2CPP.il2cpp_class_get_type(ptr)) is Il2CppSystem.Type;
}
}
catch
{
return false;
}
}
#endif
#region UI CONSTRUCTION
internal override void ConstructUI()
{
base.ConstructUI();
//var refreshBtnObj = UIFactory.CreateButton(topRowObj, new Color(0.3f, 0.3f, 0.3f));
//var btnLayout = refreshBtnObj.AddComponent<LayoutElement>();
//btnLayout.minWidth = 30;
//btnLayout.minHeight = 20;
//btnLayout.flexibleWidth = 0;
//var refreshTxt = refreshBtnObj.GetComponentInChildren<Text>();
//refreshTxt.text = "⟳";
//refreshTxt.fontSize = 16;
//var refreshBtn = refreshBtnObj.GetComponent<Button>();
//refreshBtn.onClick.AddListener(() => { ExplorerCore.Log("todo Update!"); });
var labelObj = UIFactory.CreateLabel(m_topContent, TextAnchor.MiddleLeft);
var labellayout = labelObj.AddComponent<LayoutElement>();
labellayout.minWidth = 225;
labellayout.flexibleWidth = 0;
var label = labelObj.GetComponent<Text>();
label.horizontalOverflow = HorizontalWrapMode.Wrap;
label.text = this.RichTextName;
}
#endregion
}
}

View File

@ -41,6 +41,11 @@ namespace UnityExplorer.Inspectors.Reflection
// CacheMethod cannot UpdateValue directly. Need to Evaluate.
}
public override void UpdateReflection()
{
// CacheMethod cannot UpdateValue directly. Need to Evaluate.
}
public void Evaluate()
{
MethodInfo mi;
@ -61,6 +66,7 @@ namespace UnityExplorer.Inspectors.Reflection
ret = mi.Invoke(mi.IsStatic ? null : DeclaringInstance, ParseArguments());
m_evaluated = true;
m_isEvaluating = false;
ReflectionException = null;
}
catch (Exception e)
{
@ -122,77 +128,5 @@ namespace UnityExplorer.Inspectors.Reflection
return mi;
}
// ==== GUI DRAW ====
//public override void Draw(Rect window, float width)
//{
// base.Draw(window, width);
//}
public void DrawValue(Rect window, float width)
{
string typeLabel = $"<color={SyntaxColors.Class_Instance}>{IValue.ValueType.FullName}</color>";
if (m_evaluated)
{
if (m_cachedReturnValue != null)
{
//m_cachedReturnValue.IValue.DrawValue(window, width);
}
else
{
GUILayout.Label($"null ({typeLabel})", new GUILayoutOption[0]);
}
}
else
{
GUILayout.Label($"<color=grey><i>Not yet evaluated</i></color> ({typeLabel})", new GUILayoutOption[0]);
}
}
//public void DrawGenericArgsInput()
//{
// GUILayout.Label($"<b><color=orange>Generic Arguments:</color></b>", new GUILayoutOption[0]);
// for (int i = 0; i < this.GenericArgs.Length; i++)
// {
// string types = "";
// if (this.GenericConstraints[i].Length > 0)
// {
// foreach (var constraint in this.GenericConstraints[i])
// {
// if (types != "") types += ", ";
// string type;
// if (constraint == null)
// type = "Any";
// else
// type = constraint.ToString();
// types += $"<color={Syntax.Class_Instance}>{type}</color>";
// }
// }
// else
// {
// types = $"<color={Syntax.Class_Instance}>Any</color>";
// }
// var input = this.GenericArgInput[i];
// GUIHelper.BeginHorizontal(new GUILayoutOption[0]);
// GUI.skin.label.alignment = TextAnchor.MiddleCenter;
// GUILayout.Label(
// $"<color={Syntax.StructGreen}>{this.GenericArgs[i].Name}</color>",
// new GUILayoutOption[] { GUILayout.Width(15) }
// );
// this.GenericArgInput[i] = GUIHelper.TextField(input, new GUILayoutOption[] { GUILayout.Width(150) });
// GUI.skin.label.alignment = TextAnchor.MiddleLeft;
// GUILayout.Label(types, new GUILayoutOption[0]);
// GUILayout.EndHorizontal();
// }
//}
}
}

View File

@ -6,6 +6,7 @@ using UnityEngine;
using UnityExplorer.UI;
using UnityExplorer.UI.Shared;
using UnityExplorer.Helpers;
using UnityEngine.UI;
namespace UnityExplorer.Inspectors.Reflection
{
@ -16,9 +17,7 @@ namespace UnityExplorer.Inspectors.Reflection
public virtual bool CanWrite => false;
public virtual bool HasParameters => false;
public virtual bool IsMember => false;
//public bool IsStaticClassSearchResult { get; set; }
public virtual bool HasEvaluated => true;
// TODO
public virtual void InitValue(object value, Type valueType)
@ -28,85 +27,30 @@ namespace UnityExplorer.Inspectors.Reflection
return;
}
//ExplorerCore.Log("Initializing InteractiveValue of type " + valueType.FullName);
// InteractiveValue interactive;
//if (valueType == typeof(GameObject) || valueType == typeof(Transform))
//{
// interactive = new InteractiveGameObject();
//}
//else if (valueType == typeof(Texture2D))
//{
// interactive = new InteractiveTexture2D();
//}
//else if (valueType == typeof(Texture))
//{
// interactive = new InteractiveTexture();
//}
//else if (valueType == typeof(Sprite))
//{
// interactive = new InteractiveSprite();
//}
//else if (valueType.IsPrimitive || valueType == typeof(string))
//{
// interactive = new InteractivePrimitive();
//}
//else if (valueType.IsEnum)
//{
// if (valueType.GetCustomAttributes(typeof(FlagsAttribute), true) is object[] attributes && attributes.Length > 0)
// {
// interactive = new InteractiveFlags();
// }
// else
// {
// interactive = new InteractiveEnum();
// }
//}
//else if (valueType == typeof(Vector2) || valueType == typeof(Vector3) || valueType == typeof(Vector4))
//{
// interactive = new InteractiveVector();
//}
//else if (valueType == typeof(Quaternion))
//{
// interactive = new InteractiveQuaternion();
//}
//else if (valueType == typeof(Color))
//{
// interactive = new InteractiveColor();
//}
//else if (valueType == typeof(Rect))
//{
// interactive = new InteractiveRect();
//}
//// must check this before IsEnumerable
//else if (ReflectionHelpers.IsDictionary(valueType))
//{
// interactive = new InteractiveDictionary();
//}
//else if (ReflectionHelpers.IsEnumerable(valueType))
//{
// interactive = new InteractiveEnumerable();
//}
//else
//{
// interactive = new InteractiveValue();
//}
//interactive.Value = obj;
//interactive.ValueType = valueType;
//this.IValue = interactive;
//this.IValue.OwnerCacheObject = this;
//UpdateValue();
//this.IValue.Init();
// TEMP
IValue = new InteractiveValue
{
OwnerCacheObject = this,
ValueType = ReflectionHelpers.GetActualType(value) ?? valueType,
};
UpdateValue();
}
public virtual void Draw(Rect window, float width)
public virtual void Enable()
{
// IValue.Draw(window, width);
if (!m_constructedUI)
{
ConstructUI();
IValue.ConstructUI(m_topContent);
UpdateValue();
}
m_mainContent.SetActive(true);
}
public virtual void Disable()
{
m_mainContent.SetActive(false);
}
public virtual void UpdateValue()
@ -115,5 +59,57 @@ namespace UnityExplorer.Inspectors.Reflection
}
public virtual void SetValue() => throw new NotImplementedException();
#region UI CONSTRUCTION
internal bool m_constructedUI;
internal GameObject m_parentContent;
internal GameObject m_mainContent;
internal GameObject m_topContent;
//internal GameObject m_subContent;
// Make base UI holder for CacheObject, this doesnt actually display anything.
internal virtual void ConstructUI()
{
m_constructedUI = true;
m_mainContent = UIFactory.CreateVerticalGroup(m_parentContent, new Color(0.1f, 0.1f, 0.1f));
var rowGroup = m_mainContent.GetComponent<VerticalLayoutGroup>();
rowGroup.childForceExpandWidth = true;
rowGroup.childControlWidth = true;
rowGroup.childForceExpandHeight = false;
rowGroup.childControlHeight = true;
var rowLayout = m_mainContent.AddComponent<LayoutElement>();
rowLayout.minHeight = 25;
rowLayout.flexibleHeight = 0;
rowLayout.minWidth = 200;
rowLayout.flexibleWidth = 5000;
m_topContent = UIFactory.CreateHorizontalGroup(m_mainContent, new Color(1, 1, 1, 0));
var topLayout = m_topContent.AddComponent<LayoutElement>();
topLayout.minHeight = 25;
topLayout.flexibleHeight = 0;
var topGroup = m_topContent.GetComponent<HorizontalLayoutGroup>();
topGroup.childForceExpandHeight = false;
topGroup.childForceExpandWidth = true;
topGroup.childControlHeight = true;
topGroup.childControlWidth = true;
topGroup.spacing = 4;
//m_subContent = UIFactory.CreateHorizontalGroup(m_parentContent, new Color(1, 1, 1, 0));
//var subGroup = m_subContent.GetComponent<HorizontalLayoutGroup>();
//subGroup.childForceExpandWidth = true;
//subGroup.childControlWidth = true;
//var subLayout = m_subContent.AddComponent<LayoutElement>();
//subLayout.minHeight = 25;
//subLayout.flexibleHeight = 500;
//subLayout.minWidth = 125;
//subLayout.flexibleWidth = 9000;
//m_subContent.SetActive(false);
}
#endregion
}
}

View File

@ -22,7 +22,7 @@ namespace UnityExplorer.Inspectors.Reflection
UpdateValue();
}
public override void UpdateValue()
public override void UpdateReflection()
{
if (HasParameters && !m_isEvaluating)
{
@ -30,15 +30,6 @@ namespace UnityExplorer.Inspectors.Reflection
return;
}
//if (IValue is InteractiveDictionary iDict)
//{
// if (!iDict.EnsureDictionaryIsSupported())
// {
// ReflectionException = "Not supported due to TypeInitializationException";
// return;
// }
//}
try
{
var pi = MemInfo as PropertyInfo;
@ -49,18 +40,17 @@ namespace UnityExplorer.Inspectors.Reflection
IValue.Value = pi.GetValue(target, ParseArguments());
base.UpdateValue();
//base.UpdateValue();
m_evaluated = true;
ReflectionException = null;
}
else // create a dummy value for Write-Only properties.
{
if (IValue.ValueType == typeof(string))
{
IValue.Value = "";
}
else
{
IValue.Value = Activator.CreateInstance(IValue.ValueType);
}
}
}
catch (Exception e)

View File

@ -3,7 +3,9 @@ using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEngine;
using UnityEngine.UI;
using UnityExplorer.Helpers;
using UnityExplorer.UI;
using UnityExplorer.UI.Shared;
namespace UnityExplorer.Inspectors.Reflection
@ -28,11 +30,26 @@ namespace UnityExplorer.Inspectors.Reflection
public virtual void UpdateValue()
{
GetButtonLabel();
if (!m_text)
return;
if (OwnerCacheObject is CacheMember ownerMember && !string.IsNullOrEmpty(ownerMember.ReflectionException))
{
m_text.text = "<color=red>" + ownerMember.ReflectionException + "</color>";
return;
}
if (Value == null)
{
m_text.text = "<color=red>null</color>";
}
else
{
GetButtonLabel();
m_text.text = ButtonLabel;
}
}
private MethodInfo GetToStringMethod()
{
try
@ -52,7 +69,7 @@ namespace UnityExplorer.Inspectors.Reflection
public string GetButtonLabel()
{
if (Value == null) return null;
if (Value == null) return "";
var valueType = ReflectionHelpers.GetActualType(Value);
@ -100,5 +117,35 @@ namespace UnityExplorer.Inspectors.Reflection
return m_btnLabel = label;
}
#region UI CONSTRUCTION
internal GameObject m_UIContent;
internal Text m_text;
public void ConstructUI(GameObject parent)
{
// TEMPORARY
m_UIContent = UIFactory.CreateLabel(parent, TextAnchor.MiddleLeft);
var mainLayout = m_UIContent.AddComponent<LayoutElement>();
mainLayout.minWidth = 100;
mainLayout.flexibleWidth = 5000;
mainLayout.minHeight = 25;
m_text = m_UIContent.GetComponent<Text>();
if (OwnerCacheObject != null)
{
if (!OwnerCacheObject.HasEvaluated)
{
m_text.text = "Not yet evaluated";
}
else
{
m_text.text = ButtonLabel;
}
}
}
#endregion
}
}