IL2CPP List/Dict support, cleanups

This commit is contained in:
Sinai 2021-05-17 21:48:39 +10:00
parent 7dbf694642
commit d7b0fff949
7 changed files with 117 additions and 95 deletions

View File

@ -80,9 +80,6 @@ namespace UnityExplorer
UIManager.InitUI(); UIManager.InitUI();
Log($"{NAME} {VERSION} initialized."); Log($"{NAME} {VERSION} initialized.");
//InspectorManager.Inspect(typeof(TestClass));
InspectorManager.Inspect(Camera.main.gameObject);
} }
/// <summary> /// <summary>

View File

@ -183,9 +183,9 @@ namespace UnityExplorer.UI.CacheObject
return ValueState.Color; return ValueState.Color;
else if (InteractiveValueStruct.SupportsType(type)) else if (InteractiveValueStruct.SupportsType(type))
return ValueState.ValueStruct; return ValueState.ValueStruct;
else if (typeof(IDictionary).IsAssignableFrom(type)) //(ReflectionUtility.IsDictionary(type)) else if (ReflectionUtility.IsDictionary(type))
return ValueState.Dictionary; return ValueState.Dictionary;
else if (!typeof(Transform).IsAssignableFrom(type) && typeof(IEnumerable).IsAssignableFrom(type)) //ReflectionUtility.IsEnumerable(type)) else if (!typeof(Transform).IsAssignableFrom(type) && ReflectionUtility.IsEnumerable(type))
return ValueState.Collection; return ValueState.Collection;
else else
return ValueState.Unsupported; return ValueState.Unsupported;

View File

