mirror of
https://github.com/sinai-dev/UnityExplorer.git
synced 2025-06-27 02:22:33 +08:00
InteractiveBool, Il2Cpp>Mono type dict cache, some UI fixes
This commit is contained in:
@ -9,7 +9,7 @@ using UnityEngine.UI;
|
||||
|
||||
namespace UnityExplorer.Inspectors.Reflection
|
||||
{
|
||||
public class CacheEnumerated : CacheObjectBase, INestedValue
|
||||
public class CacheEnumerated : CacheObjectBase
|
||||
{
|
||||
public override Type FallbackType => ParentEnumeration.m_baseEntryType;
|
||||
public override bool CanWrite => RefIList != null && ParentEnumeration.OwnerCacheObject.CanWrite;
|
||||
@ -40,11 +40,6 @@ namespace UnityExplorer.Inspectors.Reflection
|
||||
ParentEnumeration.OwnerCacheObject.SetValue();
|
||||
}
|
||||
|
||||
public void UpdateSubcontentHeight()
|
||||
{
|
||||
ParentEnumeration.UpdateSubcontentHeight();
|
||||
}
|
||||
|
||||
internal override void ConstructUI()
|
||||
{
|
||||
base.ConstructUI();
|
||||
|
@ -1,60 +0,0 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
using UnityExplorer.Helpers;
|
||||
|
||||
namespace UnityExplorer.Inspectors.Reflection
|
||||
{
|
||||
public static class CacheFactory
|
||||
{
|
||||
public static CacheMember GetCacheObject(MemberInfo member, object declaringInstance, GameObject parentUIContent)
|
||||
{
|
||||
CacheMember ret;
|
||||
|
||||
if (member is MethodInfo mi && CanProcessArgs(mi.GetParameters()))
|
||||
{
|
||||
ret = new CacheMethod(mi, declaringInstance);
|
||||
}
|
||||
else if (member is PropertyInfo pi && CanProcessArgs(pi.GetIndexParameters()))
|
||||
{
|
||||
ret = new CacheProperty(pi, declaringInstance);
|
||||
}
|
||||
else if (member is FieldInfo fi)
|
||||
{
|
||||
ret = new CacheField(fi, declaringInstance);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
ret.m_parentContent = parentUIContent;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static bool CanProcessArgs(ParameterInfo[] parameters)
|
||||
{
|
||||
foreach (var param in parameters)
|
||||
{
|
||||
var pType = param.ParameterType;
|
||||
|
||||
if (pType.IsByRef && pType.HasElementType)
|
||||
{
|
||||
pType = pType.GetElementType();
|
||||
}
|
||||
|
||||
if (pType != null && (pType.IsPrimitive || pType == typeof(string)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@ -50,6 +50,23 @@ namespace UnityExplorer.Inspectors.Reflection
|
||||
DeclaringInstance = declaringInstance;
|
||||
}
|
||||
|
||||
public static bool CanProcessArgs(ParameterInfo[] parameters)
|
||||
{
|
||||
foreach (var param in parameters)
|
||||
{
|
||||
var pType = param.ParameterType;
|
||||
|
||||
if (pType.IsByRef && pType.HasElementType)
|
||||
pType = pType.GetElementType();
|
||||
|
||||
if (pType != null && (pType.IsPrimitive || pType == typeof(string)))
|
||||
continue;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void CreateIValue(object value, Type fallbackType)
|
||||
{
|
||||
IValue = InteractiveValue.Create(value, fallbackType);
|
||||
|
@ -63,6 +63,8 @@ namespace UnityExplorer.Inspectors.Reflection
|
||||
}
|
||||
|
||||
IValue.OnValueUpdated();
|
||||
|
||||
IValue.RefreshElementsAfterUpdate();
|
||||
}
|
||||
|
||||
public virtual void SetValue() => throw new NotImplementedException();
|
||||
|
@ -16,7 +16,7 @@ namespace UnityExplorer.Inspectors.Reflection
|
||||
Value
|
||||
}
|
||||
|
||||
public class CachePaired : CacheObjectBase, INestedValue
|
||||
public class CachePaired : CacheObjectBase
|
||||
{
|
||||
public override Type FallbackType => PairType == PairTypes.Key
|
||||
? ParentDictionary.m_typeOfKeys
|
||||
@ -27,13 +27,13 @@ namespace UnityExplorer.Inspectors.Reflection
|
||||
public PairTypes PairType;
|
||||
public int Index { get; private set; }
|
||||
public InteractiveDictionary ParentDictionary { get; private set; }
|
||||
internal IDictionary RefIDIct;
|
||||
internal IDictionary RefIDict;
|
||||
|
||||
public CachePaired(int index, InteractiveDictionary parentDict, IDictionary refIDict, PairTypes pairType, GameObject parentContent)
|
||||
{
|
||||
Index = index;
|
||||
ParentDictionary = parentDict;
|
||||
RefIDIct = refIDict;
|
||||
RefIDict = refIDict;
|
||||
this.PairType = pairType;
|
||||
this.m_parentContent = parentContent;
|
||||
}
|
||||
@ -44,11 +44,6 @@ namespace UnityExplorer.Inspectors.Reflection
|
||||
IValue.OwnerCacheObject = this;
|
||||
}
|
||||
|
||||
public void UpdateSubcontentHeight()
|
||||
{
|
||||
ParentDictionary.UpdateSubcontentHeight();
|
||||
}
|
||||
|
||||
#region UI CONSTRUCTION
|
||||
|
||||
internal override void ConstructUI()
|
||||
|
@ -43,7 +43,7 @@ namespace UnityExplorer.Inspectors.Reflection
|
||||
}
|
||||
else
|
||||
{
|
||||
// todo write-only properties
|
||||
// todo write-only properties?
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,12 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace UnityExplorer.Inspectors.Reflection
|
||||
{
|
||||
public interface INestedValue
|
||||
{
|
||||
void UpdateSubcontentHeight();
|
||||
}
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityExplorer.Helpers;
|
||||
using UnityExplorer.UI;
|
||||
|
||||
namespace UnityExplorer.Inspectors.Reflection
|
||||
{
|
||||
public class InteractiveBool : InteractiveValue
|
||||
{
|
||||
public InteractiveBool(object value, Type valueType) : base(value, valueType)
|
||||
{
|
||||
}
|
||||
|
||||
public override IValueTypes IValueType => IValueTypes.Bool;
|
||||
public override bool HasSubContent => false;
|
||||
public override bool SubContentWanted => false;
|
||||
public override bool WantInspectBtn => false;
|
||||
|
||||
internal Toggle m_toggle;
|
||||
|
||||
public override void OnValueUpdated()
|
||||
{
|
||||
base.OnValueUpdated();
|
||||
|
||||
if (!Value.IsNullOrDestroyed())
|
||||
{
|
||||
if (OwnerCacheObject.CanWrite)
|
||||
{
|
||||
if (!m_toggle.gameObject.activeSelf)
|
||||
m_toggle.gameObject.SetActive(true);
|
||||
|
||||
var val = (bool)Value;
|
||||
if (m_toggle.isOn != val)
|
||||
m_toggle.isOn = val;
|
||||
}
|
||||
|
||||
RefreshUIElements();
|
||||
}
|
||||
}
|
||||
|
||||
internal void RefreshUIElements()
|
||||
{
|
||||
if (m_baseLabel)
|
||||
{
|
||||
var val = (bool)Value;
|
||||
var color = val
|
||||
? "00FF00" // on
|
||||
: "FF0000"; // off
|
||||
|
||||
m_baseLabel.text = $"<color=#{color}>{val}</color> ({m_richValueType})";
|
||||
}
|
||||
}
|
||||
|
||||
internal void OnToggleValueChanged(bool val)
|
||||
{
|
||||
Value = val;
|
||||
OwnerCacheObject.SetValue();
|
||||
RefreshUIElements();
|
||||
}
|
||||
|
||||
public override void ConstructUI(GameObject parent, GameObject subGroup)
|
||||
{
|
||||
base.ConstructUI(parent, subGroup);
|
||||
|
||||
if (OwnerCacheObject.CanWrite)
|
||||
{
|
||||
var toggleObj = UIFactory.CreateToggle(m_valueContent, out m_toggle, out _, new Color(0.1f, 0.1f, 0.1f));
|
||||
toggleObj.SetActive(false);
|
||||
var toggleLayout = toggleObj.AddComponent<LayoutElement>();
|
||||
toggleLayout.minWidth = 24;
|
||||
|
||||
m_toggle.onValueChanged.AddListener(OnToggleValueChanged);
|
||||
|
||||
m_baseLabel.transform.SetAsLastSibling();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -31,6 +31,7 @@ namespace UnityExplorer.Inspectors.Reflection
|
||||
|
||||
public override IValueTypes IValueType => IValueTypes.Dictionary;
|
||||
public override bool HasSubContent => true;
|
||||
public override bool SubContentWanted => (RefIDictionary?.Count ?? 1) > 0;
|
||||
public override bool WantInspectBtn => false;
|
||||
|
||||
internal IDictionary RefIDictionary;
|
||||
@ -44,8 +45,6 @@ namespace UnityExplorer.Inspectors.Reflection
|
||||
internal readonly KeyValuePair<CachePaired, CachePaired>[] m_displayedEntries
|
||||
= new KeyValuePair<CachePaired, CachePaired>[ModConfig.Instance.Default_Page_Limit];
|
||||
|
||||
//internal readonly List<CacheKeyValuePair> m_entries = new List<CacheKeyValuePair>();
|
||||
//internal CacheKeyValuePair[] m_displayedEntries = new CacheKeyValuePair[ModConfig.Instance.Default_Page_Limit];
|
||||
internal bool m_recacheWanted = true;
|
||||
|
||||
public override void OnDestroy()
|
||||
@ -176,7 +175,7 @@ namespace UnityExplorer.Inspectors.Reflection
|
||||
entry.Value.Enable();
|
||||
}
|
||||
|
||||
UpdateSubcontentHeight();
|
||||
//UpdateSubcontentHeight();
|
||||
}
|
||||
|
||||
internal override void OnToggleSubcontent(bool active)
|
||||
@ -193,38 +192,6 @@ namespace UnityExplorer.Inspectors.Reflection
|
||||
RefreshDisplay();
|
||||
}
|
||||
|
||||
public void UpdateSubcontentHeight()
|
||||
{
|
||||
Canvas.ForceUpdateCanvases();
|
||||
|
||||
float totalHeight = 0f;
|
||||
if (m_subContentParent.activeSelf)
|
||||
{
|
||||
foreach (var itemIndex in m_pageHandler)
|
||||
{
|
||||
if (itemIndex >= m_entries.Count)
|
||||
break;
|
||||
|
||||
var entry = m_entries[itemIndex];
|
||||
LayoutRebuilder.ForceRebuildLayoutImmediate(entry.Key.m_mainRect);
|
||||
LayoutRebuilder.ForceRebuildLayoutImmediate(entry.Value.m_mainRect);
|
||||
|
||||
totalHeight += Mathf.Max(entry.Key.m_mainRect.rect.height, entry.Value.m_mainRect.rect.height);
|
||||
}
|
||||
}
|
||||
|
||||
m_listLayout.minHeight = Mathf.Min(350f, totalHeight);
|
||||
//m_mainLayout.minHeight = totalHeight;
|
||||
|
||||
LayoutRebuilder.ForceRebuildLayoutImmediate(OwnerCacheObject.m_mainRect);
|
||||
|
||||
if (OwnerCacheObject is INestedValue nestedValue)
|
||||
{
|
||||
// nested enumerable
|
||||
nestedValue.UpdateSubcontentHeight();
|
||||
}
|
||||
}
|
||||
|
||||
#region UI CONSTRUCTION
|
||||
|
||||
internal GameObject m_listContent;
|
||||
|
@ -25,6 +25,7 @@ namespace UnityExplorer.Inspectors.Reflection
|
||||
public override IValueTypes IValueType => IValueTypes.Enumerable;
|
||||
|
||||
public override bool HasSubContent => true;
|
||||
public override bool SubContentWanted => (RefIList?.Count ?? 1) > 0;
|
||||
public override bool WantInspectBtn => false;
|
||||
|
||||
internal IEnumerable RefIEnumerable;
|
||||
@ -137,7 +138,7 @@ namespace UnityExplorer.Inspectors.Reflection
|
||||
entry.Enable();
|
||||
}
|
||||
|
||||
UpdateSubcontentHeight();
|
||||
//UpdateSubcontentHeight();
|
||||
}
|
||||
|
||||
internal override void OnToggleSubcontent(bool active)
|
||||
@ -154,36 +155,6 @@ namespace UnityExplorer.Inspectors.Reflection
|
||||
RefreshDisplay();
|
||||
}
|
||||
|
||||
public void UpdateSubcontentHeight()
|
||||
{
|
||||
Canvas.ForceUpdateCanvases();
|
||||
|
||||
float totalHeight = 0f;
|
||||
if (m_subContentParent.activeSelf)
|
||||
{
|
||||
foreach (var itemIndex in m_pageHandler)
|
||||
{
|
||||
if (itemIndex >= m_entries.Count)
|
||||
break;
|
||||
|
||||
var entry = m_entries[itemIndex];
|
||||
LayoutRebuilder.ForceRebuildLayoutImmediate(entry.m_mainRect);
|
||||
totalHeight += entry.m_mainRect.rect.height;
|
||||
}
|
||||
}
|
||||
|
||||
m_listLayout.minHeight = Mathf.Min(350f, totalHeight);
|
||||
//m_mainLayout.minHeight = totalHeight;
|
||||
|
||||
LayoutRebuilder.ForceRebuildLayoutImmediate(OwnerCacheObject.m_mainRect);
|
||||
|
||||
if (OwnerCacheObject is INestedValue nestedValue)
|
||||
{
|
||||
// nested enumerable
|
||||
nestedValue.UpdateSubcontentHeight();
|
||||
}
|
||||
}
|
||||
|
||||
#region UI CONSTRUCTION
|
||||
|
||||
internal GameObject m_listContent;
|
||||
|
@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityExplorer.Inspectors.Reflection
|
||||
{
|
||||
public class InteractiveNumber : InteractiveValue
|
||||
{
|
||||
public InteractiveNumber(object value, Type valueType) : base(value, valueType)
|
||||
{
|
||||
}
|
||||
|
||||
public override IValueTypes IValueType => IValueTypes.Number;
|
||||
public override bool HasSubContent => false;
|
||||
public override bool SubContentWanted => false;
|
||||
public override bool WantInspectBtn => false;
|
||||
|
||||
public override void ConstructUI(GameObject parent, GameObject subGroup)
|
||||
{
|
||||
base.ConstructUI(parent, subGroup);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public override void OnValueUpdated()
|
||||
{
|
||||
base.OnValueUpdated();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityExplorer.Inspectors.Reflection
|
||||
{
|
||||
public class InteractiveString : InteractiveValue
|
||||
{
|
||||
public InteractiveString(object value, Type valueType) : base(value, valueType)
|
||||
{
|
||||
}
|
||||
|
||||
public override IValueTypes IValueType => IValueTypes.String;
|
||||
public override bool HasSubContent => false;
|
||||
public override bool SubContentWanted => false;
|
||||
public override bool WantInspectBtn => false;
|
||||
|
||||
public override void ConstructUI(GameObject parent, GameObject subGroup)
|
||||
{
|
||||
base.ConstructUI(parent, subGroup);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public override void OnValueUpdated()
|
||||
{
|
||||
base.OnValueUpdated();
|
||||
}
|
||||
}
|
||||
}
|
@ -16,6 +16,13 @@ namespace UnityExplorer.Inspectors.Reflection
|
||||
Any,
|
||||
Enumerable,
|
||||
Dictionary,
|
||||
Bool,
|
||||
String,
|
||||
Number,
|
||||
Enum,
|
||||
Flags,
|
||||
UnityStruct,
|
||||
Color, // maybe
|
||||
}
|
||||
|
||||
public class InteractiveValue
|
||||
@ -28,15 +35,22 @@ namespace UnityExplorer.Inspectors.Reflection
|
||||
{ IValueTypes.Any, typeof(InteractiveValue) },
|
||||
{ IValueTypes.Dictionary, typeof(InteractiveDictionary) },
|
||||
{ IValueTypes.Enumerable, typeof(InteractiveEnumerable) },
|
||||
{ IValueTypes.Bool, typeof(InteractiveBool) },
|
||||
{ IValueTypes.String, typeof(InteractiveString) },
|
||||
{ IValueTypes.Number, typeof(InteractiveNumber) },
|
||||
};
|
||||
|
||||
// WIP
|
||||
public static IValueTypes GetIValueForType(Type type)
|
||||
{
|
||||
if (type.IsPrimitive || type == typeof(string))
|
||||
return IValueTypes.Any; // TODO Primitive
|
||||
if (type == typeof(bool))
|
||||
return IValueTypes.Bool;
|
||||
else if (type == typeof(string))
|
||||
return IValueTypes.String;
|
||||
else if (type.IsPrimitive)
|
||||
return IValueTypes.Number;
|
||||
else if (typeof(Transform).IsAssignableFrom(type))
|
||||
return IValueTypes.Any; // TODO Transform
|
||||
return IValueTypes.Any;
|
||||
else if (ReflectionHelpers.IsDictionary(type))
|
||||
return IValueTypes.Dictionary;
|
||||
else if (ReflectionHelpers.IsEnumerable(type))
|
||||
@ -69,6 +83,7 @@ namespace UnityExplorer.Inspectors.Reflection
|
||||
public virtual IValueTypes IValueType => IValueTypes.Any;
|
||||
|
||||
public virtual bool HasSubContent => false;
|
||||
public virtual bool SubContentWanted => false;
|
||||
public virtual bool WantInspectBtn => true;
|
||||
|
||||
public string RichTextValue => m_richValue ?? GetLabelForValue();
|
||||
@ -87,16 +102,6 @@ namespace UnityExplorer.Inspectors.Reflection
|
||||
m_valueContent.transform.SetParent(null, false);
|
||||
m_valueContent.SetActive(false);
|
||||
GameObject.Destroy(this.m_valueContent.gameObject);
|
||||
|
||||
//if (OwnerCacheObject.m_subContent)
|
||||
//{
|
||||
// var subTrans = this.OwnerCacheObject.m_subContent.transform;
|
||||
// for (int i = subTrans.childCount - 1; i >= 0; i--)
|
||||
// {
|
||||
// var child = subTrans.GetChild(i);
|
||||
// GameObject.Destroy(child.gameObject);
|
||||
// }
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
@ -115,18 +120,28 @@ namespace UnityExplorer.Inspectors.Reflection
|
||||
GetLabelForValue();
|
||||
m_baseLabel.text = RichTextValue;
|
||||
}
|
||||
}
|
||||
|
||||
bool shouldShowBtns = !Value.IsNullOrDestroyed();
|
||||
public void RefreshElementsAfterUpdate()
|
||||
{
|
||||
if (WantInspectBtn)
|
||||
{
|
||||
bool shouldShowInspect = !Value.IsNullOrDestroyed();
|
||||
|
||||
if (WantInspectBtn && m_inspectButton.activeSelf != shouldShowBtns)
|
||||
m_inspectButton.SetActive(shouldShowBtns);
|
||||
if (m_inspectButton.activeSelf != shouldShowInspect)
|
||||
m_inspectButton.SetActive(shouldShowInspect);
|
||||
}
|
||||
|
||||
bool subContentWanted = SubContentWanted;
|
||||
if (OwnerCacheObject is CacheMember cm && !cm.HasEvaluated)
|
||||
subContentWanted = false;
|
||||
|
||||
if (HasSubContent)
|
||||
{
|
||||
if (m_subExpandBtn.gameObject.activeSelf != shouldShowBtns)
|
||||
m_subExpandBtn.gameObject.SetActive(shouldShowBtns);
|
||||
if (m_subExpandBtn.gameObject.activeSelf != subContentWanted)
|
||||
m_subExpandBtn.gameObject.SetActive(subContentWanted);
|
||||
|
||||
if (!shouldShowBtns && m_subContentParent.activeSelf)
|
||||
if (!subContentWanted && m_subContentParent.activeSelf)
|
||||
ToggleSubcontent();
|
||||
}
|
||||
}
|
||||
@ -151,6 +166,8 @@ namespace UnityExplorer.Inspectors.Reflection
|
||||
}
|
||||
|
||||
OnToggleSubcontent(m_subContentParent.activeSelf);
|
||||
|
||||
RefreshElementsAfterUpdate();
|
||||
}
|
||||
|
||||
internal virtual void OnToggleSubcontent(bool toggle)
|
||||
|
@ -347,7 +347,17 @@ namespace UnityExplorer.Inspectors
|
||||
|
||||
try
|
||||
{
|
||||
var cached = CacheFactory.GetCacheObject(member, target, m_scrollContent);
|
||||
CacheMember cached;
|
||||
if (mi != null && CacheMember.CanProcessArgs(mi.GetParameters()))
|
||||
cached = new CacheMethod(mi, target);
|
||||
else if (pi != null && CacheMember.CanProcessArgs(pi.GetIndexParameters()))
|
||||
cached = new CacheProperty(pi, target);
|
||||
else if (member is FieldInfo fi)
|
||||
cached = new CacheField(fi, target);
|
||||
else
|
||||
continue;
|
||||
|
||||
cached.m_parentContent = m_scrollContent;
|
||||
|
||||
if (cached != null)
|
||||
{
|
||||
|
Reference in New Issue
Block a user