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

Commit 6bafab7

Browse files
committed
1.4.1
* Cleanup some small bugs introduced in 1.4.0 * Added better exception handling for failed Reflection, and the ability to hide failed reflection members in the Reflection window, as well as see the error type. * Reflection window members now display the full name instead of just the member name (eg. "Camera.main" instead of just "main").
1 parent 62b1688 commit 6bafab7

File tree

13 files changed

+272
-275
lines changed

13 files changed

+272
-275
lines changed

src/CachedObjects/CacheEnum.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,11 @@ public class CacheEnum : CacheObject
1515

1616
public CacheEnum(object obj)
1717
{
18-
m_enumType = obj.GetType();
19-
m_names = Enum.GetNames(obj.GetType());
18+
if (obj != null)
19+
{
20+
m_enumType = obj.GetType();
21+
m_names = Enum.GetNames(m_enumType);
22+
}
2023
}
2124

2225
public override void DrawValue(Rect window, float width)

src/CachedObjects/CacheGameObject.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,9 @@ public override void SetValue()
4343
throw new NotImplementedException("TODO");
4444
}
4545

46-
public override void UpdateValue(object obj)
46+
public override void UpdateValue()
4747
{
48-
base.UpdateValue(obj);
48+
base.UpdateValue();
4949

5050
m_gameObject = GetGameObject(Value);
5151
}

src/CachedObjects/CacheIl2CppObject.cs

Lines changed: 0 additions & 37 deletions
This file was deleted.

src/CachedObjects/CacheList.cs

Lines changed: 54 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Reflection;
66
using System.Text;
77
using System.Threading.Tasks;
8+
using Mono.CSharp;
89
using UnityEngine;
910

1011
namespace Explorer
@@ -13,30 +14,56 @@ public partial class CacheList : CacheObject
1314
{
1415
public bool IsExpanded { get; set; }
1516
public int ArrayOffset { get; set; }
16-
public Type EntryType { get; set; }
17+
18+
public Type EntryType
19+
{
20+
get
21+
{
22+
if (m_entryType == null)
23+
{
24+
m_entryType = Value?.GetType().GetGenericArguments()[0];
25+
}
26+
return m_entryType;
27+
}
28+
set
29+
{
30+
m_entryType = value;
31+
}
32+
}
33+
private Type m_entryType;
34+
35+
public IEnumerable Enumerable
36+
{
37+
get
38+
{
39+
if (m_enumerable == null && Value != null)
40+
{
41+
m_enumerable = Value as IEnumerable ?? CppListToEnumerable(Value);
42+
}
43+
return m_enumerable;
44+
}
45+
}
1746

1847
private IEnumerable m_enumerable;
1948
private CacheObject[] m_cachedEntries;
2049

2150
public CacheList(object obj)
2251
{
23-
GetEnumerable(obj);
24-
EntryType = m_enumerable.GetType().GetGenericArguments()[0];
52+
if (obj != null)
53+
{
54+
Value = obj;
55+
EntryType = obj.GetType().GetGenericArguments()[0];
56+
}
2557
}
2658

27-
private void GetEnumerable(object obj)
59+
private IEnumerable CppListToEnumerable(object list)
2860
{
29-
if (obj is IEnumerable isEnumerable)
30-
{
31-
m_enumerable = isEnumerable;
32-
}
33-
else
34-
{
35-
var listValueType = obj.GetType().GetGenericArguments()[0];
36-
var listType = typeof(Il2CppSystem.Collections.Generic.List<>).MakeGenericType(new Type[] { listValueType });
37-
var method = listType.GetMethod("ToArray");
38-
m_enumerable = (IEnumerable)method.Invoke(obj, new object[0]);
39-
}
61+
if (EntryType == null) return null;
62+
63+
return (IEnumerable)typeof(Il2CppSystem.Collections.Generic.List<>)
64+
.MakeGenericType(new Type[] { EntryType })
65+
.GetMethod("ToArray")
66+
.Invoke(list, new object[0]);
4067
}
4168

4269
public override void DrawValue(Rect window, float width)
@@ -73,7 +100,7 @@ public override void DrawValue(Rect window, float width)
73100
GUILayout.EndHorizontal();
74101
GUILayout.BeginHorizontal(null);
75102
GUILayout.Space(190);
76-
int maxOffset = (int)Mathf.Ceil(count / CppExplorer.ArrayLimit);
103+
int maxOffset = (int)Mathf.Ceil((float)(count / (decimal)CppExplorer.ArrayLimit)) - 1;
77104
GUILayout.Label($"Page {ArrayOffset + 1}/{maxOffset + 1}", new GUILayoutOption[] { GUILayout.Width(80) });
78105
// prev/next page buttons
79106
if (GUILayout.Button("< Prev", null))
@@ -99,7 +126,7 @@ public override void DrawValue(Rect window, float width)
99126
GUILayout.BeginHorizontal(null);
100127
GUILayout.Space(190);
101128

102-
if (entry == null)
129+
if (entry.Value == null)
103130
{
104131
GUILayout.Label("<i><color=grey>null</color></i>", null);
105132
}
@@ -108,22 +135,6 @@ public override void DrawValue(Rect window, float width)
108135
GUILayout.Label(i.ToString(), new GUILayoutOption[] { GUILayout.Width(30) });
109136

110137
entry.DrawValue(window, window.width - 250);
111-
112-
//var lbl = i + ": <color=cyan>" + obj.Value.ToString() + "</color>";
113-
114-
//if (EntryType.IsPrimitive || typeof(string).IsAssignableFrom(EntryType))
115-
//{
116-
// GUILayout.Label(lbl, null);
117-
//}
118-
//else
119-
//{
120-
// GUI.skin.button.alignment = TextAnchor.MiddleLeft;
121-
// if (GUILayout.Button(lbl, null))
122-
// {
123-
// WindowManager.InspectObject(obj, out _);
124-
// }
125-
// GUI.skin.button.alignment = TextAnchor.MiddleCenter;
126-
//}
127138
}
128139
}
129140
}
@@ -134,14 +145,20 @@ public override void SetValue()
134145
throw new NotImplementedException("TODO");
135146
}
136147

