Skip to content
This repository was archived by the owner on May 9, 2023. It is now read-only.

Commit d7b0fff

Browse files
committed
IL2CPP List/Dict support, cleanups
1 parent 7dbf694 commit d7b0fff

File tree

7 files changed

+117
-95
lines changed

7 files changed

+117
-95
lines changed

src/ExplorerCore.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,6 @@ private static IEnumerator SetupCoroutine()
8080
UIManager.InitUI();
8181

8282
Log($"{NAME} {VERSION} initialized.");
83-
84-
//InspectorManager.Inspect(typeof(TestClass));
85-
InspectorManager.Inspect(Camera.main.gameObject);
8683
}
8784

8885
/// <summary>

src/UI/CacheObject/CacheObjectBase.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,9 +183,9 @@ public ValueState GetStateForType(Type type)
183183
return ValueState.Color;
184184
else if (InteractiveValueStruct.SupportsType(type))
185185
return ValueState.ValueStruct;
186-
else if (typeof(IDictionary).IsAssignableFrom(type)) //(ReflectionUtility.IsDictionary(type))
186+
else if (ReflectionUtility.IsDictionary(type))
187187
return ValueState.Dictionary;
188-
else if (!typeof(Transform).IsAssignableFrom(type) && typeof(IEnumerable).IsAssignableFrom(type)) //ReflectionUtility.IsEnumerable(type))
188+
else if (!typeof(Transform).IsAssignableFrom(type) && ReflectionUtility.IsEnumerable(type))
189189
return ValueState.Collection;
190190
else
191191
return ValueState.Unsupported;

src/UI/IValues/InteractiveDictionary.cs

Lines changed: 46 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,13 @@ public class InteractiveDictionary : InteractiveValue, ICellPoolDataSource<Cache
2525
public Type ValueType;
2626
public IDictionary RefIDictionary;
2727

28-
public int ItemCount => values.Count;
29-
private readonly List<object> keys = new List<object>();
30-
private readonly List<object> values = new List<object>();
28+
public int ItemCount => cachedEntries.Count;
3129
private readonly List<CacheKeyValuePair> cachedEntries = new List<CacheKeyValuePair>();
3230

3331
public ScrollPool<CacheKeyValuePairCell> DictScrollPool { get; private set; }
3432

33+
private Text NotSupportedLabel;
34+
3535
public Text TopLabel;
3636

