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

Commit 6ea435d

Browse files
committed
1.6.6
* Added better support for Properties with index parameters, can now support multiple parameters and non-int parameters. * Parameters are now formatted in a more expected fashion (in the `(Type arg0, Type arg1)` format). * Got rid of all the ugly yellow text. * Cleaned up some minor GUI display / layout issues. * Refactored some of CacheMethod into CacheObjectBase
1 parent 94f7493 commit 6ea435d

15 files changed

+337
-216
lines changed

img.png

74.8 KB
Loading

src/CachedObjects/CacheObjectBase.cs

Lines changed: 160 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,12 @@ public abstract class CacheObjectBase
1919
public MemberInfo MemInfo { get; set; }
2020
public Type DeclaringType { get; set; }
2121
public object DeclaringInstance { get; set; }
22-
public int PropertyIndex { get; private set; }
23-
private string m_propertyIndexInput = "0";
22+
23+
public bool HasParameters => m_arguments != null && m_arguments.Length > 0;
24+
public bool m_evaluated = false;
25+
public bool m_isEvaluating;
26+
public ParameterInfo[] m_arguments = new ParameterInfo[0];
27+
public string[] m_argumentInput = new string[0];
2428

2529
public string ReflectionException { get; set; }
2630

@@ -43,7 +47,6 @@ public bool CanWrite
4347
// ===== Abstract/Virtual Methods ===== //
4448

4549
public virtual void Init() { }
46-
4750
public abstract void DrawValue(Rect window, float width);
4851

