@@ -19,8 +19,12 @@ public abstract class CacheObjectBase
19
19
public MemberInfo MemInfo { get ; set ; }
20
20
public Type DeclaringType { get ; set ; }
21
21
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 ] ;
24
28
25
29
public string ReflectionException { get ; set ; }
26
30
@@ -43,7 +47,6 @@ public bool CanWrite
43
47
// ===== Abstract/Virtual Methods ===== //
44
48
45
49
public virtual void Init ( ) { }
46
-
47
50
public abstract void DrawValue ( Rect window , float width ) ;
48
51
49
52
// ===== Static Methods ===== //
@@ -114,12 +117,21 @@ private static CacheObjectBase GetCacheObjectImpl(object obj, MemberInfo memberI
114
117
{
115
118
CacheObjectBase holder ;
116
119
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
+
117
129
// This is pretty ugly, could probably make a cleaner implementation.
118
130
// However, the only cleaner ways I can think of are slower and probably not worth it.
119
131
120
132
// Note: the order is somewhat important.
121
133
122
- if ( memberInfo is MethodInfo mi )
134
+ if ( mi != null )
123
135
{
124
136
if ( CacheMethod . CanEvaluate ( mi ) )
125
137
{
@@ -181,7 +193,21 @@ private static CacheObjectBase GetCacheObjectImpl(object obj, MemberInfo memberI
181
193
holder . MemInfo = memberInfo ;
182
194
holder . DeclaringType = memberInfo . DeclaringType ;
183
195
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 ] ;
184
208
209
+ if ( ! holder . HasParameters )
210
+ {
185
211
holder . UpdateValue ( ) ;
186
212
}
187
213
@@ -190,11 +216,57 @@ private static CacheObjectBase GetCacheObjectImpl(object obj, MemberInfo memberI
190
216
return holder ;
191
217
}
192
218
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
+
193
232
// ======== Instance Methods =========
194
233
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
+
195
267
public virtual void UpdateValue ( )
196
268
{
197
- if ( MemInfo == null || ! string . IsNullOrEmpty ( ReflectionException ) )
269
+ if ( MemInfo == null )
198
270
{
199
271
return ;
200
272
}
@@ -209,13 +281,11 @@ public virtual void UpdateValue()
209
281
else if ( MemInfo . MemberType == MemberTypes . Property )
210
282
{
211
283
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 ;
214
285
215
- if ( pi . GetIndexParameters ( ) . Length > 0 )
286
+ if ( HasParameters )
216
287
{
217
- var indexes = new object [ ] { PropertyIndex } ;
218
- Value = pi . GetValue ( target , indexes ) ;
288
+ Value = pi . GetValue ( target , ParseArguments ( ) ) ;
219
289
}
220
290
else
221
291
{
@@ -224,6 +294,8 @@ public virtual void UpdateValue()
224
294
}
225
295
226
296
ReflectionException = null ;
297
+ m_evaluated = true ;
298
+ m_isEvaluating = false ;
227
299
}
228
300
catch ( Exception e )
229
301
{
@@ -244,10 +316,9 @@ public void SetValue()
244
316
{
245
317
var pi = MemInfo as PropertyInfo ;
246
318
247
- if ( pi . GetIndexParameters ( ) . Length > 0 )
319
+ if ( HasParameters )
248
320
{
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 ( ) ) ;
251
322
}
252
323
else
253
324
{
@@ -264,6 +335,7 @@ public void SetValue()
264
335
// ========= Instance Gui Draw ==========
265
336
266
337
public const float MAX_LABEL_WIDTH = 400f ;
338
+ public const string EVALUATE_LABEL = "<color=lime>Evaluate</color>" ;
267
339
268
340
public static void ClampLabelWidth ( Rect window , ref float labelWidth )
269
341
{
@@ -282,53 +354,96 @@ public void Draw(Rect window, float labelWidth = 215f)
282
354
283
355
if ( MemInfo != null )
284
356
{
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 ) } ) ;
292
358
}
293
359
else
294
360
{
295
361
GUILayout . Space ( labelWidth ) ;
296
362
}
297
363
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 )
307
367
{
308
- if ( MemInfo is PropertyInfo pi && pi . GetIndexParameters ( ) . Length > 0 )
368
+ GUILayout . BeginVertical ( null ) ;
369
+
370
+ if ( m_isEvaluating )
309
371
{
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
+ }
311
384
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 )
314
387
{
315
- if ( int . TryParse ( m_propertyIndexInput , out int i ) )
388
+ if ( GUILayout . Button ( EVALUATE_LABEL , new GUILayoutOption [ ] { GUILayout . Width ( 70 ) } ) )
316
389
{
317
- PropertyIndex = i ;
318
- UpdateValue ( ) ;
390
+ cm . Evaluate ( ) ;
319
391
}
320
- else
392
+ }
393
+ else
394
+ {
395
+ if ( GUILayout . Button ( EVALUATE_LABEL , new GUILayoutOption [ ] { GUILayout . Width ( 70 ) } ) )
321
396
{
322
- MelonLogger . Log ( $ "Could not parse ' { m_propertyIndexInput } ' to an int!" ) ;
397
+ UpdateValue ( ) ;
323
398
}
324
399
}
325
-
326
- // new line and space
400
+
401
+ if ( GUILayout . Button ( "Cancel" , new GUILayoutOption [ ] { GUILayout . Width ( 70 ) } ) )
402
+ {
403
+ m_isEvaluating = false ;
404
+ }
327
405
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 ( ) ;
330
429
}
331
430
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
+ {
332
447
DrawValue ( window , window . width - labelWidth - 90 ) ;
333
448
}
334
449
}
@@ -348,15 +463,15 @@ private string GetRichTextName()
348
463
349
464
m_richTextName = $ "<color=#2df7b2>{ MemInfo . DeclaringType . Name } </color>.<color={ memberColor } >{ MemInfo . Name } </color>";
350
465
351
- if ( MemInfo is MethodInfo mi )
466
+ if ( m_arguments . Length > 0 )
352
467
{
353
468
m_richTextName += "(" ;
354
469
var _params = "" ;
355
- foreach ( var param in mi . GetParameters ( ) )
470
+ foreach ( var param in m_arguments )
356
471
{
357
472
if ( _params != "" ) _params += ", " ;
358
473
359
- _params += $ "<color=#a6e9e9>{ param . Name } </color>";
474
+ _params += $ "<color=#2df7b2> { param . ParameterType . Name } </color> <color=# a6e9e9>{ param . Name } </color>";
360
475
}
361
476
m_richTextName += _params ;
362
477
m_richTextName += ")" ;
0 commit comments