3737
public LayoutElement KeyTitleLayout;
@@ -54,8 +54,6 @@ public override void ReleaseFromOwner()
5454
private void ClearAndRelease()
5555
{
5656
RefIDictionary = null;
57-
keys.Clear();
58-
values.Clear();
5957

6058
foreach (var entry in cachedEntries)
6159
{
@@ -71,8 +69,8 @@ public override void SetValue(object value)
7169
if (value == null)
7270
{
7371
// should never be null
74-
if (keys.Any())
75-
ClearAndRelease();
72+
ClearAndRelease();
73+
return;
7674
}
7775
else
7876
{
@@ -101,53 +99,48 @@ private void CacheEntries(object value)
10199
{
102100
RefIDictionary = value as IDictionary;
103101

104-
if (RefIDictionary == null)
102+
if (ReflectionUtility.TryGetDictEnumerator(value, out IEnumerator<DictionaryEntry> dictEnumerator))
105103
{
106-
// todo il2cpp
107-
return;
108-
}
109-
110-
keys.Clear();
111-
foreach (var k in RefIDictionary.Keys)
112-
keys.Add(k);
104+
NotSupportedLabel.gameObject.SetActive(false);
113105

114-
values.Clear();
115-
foreach (var v in RefIDictionary.Values)
116-
values.Add(v);
117-
118-
int idx = 0;
119-
for (int i = 0; i < keys.Count; i++)
120-
{
121-
CacheKeyValuePair cache;
122-
if (idx >= cachedEntries.Count)
106+
int idx = 0;
107+
while (dictEnumerator.MoveNext())
123108
{
124-
cache = new CacheKeyValuePair();
125-
cache.SetDictOwner(this, i);
126-
cachedEntries.Add(cache);
109+
CacheKeyValuePair cache;
110+
if (idx >= cachedEntries.Count)
111+
{
112+
cache = new CacheKeyValuePair();
113+
cache.SetDictOwner(this, idx);
114+
cachedEntries.Add(cache);
115+
}
116+
else
117+
cache = cachedEntries[idx];
118+
119+
cache.SetFallbackType(ValueType);
120+
cache.SetKey(dictEnumerator.Current.Key);
121+
cache.SetValueFromSource(dictEnumerator.Current.Value);
122+
123+
idx++;
127124
}
128-
else
129-
cache = cachedEntries[i];
130-
131-
cache.SetFallbackType(ValueType);
132-
cache.SetKey(keys[i]);
133-
cache.SetValueFromSource(values[i]);
134125

135-
idx++;
136-
}
137-
138-
// Remove excess cached entries if dict count decreased
139-
if (cachedEntries.Count > values.Count)
140-
{
141-
for (int i = cachedEntries.Count - 1; i >= values.Count; i--)
126+
// Remove excess cached entries if dict count decreased
127+
if (cachedEntries.Count > idx)
142128
{
143-
var cache = cachedEntries[i];
144-
if (cache.CellView != null)
145-
cache.UnlinkFromView();
146-
147-
cache.ReleasePooledObjects();
148-
cachedEntries.RemoveAt(i);
129+
for (int i = cachedEntries.Count - 1; i >= idx; i--)
130+
{
131+
var cache = cachedEntries[i];
132+
if (cache.CellView != null)
133+
cache.UnlinkFromView();
134+
135+
cache.ReleasePooledObjects();
136+
cachedEntries.RemoveAt(i);
137+
}
149138
}
150139
}
140+
else
141+
{
142+
NotSupportedLabel.gameObject.SetActive(true);
143+
}
151144
}
152145

153146
// Setting value to dictionary
@@ -156,8 +149,6 @@ public void TrySetValueToKey(object key, object value, int keyIndex)
156149
{
157150
try
158151
{
159-
//key = key.TryCast(KeyType);
160-
161152
if (!RefIDictionary.Contains(key))
162153
{
163154
ExplorerCore.LogWarning("Unable to set key! Key may have been boxed to/from Il2Cpp Object.");
@@ -255,6 +246,13 @@ public override GameObject CreateContent(GameObject parent)
255246
DictScrollPool.Initialize(this, SetLayout);
256247
scrollLayout = scrollObj.GetComponent<LayoutElement>();
257248

249+
NotSupportedLabel = UIFactory.CreateLabel(DictScrollPool.Content.gameObject, "NotSupportedMessage",
250+
"The IDictionary failed to enumerate. This is likely due to an issue with Unhollowed interfaces.",
251+
TextAnchor.MiddleLeft, Color.red);
252+
253+
UIFactory.SetLayoutElement(NotSupportedLabel.gameObject, minHeight: 25, flexibleWidth: 9999);
254+
NotSupportedLabel.gameObject.SetActive(false);
255+
258256
return UIRoot;
259257
}
260258
}

src/UI/IValues/InteractiveList.cs

Lines changed: 46 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ public class InteractiveList : InteractiveValue, ICellPoolDataSource<CacheListEn
2222
public override bool CanWrite => base.CanWrite && RefIList != null && !RefIList.IsReadOnly;
2323

2424
public Type EntryType;
25-
//public IEnumerable RefIEnumerable;
2625
public IList RefIList;
2726

2827
public int ItemCount => values.Count;
@@ -49,7 +48,6 @@ public override void ReleaseFromOwner()
4948

5049
private void ClearAndRelease()
5150
{
52-
//RefIEnumerable = null;
5351
RefIList = null;
5452
values.Clear();
5553

@@ -94,50 +92,53 @@ private void CacheEntries(object value)
9492
{
9593
RefIList = value as IList;
9694

97-
IEnumerator enumerator = (value as IEnumerable).GetEnumerator();
98-
99-
//if (value is IEnumerable enumerable)
100-
// enumerator = enumerable.GetEnumerator();
101-
//else
102-
// enumerator = Il2CppReflection.EnumerateCppList(value);
103-
10495
values.Clear();
10596
int idx = 0;
106-
while (enumerator.MoveNext())
107-
{
108-
var entry = enumerator.Current;
10997

110-
values.Add(entry);
98+
if (ReflectionUtility.TryGetEnumerator(value, out IEnumerator enumerator))
99+
{
100+
NotSupportedLabel.gameObject.SetActive(false);
111101

112-
// If list count increased, create new cache entries
113-
CacheListEntry cache;
114-
if (idx >= cachedEntries.Count)
102+
while (enumerator.MoveNext())
115103
{
116-
cache = new CacheListEntry();
117-
cache.SetListOwner(this, idx);
118-
cachedEntries.Add(cache);
104+
var entry = enumerator.Current;
105+
106+
values.Add(entry);
107+
108+
// If list count increased, create new cache entries
109+
CacheListEntry cache;
110+
if (idx >= cachedEntries.Count)
111+
{
112+
cache = new CacheListEntry();
113+
cache.SetListOwner(this, idx);
114+
cachedEntries.Add(cache);
115+
}
116+
else
117+
cache = cachedEntries[idx];
118+
119+
cache.SetFallbackType(this.EntryType);
120+
cache.SetValueFromSource(entry);
121+
idx++;
119122
}
120-
else
121-
cache = cachedEntries[idx];
122-
123-
cache.SetFallbackType(this.EntryType);
124-
cache.SetValueFromSource(entry);
125-
idx++;
126-
}
127123

128-
// Remove excess cached entries if list count decreased
129-
if (cachedEntries.Count > values.Count)
130-
{
131-
for (int i = cachedEntries.Count - 1; i >= values.Count; i--)
124+
// Remove excess cached entries if list count decreased
125+
if (cachedEntries.Count > values.Count)
132126
{
133-
var cache = cachedEntries[i];
134-
if (cache.CellView != null)
135-
cache.UnlinkFromView();
136-
137-
cache.ReleasePooledObjects();
138-
cachedEntries.RemoveAt(i);
127+
for (int i = cachedEntries.Count - 1; i >= values.Count; i--)
128+
{
129+
var cache = cachedEntries[i];
130+
if (cache.CellView != null)
131+
cache.UnlinkFromView();
132+
133+
cache.ReleasePooledObjects();
134+
cachedEntries.RemoveAt(i);
135+
}
139136
}
140137
}
138+
else
139+
{
140+
NotSupportedLabel.gameObject.SetActive(true);
141+
}
141142
}
142143

143144
// Setting the value of an index to the list
@@ -185,6 +186,8 @@ public void SetCell(CacheListEntryCell cell, int index)
185186

186187
private LayoutElement scrollLayout;
187188

189+
private Text NotSupportedLabel;
190+
188191
public override GameObject CreateContent(GameObject parent)
189192
{
190193
UIRoot = UIFactory.CreateVerticalGroup(parent, "InteractiveList", true, true, true, true, 6, new Vector4(10, 3, 15, 4),
@@ -205,6 +208,13 @@ public override GameObject CreateContent(GameObject parent)
205208
ListScrollPool.Initialize(this, SetLayout);
206209
scrollLayout = scrollObj.GetComponent<LayoutElement>();
207210

211+
NotSupportedLabel = UIFactory.CreateLabel(ListScrollPool.Content.gameObject, "NotSupportedMessage",
212+
"The IEnumerable failed to enumerate. This is likely due to an issue with Unhollowed interfaces.",
213+
TextAnchor.MiddleLeft, Color.red);
214+
215+
UIFactory.SetLayoutElement(NotSupportedLabel.gameObject, minHeight: 25, flexibleWidth: 9999);
216+
NotSupportedLabel.gameObject.SetActive(false);
217+
208218
return UIRoot;
209219
}
210220
}

src/UI/Inspectors/GameObjectInspector.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ public override void OnReturnToPool()
6262

6363
addChildInput.Text = "";
6464
addCompInput.Text = "";
65+
66+
TransformTree.Clear();
67+
ComponentList.Clear();
6568
}
6669

6770
public override void CloseInspector()

src/UI/Inspectors/GameObjectWidgets/ComponentList.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ public ComponentList(ScrollPool<ComponentCell> scrollPool, Func<List<Component>>
1919
base.OnCellClicked = OnComponentClicked;
2020
}
2121

22+
public void Clear()
23+
{
24+
this.currentEntries.Clear();
25+
}
26+
2227
private bool CheckShouldDisplay(Component _, string __) => true;
2328

2429
public override void OnCellBorrowed(ComponentCell cell)

src/UI/Widgets/TransformTree/TransformTree.cs

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,21 @@ public string CurrentFilter
5050
}
5151
private string currentFilter;
5252

53+
54+
public void Init()
55+
{
56+
ScrollPool.Initialize(this);
57+
}
58+
59+
public void Clear()
60+
{
61+
this.displayedObjects.Clear();
62+
displayIndex = 0;
63+
autoExpandedIDs.Clear();
64+
expandedInstanceIDs.Clear();
65+
}
66+
67+
5368
public void OnGameObjectClicked(GameObject obj)
5469
{
5570
if (OnClickOverrideHandler != null)
@@ -68,12 +83,6 @@ public TransformTree(ScrollPool<TransformCell> scrollPool, Func<IEnumerable<Game
6883
GetRootEntriesMethod = getRootEntriesMethod;
6984
}
7085

71-
public void Init()
72-
{
73-
ScrollPool.Initialize(this);
74-
}
75-
76-
7786
public bool IsCellExpanded(int instanceID)
7887
{
7988
return Filtering ? autoExpandedIDs.Contains(instanceID)

0 commit comments

Comments
 (0)