Use recursive GetGenericArguments to catch unusual type structures, cleanup InteractiveList value caching

This commit is contained in:
Sinai 2021-05-18 20:55:18 +10:00
parent 496a5de55e
commit ac9c2d5286
3 changed files with 32 additions and 15 deletions

View File

@ -36,6 +36,27 @@ namespace UnityExplorer
// ------- Misc extensions -------- // ------- Misc extensions --------
/// <summary>
/// Recursively check the type and its base types to find any generic arguments.
/// </summary>
public static bool TryGetGenericArguments(this Type type, out Type[] args)
{
if (type.IsGenericType)
{
args = type.GetGenericArguments();
return true;
}
else if (type.BaseType != null)
{
return TryGetGenericArguments(type.BaseType, out args);
}
else
{
args = null;
return false;
}
}
/// <summary> /// <summary>
/// Safely try to get all Types inside an Assembly. /// Safely try to get all Types inside an Assembly.
/// </summary> /// </summary>

View File

@ -75,10 +75,11 @@ namespace UnityExplorer.UI.IValues
else else
{ {
var type = value.GetActualType(); var type = value.GetActualType();
if (type.IsGenericType && type.GetGenericArguments().Length == 2)
if (type.TryGetGenericArguments(out var args) && args.Length == 2)
{ {
KeyType = type.GetGenericArguments()[0]; KeyType = args[0];
ValueType = type.GetGenericArguments()[1]; ValueType = args[1];
} }
else else
{ {

View File

@ -28,8 +28,7 @@ namespace UnityExplorer.UI.IValues
private bool IsWritableGenericIList; private bool IsWritableGenericIList;
private PropertyInfo genericIndexer; private PropertyInfo genericIndexer;
public int ItemCount => values.Count; public int ItemCount => cachedEntries.Count;
private readonly List<object> values = new List<object>();
private readonly List<CacheListEntry> cachedEntries = new List<CacheListEntry>(); private readonly List<CacheListEntry> cachedEntries = new List<CacheListEntry>();
public ScrollPool<CacheListEntryCell> ListScrollPool { get; private set; } public ScrollPool<CacheListEntryCell> ListScrollPool { get; private set; }
@ -53,7 +52,6 @@ namespace UnityExplorer.UI.IValues
private void ClearAndRelease() private void ClearAndRelease()
{ {
RefIList = null; RefIList = null;
values.Clear();
foreach (var entry in cachedEntries) foreach (var entry in cachedEntries)
{ {
@ -70,14 +68,14 @@ namespace UnityExplorer.UI.IValues
if (value == null) if (value == null)
{ {
// should never be null // should never be null
if (values.Any()) if (cachedEntries.Any())
ClearAndRelease(); ClearAndRelease();
} }
else else
{ {
var type = value.GetActualType(); var type = value.GetActualType();
if (type.IsGenericType) if (type.TryGetGenericArguments(out var args))
EntryType = type.GetGenericArguments()[0]; EntryType = args[0];
else if (type.HasElementType) else if (type.HasElementType)
EntryType = type.GetElementType(); EntryType = type.GetElementType();
else else
@ -102,7 +100,6 @@ namespace UnityExplorer.UI.IValues
else else
IsWritableGenericIList = false; IsWritableGenericIList = false;
values.Clear();
int idx = 0; int idx = 0;
if (ReflectionUtility.TryGetEnumerator(value, out IEnumerator enumerator)) if (ReflectionUtility.TryGetEnumerator(value, out IEnumerator enumerator))
@ -113,8 +110,6 @@ namespace UnityExplorer.UI.IValues
{ {
var entry = enumerator.Current; var entry = enumerator.Current;
values.Add(entry);
// If list count increased, create new cache entries // If list count increased, create new cache entries
CacheListEntry cache; CacheListEntry cache;
if (idx >= cachedEntries.Count) if (idx >= cachedEntries.Count)
@ -132,9 +127,9 @@ namespace UnityExplorer.UI.IValues
} }
// Remove excess cached entries if list count decreased // Remove excess cached entries if list count decreased
if (cachedEntries.Count > values.Count) if (cachedEntries.Count > idx)
{ {
for (int i = cachedEntries.Count - 1; i >= values.Count; i--) for (int i = cachedEntries.Count - 1; i >= idx; i--)
{ {
var cache = cachedEntries[i]; var cache = cachedEntries[i];
if (cache.CellView != null) if (cache.CellView != null)