mirror of
https://github.com/sinai-dev/UnityExplorer.git
synced 2025-06-26 02:02:28 +08:00
Lots of fixes, everything basically done except Reflection Inspector
This commit is contained in:
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
// }
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user