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();
Log($"{NAME} {VERSION} initialized.");
//InspectorManager.Inspect(typeof(TestClass));
InspectorManager.Inspect(Camera.main.gameObject);
}
/// <summary>

View File

@ -183,9 +183,9 @@ namespace UnityExplorer.UI.CacheObject
return ValueState.Color;
else if (InteractiveValueStruct.SupportsType(type))
return ValueState.ValueStruct;
else if (typeof(IDictionary).IsAssignableFrom(type)) //(ReflectionUtility.IsDictionary(type))
else if (ReflectionUtility.IsDictionary(type))
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;
else
return ValueState.Unsupported;

View File

@ -25,13 +25,13 @@ namespace UnityExplorer.UI.IValues
public Type ValueType;
public IDictionary RefIDictionary;
public int ItemCount => values.Count;
private readonly List<object> keys = new List<object>();
private readonly List<object> values = new List<object>();
public int ItemCount => cachedEntries.Count;
private readonly List<CacheKeyValuePair> cachedEntries = new List<CacheKeyValuePair>();
public ScrollPool<CacheKeyValuePairCell> DictScrollPool { get; private set; }
private Text NotSupportedLabel;
public Text TopLabel;
public LayoutElement KeyTitleLayout;
@ -54,8 +54,6 @@ namespace UnityExplorer.UI.IValues
private void ClearAndRelease()
{
RefIDictionary = null;
keys.Clear();
values.Clear();
foreach (var entry in cachedEntries)
{
@ -71,8 +69,8 @@ namespace UnityExplorer.UI.IValues
if (value == null)
{
// should never be null
if (keys.Any())
ClearAndRelease();
ClearAndRelease();
return;
}
else
{
@ -101,53 +99,48 @@ namespace UnityExplorer.UI.IValues
{
RefIDictionary = value as IDictionary;
if (RefIDictionary == null)
if (ReflectionUtility.TryGetDictEnumerator(value, out IEnumerator<DictionaryEntry> dictEnumerator))
{
// todo il2cpp
return;
}
NotSupportedLabel.gameObject.SetActive(false);
keys.Clear();
foreach (var k in RefIDictionary.Keys)
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)
int idx = 0;
while (dictEnumerator.MoveNext())
{
cache = new CacheKeyValuePair();
cache.SetDictOwner(this, i);
cachedEntries.Add(cache);
CacheKeyValuePair cache;
if (idx >= cachedEntries.Count)
{
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);
cache.SetKey(keys[i]);
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--)
// Remove excess cached entries if dict count decreased
if (cachedEntries.Count > idx)
{
var cache = cachedEntries[i];
if (cache.CellView != null)
cache.UnlinkFromView();
for (int i = cachedEntries.Count - 1; i >= idx; i--)
{
var cache = cachedEntries[i];
if (cache.CellView != null)
cache.UnlinkFromView();
cache.ReleasePooledObjects();
cachedEntries.RemoveAt(i);
cache.ReleasePooledObjects();
cachedEntries.RemoveAt(i);
}
}
}
else
{
NotSupportedLabel.gameObject.SetActive(true);
}
}
// Setting value to dictionary
@ -156,8 +149,6 @@ namespace UnityExplorer.UI.IValues
{
try
{
//key = key.TryCast(KeyType);
if (!RefIDictionary.Contains(key))
{
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);
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;
}
}

View File

@ -22,7 +22,6 @@ namespace UnityExplorer.UI.IValues
public override bool CanWrite => base.CanWrite && RefIList != null && !RefIList.IsReadOnly;
public Type EntryType;
//public IEnumerable RefIEnumerable;
public IList RefIList;
public int ItemCount => values.Count;
@ -49,7 +48,6 @@ namespace UnityExplorer.UI.IValues
private void ClearAndRelease()
{
//RefIEnumerable = null;
RefIList = null;
values.Clear();
@ -94,49 +92,52 @@ namespace UnityExplorer.UI.IValues
{
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();
int idx = 0;
while (enumerator.MoveNext())
if (ReflectionUtility.TryGetEnumerator(value, out IEnumerator enumerator))
{
var entry = enumerator.Current;
NotSupportedLabel.gameObject.SetActive(false);
values.Add(entry);
// If list count increased, create new cache entries
CacheListEntry cache;
if (idx >= cachedEntries.Count)
while (enumerator.MoveNext())
{
cache = new CacheListEntry();
cache.SetListOwner(this, idx);
cachedEntries.Add(cache);
}
else
cache = cachedEntries[idx];
var entry = enumerator.Current;
cache.SetFallbackType(this.EntryType);
cache.SetValueFromSource(entry);
idx++;
values.Add(entry);
// 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);
}
}
}
// Remove excess cached entries if list count decreased
if (cachedEntries.Count > values.Count)
else
{
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);
}
NotSupportedLabel.gameObject.SetActive(true);
}
}
@ -185,6 +186,8 @@ namespace UnityExplorer.UI.IValues
private LayoutElement scrollLayout;
private Text NotSupportedLabel;
public override GameObject CreateContent(GameObject parent)
{
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);
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;
}
}

View File

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

View File

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

View File

@ -50,6 +50,21 @@ namespace UnityExplorer.UI.Widgets
}
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)
{
if (OnClickOverrideHandler != null)
@ -68,12 +83,6 @@ namespace UnityExplorer.UI.Widgets
GetRootEntriesMethod = getRootEntriesMethod;
}
public void Init()
{
ScrollPool.Initialize(this);
}
public bool IsCellExpanded(int instanceID)
{
return Filtering ? autoExpandedIDs.Contains(instanceID)