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

Commit b264151

Browse files
committed
1.4.0
- Wrote the CacheObject class to replace MemberInfoHolder, resulting code is better perfomance and much easier to read. - Added pages to Object Reflection window, now limited to 20 members per page to improve performance further.
1 parent 3d2bc7c commit b264151

18 files changed

+904
-697
lines changed

src/CachedObjects/CacheEnum.cs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
using MelonLoader;
7+
using UnityEngine;
8+
9+
namespace Explorer
10+
{
11+
public class CacheEnum : CacheObject
12+
{
13+
private readonly Type m_enumType;
14+
private readonly string[] m_names;
15+
16+
public CacheEnum(object obj)
17+
{
18+
m_enumType = obj.GetType();
19+
m_names = Enum.GetNames(obj.GetType());
20+
}
21+
22+
public override void DrawValue(Rect window, float width)
23+
{
24+
if (MemberInfo != null)
25+
{
26+
if (GUILayout.Button("<", new GUILayoutOption[] { GUILayout.Width(25) }))
27+
{
28+
SetEnum(ref Value, -1);
29+
SetValue();
30+
}
31+
if (GUILayout.Button(">", new GUILayoutOption[] { GUILayout.Width(25) }))
32+
{
33+
SetEnum(ref Value, 1);
34+
SetValue();
35+
}
36+
}
37+
38+
GUILayout.Label(Value.ToString(), null);
39+
}
40+
41+
public override void SetValue()
42+
{
43+
if (MemberInfo == null)
44+
{
45+
MelonLogger.Log("Trying to SetValue but the MemberInfo is null!");
46+
return;
47+
}
48+
49+
if (Enum.Parse(m_enumType, Value.ToString()) is object enumValue && enumValue != null)
50+
{
51+
Value = enumValue;
52+
}
53+
54+
SetValue(Value, MemberInfo, DeclaringInstance);
55+
}
56+
57+
public void SetEnum(ref object value, int change)
58+
{
59+
var names = m_names.ToList();
60+
61+
int newindex = names.IndexOf(value.ToString()) + change;
62+
63+
if ((change < 0 && newindex >= 0) || (change > 0 && newindex < names.Count))
64+
{
65+
value = Enum.Parse(m_enumType, names[newindex]);
66+
}
67+
}
68+
}
69+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
using MelonLoader;
7+
using UnityEngine;
8+
9+
namespace Explorer
10+
{
11+
public class CacheGameObject : CacheObject
12+
{
13+
private GameObject m_gameObject;
14+
15+
public CacheGameObject(object obj)
16+
{
17+
if (obj != null)
18+
m_gameObject = GetGameObject(obj);
19+
}
20+
21+
private GameObject GetGameObject(object obj)
22+
{
23+
if (obj is Il2CppSystem.Object ilObj)
24+
{
25+
var ilType = ilObj.GetIl2CppType();
26+
27+
if (ilType == ReflectionHelpers.GameObjectType || ilType == ReflectionHelpers.TransformType)
28+
{
29+
return ilObj.TryCast<GameObject>() ?? ilObj.TryCast<Transform>()?.gameObject;
30+
}
31+
}
32+
33+
return null;
34+
}
35+
36+
public override void DrawValue(Rect window, float width)
37+
{
38+
UIHelpers.GameobjButton(m_gameObject, null, false, width);
39+
}
40+
41+
public override void SetValue()
42+
{
43+
throw new NotImplementedException("TODO");
44+
}
45+
46+
public override void UpdateValue(object obj)
47+
{
48+
base.UpdateValue(obj);
49+
50+
m_gameObject = GetGameObject(Value);
51+
}
52+
}
53+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
using UnityEngine;
7+
8+
namespace Explorer
9+
{
10+
public class CacheIl2CppObject : CacheObject
11+
{
12+
public override void DrawValue(Rect window, float width)
13+
{
14+
var label = ValueType ?? Value.ToString();
15+
if (!label.Contains(ValueType))
16+
{
17+
label += $" ({ValueType})";
18+
}
19+
if (Value is UnityEngine.Object unityObj)
20+
{
21+
label = unityObj.name + " | " + label;
22+
}
23+
24+
GUI.skin.button.alignment = TextAnchor.MiddleLeft;
25+
if (GUILayout.Button("<color=yellow>" + label + "</color>", new GUILayoutOption[] { GUILayout.MaxWidth(width) }))
26+
{
27+
WindowManager.InspectObject(Value, out bool _);
28+
}
29+
GUI.skin.button.alignment = TextAnchor.MiddleCenter;
30+
}
31+
32+
public override void SetValue()
33+
{
34+
throw new NotImplementedException("TODO");
35+
}
36+
}
37+
}

src/CachedObjects/CacheList.cs

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
using System;
2+
using System.Collections;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Reflection;
6+
using System.Text;
7+
using System.Threading.Tasks;
8+
using UnityEngine;
9+
10+
namespace Explorer
11+
{
12+
public partial class CacheList : CacheObject
13+
{
14+
public bool IsExpanded { get; set; }
15+
public int ArrayOffset { get; set; }
16+
public Type EntryType { get; set; }
17+
18+
private IEnumerable m_enumerable;
19+
private CacheObject[] m_cachedEntries;
20+
21+
public CacheList(object obj)
22+
{
23+
GetEnumerable(obj);
24+
EntryType = m_enumerable.GetType().GetGenericArguments()[0];
25+
}
26+
27+
private void GetEnumerable(object obj)
28+
{
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+
}
40+
}
41+
42+
public override void DrawValue(Rect window, float width)
43+
{
44+
int count = m_cachedEntries.Length;
45+
46+
if (!IsExpanded)
47+
{
48+
if (GUILayout.Button("v", new GUILayoutOption[] { GUILayout.Width(25) }))
49+
{
50+
IsExpanded = true;
51+
}
52+
}
53+
else
54+
{
55+
if (GUILayout.Button("^", new GUILayoutOption[] { GUILayout.Width(25) }))
56+
{
57+
IsExpanded = false;
58+
}
59+
}
60+
61+
GUI.skin.button.alignment = TextAnchor.MiddleLeft;
62+
string btnLabel = "<color=yellow>[" + count + "] " + EntryType + "</color>";
63+
if (GUILayout.Button(btnLabel, new GUILayoutOption[] { GUILayout.MaxWidth(window.width - 260) }))
64+
{
65+
WindowManager.InspectObject(Value, out bool _);
66+
}
67+
GUI.skin.button.alignment = TextAnchor.MiddleCenter;
68+
69+
if (IsExpanded)
70+
{
71+
if (count > CppExplorer.ArrayLimit)
72+
{
73+
GUILayout.EndHorizontal();
74+
GUILayout.BeginHorizontal(null);
75+
GUILayout.Space(190);
76+
int maxOffset = (int)Mathf.Ceil(count / CppExplorer.ArrayLimit);
77+
GUILayout.Label($"Page {ArrayOffset + 1}/{maxOffset + 1}", new GUILayoutOption[] { GUILayout.Width(80) });
78+
// prev/next page buttons
79+
if (GUILayout.Button("< Prev", null))
80+
{
81+
if (ArrayOffset > 0) ArrayOffset--;
82+
}
83+
if (GUILayout.Button("Next >", null))
84+
{
85+
if (ArrayOffset < maxOffset) ArrayOffset++;
86+
}
87+
}
88+
89+
int offset = ArrayOffset * CppExplorer.ArrayLimit;
90+
91+
if (offset >= count) offset = 0;
92+
93+
for (int i = offset; i < offset + CppExplorer.ArrayLimit && i < count; i++)
94+
{
95+
var entry = m_cachedEntries[i];
96+
97+
//collapsing the BeginHorizontal called from ReflectionWindow.WindowFunction or previous array entry
98+
GUILayout.EndHorizontal();
99+
GUILayout.BeginHorizontal(null);
100+
GUILayout.Space(190);
101+
102+
if (entry == null)
103+
{
104+
GUILayout.Label("<i><color=grey>null</color></i>", null);
105+
}
106+
else
107+
{
108+
GUILayout.Label(i.ToString(), new GUILayoutOption[] { GUILayout.Width(30) });
109+
110+
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+
//}
127+
}
128+
}
129+
}
130+
}
131+
132+
public override void SetValue()
133+
{
134+
throw new NotImplementedException("TODO");
135+
}
136+
137+
public override void UpdateValue(object obj)
138+
{
139+
GetEnumerable(Value);
140+
141+
var list = new List<CacheObject>();
142+
143+
var enumerator = m_enumerable.GetEnumerator();
144+
145+
while (enumerator.MoveNext())
146+
{
147+
list.Add(GetCacheObject(enumerator.Current));
148+
}
149+
150+
m_cachedEntries = list.ToArray();
151+
}
152+
}
153+
}

0 commit comments

Comments
 (0)