@ -25,13 +25,13 @@ namespace UnityExplorer.UI.IValues
public Type ValueType; public Type ValueType;
public IDictionary RefIDictionary; public IDictionary RefIDictionary;
public int ItemCount => values.Count; public int ItemCount => cachedEntries.Count;
private readonly List<object> keys = new List<object>();
private readonly List<object> values = new List<object>();
private readonly List<CacheKeyValuePair> cachedEntries = new List<CacheKeyValuePair>(); private readonly List<CacheKeyValuePair> cachedEntries = new List<CacheKeyValuePair>();
public ScrollPool<CacheKeyValuePairCell> DictScrollPool { get; private set; } public ScrollPool<CacheKeyValuePairCell> DictScrollPool { get; private set; }
private Text NotSupportedLabel;
public Text TopLabel; public Text TopLabel;
public LayoutElement KeyTitleLayout; public LayoutElement KeyTitleLayout;
@ -54,8 +54,6 @@ namespace UnityExplorer.UI.IValues
private void ClearAndRelease() private void ClearAndRelease()
{ {
RefIDictionary = null; RefIDictionary = null;
keys.Clear();
values.Clear();
foreach (var entry in cachedEntries) foreach (var entry in cachedEntries)
{ {
@ -71,8 +69,8 @@ namespace UnityExplorer.UI.IValues
if (value == null) if (value == null)
{ {
// should never be null // should never be null
if (keys.Any()) ClearAndRelease();
ClearAndRelease(); return;
} }
else else
{ {
@ -101,53 +99,48 @@ namespace UnityExplorer.UI.IValues
{ {
RefIDictionary = value as IDictionary; RefIDictionary = value as IDictionary;
if (RefIDictionary == null) if (ReflectionUtility.TryGetDictEnumerator(value, out IEnumerator<DictionaryEntry> dictEnumerator))
{ {
// todo il2cpp NotSupportedLabel.gameObject.SetActive(false);
return;
}
keys.Clear(); int idx = 0;
foreach (var k in RefIDictionary.Keys) while (dictEnumerator.MoveNext())
keys.Add(k);
values.Clear();
foreach (var v in RefIDictionary.Values)
values.Add(v);
int idx = 0;
for (int i = 0; i < keys.Count; i++)
{
CacheKeyValuePair cache;
if (idx >= cachedEntries.Count)
{ {
cache = new CacheKeyValuePair(); CacheKeyValuePair cache;
cache.SetDictOwner(this, i); if (idx >= cachedEntries.Count)
cachedEntries.Add(cache); {
cache = new CacheKeyValuePair();
cache.SetDictOwner(this, idx);
cachedEntries.Add(cache);
}
else
cache = cachedEntries[idx];
cache.SetFallbackType(ValueType);
cache.SetKey(dictEnumerator.Current.Key);
cache.SetValueFromSource(dictEnumerator.Current.Value);
idx++;
} }
else
cache = cachedEntries[i];
cache.SetFallbackType(ValueType); // Remove excess cached entries if dict count decreased
cache.SetKey(keys[i]); if (cachedEntries.Count > idx)
cache.SetValueFromSource(values[i]);
idx++;
}
// Remove excess cached entries if dict count decreased
if (cachedEntries.Count > values.Count)
{
for (int i = cachedEntries.Count - 1; i >= values.Count; i--)
{ {
var cache = cachedEntries[i]; for (int i = cachedEntries.Count - 1; i >= idx; i--)
if (cache.CellView != null) {
cache.UnlinkFromView(); var cache = cachedEntries[i];
if (cache.CellView != null)
cache.UnlinkFromView();
cache.ReleasePooledObjects(); cache.ReleasePooledObjects();
cachedEntries.RemoveAt(i); cachedEntries.RemoveAt(i);
}
} }
} }
else
{
NotSupportedLabel.gameObject.SetActive(true);
}
} }
// Setting value to dictionary // Setting value to dictionary
@ -156,8 +149,6 @@ namespace UnityExplorer.UI.IValues
{ {
try try
{ {
//key = key.TryCast(KeyType);
if (!RefIDictionary.Contains(key)) if (!RefIDictionary.Contains(key))
{ {
ExplorerCore.LogWarning("Unable to set key! Key may have been boxed to/from Il2Cpp Object."); ExplorerCore.LogWarning("Unable to set key! Key may have been boxed to/from Il2Cpp Object.");
@ -255,6 +246,13 @@ namespace UnityExplorer.UI.IValues
DictScrollPool.Initialize(this, SetLayout); DictScrollPool.Initialize(this, SetLayout);
scrollLayout = scrollObj.GetComponent<LayoutElement>(); scrollLayout = scrollObj.GetComponent<LayoutElement>();
NotSupportedLabel = UIFactory.CreateLabel(DictScrollPool.Content.gameObject, "NotSupportedMessage",
"The IDictionary failed to enumerate. This is likely due to an issue with Unhollowed interfaces.",
TextAnchor.MiddleLeft, Color.red);
UIFactory.SetLayoutElement(NotSupportedLabel.gameObject, minHeight: 25, flexibleWidth: 9999);
NotSupportedLabel.gameObject.SetActive(false);
return UIRoot; return UIRoot;
} }
} }

View File

@ -22,7 +22,6 @@ namespace UnityExplorer.UI.IValues
public override bool CanWrite => base.CanWrite && RefIList != null && !RefIList.IsReadOnly; public override bool CanWrite => base.CanWrite && RefIList != null && !RefIList.IsReadOnly;
public Type EntryType; public Type EntryType;
//public IEnumerable RefIEnumerable;
public IList RefIList; public IList RefIList;
public int ItemCount => values.Count; public int ItemCount => values.Count;
@ -49,7 +48,6 @@ namespace UnityExplorer.UI.IValues
private void ClearAndRelease() private void ClearAndRelease()
{ {
//RefIEnumerable = null;
RefIList = null; RefIList = null;
values.Clear(); values.Clear();
@ -94,49 +92,52 @@ namespace UnityExplorer.UI.IValues
{ {
RefIList = value as IList; RefIList = value as IList;
IEnumerator enumerator = (value as IEnumerable).GetEnumerator();
//if (value is IEnumerable enumerable)
// enumerator = enumerable.GetEnumerator();
//else
// enumerator = Il2CppReflection.EnumerateCppList(value);
values.Clear(); values.Clear();
int idx = 0; int idx = 0;
while (enumerator.MoveNext())
if (ReflectionUtility.TryGetEnumerator(value, out IEnumerator enumerator))
{ {
var entry = enumerator.Current; NotSupportedLabel.gameObject.SetActive(false);
values.Add(entry); while (enumerator.MoveNext())
// If list count increased, create new cache entries
CacheListEntry cache;
if (idx >= cachedEntries.Count)
{ {
cache = new CacheListEntry(); var entry = enumerator.Current;
cache.SetListOwner(this, idx);
cachedEntries.Add(cache);
}
else
cache = cachedEntries[idx];
cache.SetFallbackType(this.EntryType); values.Add(entry);
cache.SetValueFromSource(entry);
idx++; // If list count increased, create new cache entries
CacheListEntry cache;
if (idx >= cachedEntries.Count)
{
cache = new CacheListEntry();
cache.SetListOwner(this, idx);
cachedEntries.Add(cache);
}
else
cache = cachedEntries[idx];
cache.SetFallbackType(this.EntryType);
cache.SetValueFromSource(entry);
idx++;
}
// Remove excess cached entries if list count decreased
if (cachedEntries.Count > values.Count)
{
for (int i = cachedEntries.Count - 1; i >= values.Count; i--)
{
var cache = cachedEntries[i];
if (cache.CellView != null)
cache.UnlinkFromView();
cache.ReleasePooledObjects();
cachedEntries.RemoveAt(i);
}
}
} }
else
// Remove excess cached entries if list count decreased
if (cachedEntries.Count > values.Count)
{ {
for (int i = cachedEntries.Count - 1; i >= values.Count; i--) NotSupportedLabel.gameObject.SetActive(true);
{
var cache = cachedEntries[i];
if (cache.CellView != null)
cache.UnlinkFromView();
cache.ReleasePooledObjects();
cachedEntries.RemoveAt(i);
}
} }
} }
@ -185,6 +186,8 @@ namespace UnityExplorer.UI.IValues
private LayoutElement scrollLayout; private LayoutElement scrollLayout;
private Text NotSupportedLabel;
public override GameObject CreateContent(GameObject parent) public override GameObject CreateContent(GameObject parent)
{ {
UIRoot = UIFactory.CreateVerticalGroup(parent, "InteractiveList", true, true, true, true, 6, new Vector4(10, 3, 15, 4), UIRoot = UIFactory.CreateVerticalGroup(parent, "InteractiveList", true, true, true, true, 6, new Vector4(10, 3, 15, 4),
@ -205,6 +208,13 @@ namespace UnityExplorer.UI.IValues
ListScrollPool.Initialize(this, SetLayout); ListScrollPool.Initialize(this, SetLayout);
scrollLayout = scrollObj.GetComponent<LayoutElement>(); scrollLayout = scrollObj.GetComponent<LayoutElement>();
NotSupportedLabel = UIFactory.CreateLabel(ListScrollPool.Content.gameObject, "NotSupportedMessage",
"The IEnumerable failed to enumerate. This is likely due to an issue with Unhollowed interfaces.",
TextAnchor.MiddleLeft, Color.red);
UIFactory.SetLayoutElement(NotSupportedLabel.gameObject, minHeight: 25, flexibleWidth: 9999);
NotSupportedLabel.gameObject.SetActive(false);
return UIRoot; return UIRoot;
} }
} }

View File

@ -62,6 +62,9 @@ namespace UnityExplorer.UI.Inspectors
addChildInput.Text = ""; addChildInput.Text = "";
addCompInput.Text = ""; addCompInput.Text = "";
TransformTree.Clear();
ComponentList.Clear();
} }
public override void CloseInspector() public override void CloseInspector()

View File

@ -19,6 +19,11 @@ namespace UnityExplorer.UI.Inspectors
base.OnCellClicked = OnComponentClicked; base.OnCellClicked = OnComponentClicked;
} }
public void Clear()
{
this.currentEntries.Clear();
}
private bool CheckShouldDisplay(Component _, string __) => true; private bool CheckShouldDisplay(Component _, string __) => true;
public override void OnCellBorrowed(ComponentCell cell) public override void OnCellBorrowed(ComponentCell cell)

View File

@ -50,6 +50,21 @@ namespace UnityExplorer.UI.Widgets
} }
private string currentFilter; private string currentFilter;
public void Init()
{
ScrollPool.Initialize(this);
}
public void Clear()
{
this.displayedObjects.Clear();
displayIndex = 0;
autoExpandedIDs.Clear();
expandedInstanceIDs.Clear();
}
public void OnGameObjectClicked(GameObject obj) public void OnGameObjectClicked(GameObject obj)
{ {
if (OnClickOverrideHandler != null) if (OnClickOverrideHandler != null)
@ -68,12 +83,6 @@ namespace UnityExplorer.UI.Widgets
GetRootEntriesMethod = getRootEntriesMethod; GetRootEntriesMethod = getRootEntriesMethod;
} }
public void Init()
{
ScrollPool.Initialize(this);
}
public bool IsCellExpanded(int instanceID) public bool IsCellExpanded(int instanceID)
{ {
return Filtering ? autoExpandedIDs.Contains(instanceID) return Filtering ? autoExpandedIDs.Contains(instanceID)