137-
public override void UpdateValue(object obj)
148+
/// <summary>
149+
/// Called when the user presses the "Update" button, or if AutoUpdate is on.
150+
/// </summary>
151+
public override void UpdateValue()
138152
{
139-
GetEnumerable(Value);
153+
base.UpdateValue();
140154

141-
var list = new List<CacheObject>();
155+
if (Value == null) return;
156+
157+
var enumerator = Enumerable?.GetEnumerator();
142158

143-
var enumerator = m_enumerable.GetEnumerator();
159+
if (enumerator == null) return;
144160

161+
var list = new List<CacheObject>();
145162
while (enumerator.MoveNext())
146163
{
147164
list.Add(GetCacheObject(enumerator.Current));

src/CachedObjects/CacheObject.cs

Lines changed: 57 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@ public abstract class CacheObject
2020
public ReflectionWindow.MemberInfoType MemberInfoType { get; set; }
2121
public Type DeclaringType { get; set; }
2222
public object DeclaringInstance { get; set; }
23+
public string FullName => $"{MemberInfo.DeclaringType.Name}.{MemberInfo.Name}";
24+
public string ReflectionException;
2325

26+
// methods
2427
public abstract void DrawValue(Rect window, float width);
2528
public abstract void SetValue();
2629

@@ -29,73 +32,63 @@ public static CacheObject GetCacheObject(object obj)
2932
return GetCacheObject(obj, null, null);
3033
}
3134

35+
/// <summary>
36+
/// Gets the CacheObject subclass for an object or MemberInfo
37+
/// </summary>
38+
/// <param name="obj">The current value (can be null if memberInfo is not null)</param>
39+
/// <param name="memberInfo">The MemberInfo (can be null if obj is not null)</param>
40+
/// <param name="declaringInstance">If MemberInfo is not null, the declaring class instance. Can be null if static.</param>
41+
/// <returns></returns>
3242
public static CacheObject GetCacheObject(object obj, MemberInfo memberInfo, object declaringInstance)
3343
{
3444
CacheObject holder;
3545

3646
var type = ReflectionHelpers.GetActualType(obj) ?? (memberInfo as FieldInfo)?.FieldType ?? (memberInfo as PropertyInfo)?.PropertyType;
3747

38-
if (obj is Il2CppSystem.Object || typeof(Il2CppSystem.Object).IsAssignableFrom(type))
48+
if ((obj is Il2CppSystem.Object || typeof(Il2CppSystem.Object).IsAssignableFrom(type))
49+
&& (type.FullName.Contains("UnityEngine.GameObject") || type.FullName.Contains("UnityEngine.Transform")))
3950
{
40-
var name = type.FullName;
41-
if (name == "UnityEngine.GameObject" || name == "UnityEngine.Transform")
42-
{
43-
holder = new CacheGameObject(obj);
44-
}
45-
else
46-
{
47-
holder = new CacheIl2CppObject();
48-
}
51+
holder = new CacheGameObject(obj);
4952
}
50-
else
53+
else if (type.IsPrimitive || type == typeof(string))
5154
{
52-
if (type.IsPrimitive || type == typeof(string))
53-
{
54-
holder = new CachePrimitive(obj);
55-
}
56-
else if (type.IsEnum)
57-
{
58-
holder = new CacheEnum(obj);
59-
}
60-
else if (typeof(System.Collections.IEnumerable).IsAssignableFrom(type) || ReflectionHelpers.IsList(type))
61-
{
62-
holder = new CacheList(obj);
63-
}
64-
else if (type.IsValueType)
65-
{
66-
holder = new CacheStruct(obj);
67-
}
68-
else
69-
{
70-
holder = new CacheOther();
71-
}
55+
holder = new CachePrimitive(obj);
7256
}
73-
74-
if (holder == null)
57+
else if (type.IsEnum)
7558
{
76-
return null;
59+
holder = new CacheEnum(obj);
60+
}
61+
else if (typeof(System.Collections.IEnumerable).IsAssignableFrom(type) || ReflectionHelpers.IsList(type))
62+
{
63+
holder = new CacheList(obj);
64+
}
65+
else
66+
{
67+
holder = new CacheOther();
7768
}
7869

7970
if (memberInfo != null)
8071
{
8172
holder.MemberInfo = memberInfo;
8273
holder.DeclaringType = memberInfo.DeclaringType;
83-
84-
if (declaringInstance is Il2CppSystem.Object ilInstance && ilInstance.GetType() != memberInfo.DeclaringType)
85-
{
86-
try
87-
{
88-
holder.DeclaringInstance = ilInstance.Il2CppCast(holder.DeclaringType);
89-
}
90-
catch
91-
{
92-
holder.DeclaringInstance = declaringInstance;
93-
}
94-
}
95-
else
96-
{
97-
holder.DeclaringInstance = declaringInstance;
98-
}
74+
holder.DeclaringInstance = declaringInstance;
75+
76+
//if (declaringInstance is Il2CppSystem.Object ilInstance && ilInstance.GetType() != memberInfo.DeclaringType)
77+
//{
78+
// try
79+
// {
80+
// holder.DeclaringInstance = ilInstance.Il2CppCast(holder.DeclaringType);
81+
// }
82+
// catch (Exception e)
83+
// {
84+
// holder.ReflectionException = ReflectionHelpers.ExceptionToString(e);
85+
// holder.DeclaringInstance = declaringInstance;
86+
// }
87+
//}
88+
//else
89+
//{
90+
// holder.DeclaringInstance = declaringInstance;
91+
//}
9992

10093
if (memberInfo.MemberType == MemberTypes.Field)
10194
{
@@ -121,14 +114,18 @@ public void Draw(Rect window, float labelWidth = 180f)
121114
{
122115
if (MemberInfo != null)
123116
{
124-
GUILayout.Label("<color=cyan>" + MemberInfo.Name + ":</color>", new GUILayoutOption[] { GUILayout.Width(labelWidth) });
117+
GUILayout.Label("<color=cyan>" + FullName + ":</color>", new GUILayoutOption[] { GUILayout.Width(labelWidth) });
125118
}
126119
else
127120
{
128121
GUILayout.Space(labelWidth);
129122
}
130123

131-
if (Value == null)
124+
if (!string.IsNullOrEmpty(ReflectionException))
125+
{
126+
GUILayout.Label("<color=red>Reflection failed!</color> (" + ReflectionException + ")", null);
127+
}
128+
else if (Value == null)
132129
{
133130
GUILayout.Label("<i>null (" + this.ValueType + ")</i>", null);
134131
}
@@ -138,9 +135,9 @@ public void Draw(Rect window, float labelWidth = 180f)
138135
}
139136
}
140137

141-
public virtual void UpdateValue(object obj)
138+
public virtual void UpdateValue()
142139
{
143-
if (MemberInfo == null)
140+
if (MemberInfo == null || !string.IsNullOrEmpty(ReflectionException))
144141
{
145142
return;
146143
}
@@ -155,12 +152,15 @@ public virtual void UpdateValue(object obj)
155152
else if (MemberInfo.MemberType == MemberTypes.Property)
156153
{
157154
var pi = MemberInfo as PropertyInfo;
158-
Value = pi.GetValue(pi.GetAccessors()[0].IsStatic ? null : DeclaringInstance, null);
155+
bool isStatic = pi.GetAccessors()[0].IsStatic;
156+
var target = isStatic ? null : DeclaringInstance;
157+
Value = pi.GetValue(target, null);
159158
}
159+
//ReflectionException = null;
160160
}
161-
catch //(Exception e)
161+
catch (Exception e)
162162
{
163-
//MelonLogger.Log($"Error updating MemberInfo value | {e.GetType()}: {e.Message}\r\n{e.StackTrace}");
163+
ReflectionException = ReflectionHelpers.ExceptionToString(e);
164164
}
165165
}
166166

0 commit comments

Comments
 (0)