4952
// ===== Static Methods ===== //
@@ -114,12 +117,21 @@ private static CacheObjectBase GetCacheObjectImpl(object obj, MemberInfo memberI
114117
{
115118
CacheObjectBase holder;
116119

120+
var pi = memberInfo as PropertyInfo;
121+
var mi = memberInfo as MethodInfo;
122+
123+
// if PropertyInfo, check if can process args
124+
if (pi != null && !CanProcessArgs(pi.GetIndexParameters()))
125+
{
126+
return null;
127+
}
128+
117129
// This is pretty ugly, could probably make a cleaner implementation.
118130
// However, the only cleaner ways I can think of are slower and probably not worth it.
119131

120132
// Note: the order is somewhat important.
121133

122-
if (memberInfo is MethodInfo mi)
134+
if (mi != null)
123135
{
124136
if (CacheMethod.CanEvaluate(mi))
125137
{
@@ -181,7 +193,21 @@ private static CacheObjectBase GetCacheObjectImpl(object obj, MemberInfo memberI
181193
holder.MemInfo = memberInfo;
182194
holder.DeclaringType = memberInfo.DeclaringType;
183195
holder.DeclaringInstance = declaringInstance;
196+
}
197+
198+
if (pi != null)
199+
{
200+
holder.m_arguments = pi.GetIndexParameters();
201+
}
202+
else if (mi != null)
203+
{
204+
holder.m_arguments = mi.GetParameters();
205+
}
206+
207+
holder.m_argumentInput = new string[holder.m_arguments.Length];
184208

209+
if (!holder.HasParameters)
210+
{
185211
holder.UpdateValue();
186212
}
187213

@@ -190,11 +216,57 @@ private static CacheObjectBase GetCacheObjectImpl(object obj, MemberInfo memberI
190216
return holder;
191217
}
192218

219+
public static bool CanProcessArgs(ParameterInfo[] parameters)
220+
{
221+
foreach (var param in parameters)
222+
{
223+
if (!param.ParameterType.IsPrimitive && param.ParameterType != typeof(string))
224+
{
225+
return false;
226+
}
227+
}
228+
229+
return true;
230+
}
231+
193232
// ======== Instance Methods =========
194233

234+
public object[] ParseArguments()
235+
{
236+
var parsedArgs = new List<object>();
237+
for (int i = 0; i < m_arguments.Length; i++)
238+
{
239+
var input = m_argumentInput[i];
240+
var type = m_arguments[i].ParameterType;
241+
242+
if (type == typeof(string))
243+
{
244+
parsedArgs.Add(input);
245+
}
246+
else
247+
{
248+
try
249+
{
250+
parsedArgs.Add(type.GetMethod("Parse", new Type[] { typeof(string) }).Invoke(null, new object[] { input }));
251+
}
252+
catch
253+
{
254+
//MelonLogger.Log($"Unable to parse '{input}' to type '{type.Name}'");
255+
256+
// try add a null arg i guess
257+
parsedArgs.Add(null);
258+
259+
//break;
260+
}
261+
}
262+
}
263+
264+
return parsedArgs.ToArray();
265+
}
266+
195267
public virtual void UpdateValue()
196268
{
197-
if (MemInfo == null || !string.IsNullOrEmpty(ReflectionException))
269+
if (MemInfo == null)
198270
{
199271
return;
200272
}
@@ -209,13 +281,11 @@ public virtual void UpdateValue()
209281
else if (MemInfo.MemberType == MemberTypes.Property)
210282
{
211283
var pi = MemInfo as PropertyInfo;
212-
bool isStatic = pi.GetAccessors()[0].IsStatic;
213-
var target = isStatic ? null : DeclaringInstance;
284+
var target = pi.GetAccessors()[0].IsStatic ? null : DeclaringInstance;
214285

215-
if (pi.GetIndexParameters().Length > 0)
286+
if (HasParameters)
216287
{
217-
var indexes = new object[] { PropertyIndex };
218-
Value = pi.GetValue(target, indexes);
288+
Value = pi.GetValue(target, ParseArguments());
219289
}
220290
else
221291
{
@@ -224,6 +294,8 @@ public virtual void UpdateValue()
224294
}
225295

226296
ReflectionException = null;
297+
m_evaluated = true;
298+
m_isEvaluating = false;
227299
}
228300
catch (Exception e)
229301
{
@@ -244,10 +316,9 @@ public void SetValue()
244316
{
245317
var pi = MemInfo as PropertyInfo;
246318

247-
if (pi.GetIndexParameters().Length > 0)
319+
if (HasParameters)
248320
{
249-
var indexes = new object[] { PropertyIndex };
250-
pi.SetValue(pi.GetAccessors()[0].IsStatic ? null : DeclaringInstance, Value, indexes);
321+
pi.SetValue(pi.GetAccessors()[0].IsStatic ? null : DeclaringInstance, Value, ParseArguments());
251322
}
252323
else
253324
{
@@ -264,6 +335,7 @@ public void SetValue()
264335
// ========= Instance Gui Draw ==========
265336

266337
public const float MAX_LABEL_WIDTH = 400f;
338+
public const string EVALUATE_LABEL = "<color=lime>Evaluate</color>";
267339

268340
public static void ClampLabelWidth(Rect window, ref float labelWidth)
269341
{
@@ -282,53 +354,96 @@ public void Draw(Rect window, float labelWidth = 215f)
282354

283355
if (MemInfo != null)
284356
{
285-
var name = RichTextName;
286-
if (MemInfo is PropertyInfo pi && pi.GetIndexParameters().Length > 0)
287-
{
288-
name += $"[{PropertyIndex}]";
289-
}
290-
291-
GUILayout.Label(name, new GUILayoutOption[] { GUILayout.Width(labelWidth) });
357+
GUILayout.Label(RichTextName, new GUILayoutOption[] { GUILayout.Width(labelWidth) });
292358
}
293359
else
294360
{
295361
GUILayout.Space(labelWidth);
296362
}
297363

298-
if (!string.IsNullOrEmpty(ReflectionException))
299-
{
300-
GUILayout.Label("<color=red>Reflection failed!</color> (" + ReflectionException + ")", null);
301-
}
302-
else if (Value == null && MemInfo?.MemberType != MemberTypes.Method)
303-
{
304-
GUILayout.Label("<i>null (" + ValueTypeName + ")</i>", null);
305-
}
306-
else
364+
var cm = this as CacheMethod;
365+
366+
if (HasParameters)
307367
{
308-
if (MemInfo is PropertyInfo pi && pi.GetIndexParameters().Length > 0)
368+
GUILayout.BeginVertical(null);
369+
370+
if (m_isEvaluating)
309371
{
310-
GUILayout.Label("index:", new GUILayoutOption[] { GUILayout.Width(50) });
372+
for (int i = 0; i < m_arguments.Length; i++)
373+
{
374+
var name = m_arguments[i].Name;
375+
var input = m_argumentInput[i];
376+
var type = m_arguments[i].ParameterType.Name;
377+
378+
GUILayout.BeginHorizontal(null);
379+
GUILayout.Label(i.ToString(), new GUILayoutOption[] { GUILayout.Width(30) });
380+
m_argumentInput[i] = GUILayout.TextField(input, new GUILayoutOption[] { GUILayout.Width(150) });
381+
GUILayout.Label("<color=#2df7b2>" + type + "</color> <color=cyan>" + name + "</color>", null);
382+
GUILayout.EndHorizontal();
383+
}
311384

312-
m_propertyIndexInput = GUILayout.TextField(m_propertyIndexInput, new GUILayoutOption[] { GUILayout.Width(100) });
313-
if (GUILayout.Button("Set", new GUILayoutOption[] { GUILayout.Width(60) }))
385+
GUILayout.BeginHorizontal(null);
386+
if (cm != null)
314387
{
315-
if (int.TryParse(m_propertyIndexInput, out int i))
388+
if (GUILayout.Button(EVALUATE_LABEL, new GUILayoutOption[] { GUILayout.Width(70) }))
316389
{
317-
PropertyIndex = i;
318-
UpdateValue();
390+
cm.Evaluate();
319391
}
320-
else
392+
}
393+
else
394+
{
395+
if (GUILayout.Button(EVALUATE_LABEL, new GUILayoutOption[] { GUILayout.Width(70) }))
321396
{
322-
MelonLogger.Log($"Could not parse '{m_propertyIndexInput}' to an int!");
397+
UpdateValue();
323398
}
324399
}
325-
326-
// new line and space
400+
401+
if (GUILayout.Button("Cancel", new GUILayoutOption[] { GUILayout.Width(70) }))
402+
{
403+
m_isEvaluating = false;
404+
}
327405
GUILayout.EndHorizontal();
328-
GUILayout.BeginHorizontal(null);
329-
GUILayout.Space(labelWidth);
406+
}
407+
else
408+
{
409+
if (GUILayout.Button($"Evaluate ({m_arguments.Length} params)", new GUILayoutOption[] { GUILayout.Width(150) }))
410+
{
411+
m_isEvaluating = true;
412+
}
413+
}
414+
415+
GUILayout.EndVertical();
416+
417+
// new line and space
418+
GUILayout.EndHorizontal();
419+
GUILayout.BeginHorizontal(null);
420+
GUILayout.Space(labelWidth);
421+
}
422+
else if (cm != null)
423+
{
424+
//GUILayout.BeginHorizontal(null);
425+
426+
if (GUILayout.Button(EVALUATE_LABEL, new GUILayoutOption[] { GUILayout.Width(70) }))
427+
{
428+
cm.Evaluate();
330429
}
331430

431+
// new line and space
432+
GUILayout.EndHorizontal();
433+
GUILayout.BeginHorizontal(null);
434+
GUILayout.Space(labelWidth);
435+
}
436+
437+
if (!string.IsNullOrEmpty(ReflectionException))
438+
{
439+
GUILayout.Label("<color=red>Reflection failed!</color> (" + ReflectionException + ")", null);
440+
}
441+
else if (Value == null && MemInfo?.MemberType != MemberTypes.Method)
442+
{
443+
GUILayout.Label("<i>null (" + ValueTypeName + ")</i>", null);
444+
}
445+
else
446+
{
332447
DrawValue(window, window.width - labelWidth - 90);
333448
}
334449
}
@@ -348,15 +463,15 @@ private string GetRichTextName()
348463

349464
m_richTextName = $"<color=#2df7b2>{MemInfo.DeclaringType.Name}</color>.<color={memberColor}>{MemInfo.Name}</color>";
350465

351-
if (MemInfo is MethodInfo mi)
466+
if (m_arguments.Length > 0)
352467
{
353468
m_richTextName += "(";
354469
var _params = "";
355-
foreach (var param in mi.GetParameters())
470+
foreach (var param in m_arguments)
356471
{
357472
if (_params != "") _params += ", ";
358473

359-
_params += $"<color=#a6e9e9>{param.Name}</color>";
474+
_params += $"<color=#2df7b2>{param.ParameterType.Name}</color> <color=#a6e9e9>{param.Name}</color>";
360475
}
361476
m_richTextName += _params;
362477
m_richTextName += ")";

src/CachedObjects/Object/CacheDictionary.cs

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public class CacheDictionary : CacheObjectBase, IExpandHeight
1515
{
1616
public bool IsExpanded { get; set; }
1717
public float WhiteSpace { get; set; } = 215f;
18-
public float ButtonWidthOffset { get; set; } = 290f;
18+
public float ButtonWidthOffset { get; set; } = 350f;
1919

2020
public PageHelper Pages = new PageHelper();
2121

@@ -152,15 +152,13 @@ public override void UpdateValue()
152152
foreach (var key in IDict.Keys)
153153
{
154154
var cache = GetCacheObject(key, TypeOfKeys);
155-
cache.UpdateValue();
156155
keys.Add(cache);
157156
}
158157

159158
var values = new List<CacheObjectBase>();
160159
foreach (var val in IDict.Values)
161160
{
162161
var cache = GetCacheObject(val, TypeOfValues);
163-
cache.UpdateValue();
164162
values.Add(cache);
165163
}
166164

@@ -170,6 +168,11 @@ public override void UpdateValue()
170168

171169
private bool EnsureDictionaryIsSupported()
172170
{
171+
if (typeof(IDictionary).IsAssignableFrom(ValueType))
172+
{
173+
return true;
174+
}
175+
173176
try
174177
{
175178
return Check(TypeOfKeys) && Check(TypeOfValues);
@@ -200,6 +203,12 @@ public override void DrawValue(Rect window, float width)
200203
return;
201204
}
202205

206+
float whitespace = WhiteSpace;
207+
if (whitespace > 0)
208+
{
209+
ClampLabelWidth(window, ref whitespace);
210+
}
211+
203212
int count = m_cachedKeys.Length;
204213

205214
if (!IsExpanded)
@@ -217,9 +226,11 @@ public override void DrawValue(Rect window, float width)
217226
}
218227
}
219228

229+
var negativeWhitespace = window.width - (whitespace + 100f);
230+
220231
GUI.skin.button.alignment = TextAnchor.MiddleLeft;
221-
string btnLabel = $"<color=yellow>[{count}] Dictionary<{TypeOfKeys.FullName}, {TypeOfValues.FullName}></color>";
222-
if (GUILayout.Button(btnLabel, new GUILayoutOption[] { GUILayout.MaxWidth(window.width - ButtonWidthOffset) }))
232+
string btnLabel = $"<color=#2df7b2>[{count}] Dictionary<{TypeOfKeys.FullName}, {TypeOfValues.FullName}></color>";
233+
if (GUILayout.Button(btnLabel, new GUILayoutOption[] { GUILayout.Width(negativeWhitespace) }))
223234
{
224235
WindowManager.InspectObject(Value, out bool _);
225236
}
@@ -229,12 +240,6 @@ public override void DrawValue(Rect window, float width)
229240

230241
if (IsExpanded)
231242
{
232-
float whitespace = WhiteSpace;
233-
if (whitespace > 0)
234-
{
235-
ClampLabelWidth(window, ref whitespace);
236-
}
237-
238243
Pages.ItemCount = count;
239244

240245
if (count > Pages.ItemsPerPage)

0 commit comments

Comments
 (0)