@@ -213,7 +213,7 @@ object existingValue
213
213
)
214
214
{
215
215
Type fieldType = field . FieldType ;
216
- bool isArray = typeof ( IEnumerable ) . IsAssignableFrom ( fieldType ) ;
216
+ bool isCollection = IsCollectionType ( fieldType , out bool _ , out bool isList ) ;
217
217
bool includeInactive = attr . HasFlags ( Flag . IncludeInactive ) ;
218
218
219
219
ISerializableRef iSerializable = null ;
@@ -223,12 +223,10 @@ object existingValue
223
223
fieldType = iSerializable . RefType ;
224
224
existingValue = iSerializable . SerializedObject ;
225
225
}
226
- IEnumerable existingValueEnumerable = existingValue as IEnumerable ;
227
226
228
227
if ( attr . HasFlags ( Flag . Editable ) )
229
228
{
230
- var enumerator = existingValueEnumerable . GetEnumerator ( ) ;
231
- bool isFilledArray = isArray && enumerator . MoveNext ( ) ;
229
+ bool isFilledArray = isCollection && ( existingValue as IEnumerable ) . CountEnumerable ( ) > 0 ;
232
230
if ( isFilledArray || existingValue is Object )
233
231
{
234
232
// If the field is editable and the value has already been set, keep it.
@@ -237,7 +235,7 @@ object existingValue
237
235
}
238
236
239
237
Type elementType = fieldType ;
240
- if ( isArray )
238
+ if ( isCollection )
241
239
{
242
240
elementType = GetElementType ( fieldType ) ;
243
241
if ( typeof ( ISerializableRef ) . IsAssignableFrom ( elementType ) )
@@ -260,47 +258,47 @@ object existingValue
260
258
switch ( attr . Loc )
261
259
{
262
260
case RefLoc . Anywhere :
263
- if ( isArray ? typeof ( ISerializableRef ) . IsAssignableFrom ( fieldType . GetElementType ( ) ) : iSerializable != null )
261
+ if ( isCollection ? typeof ( ISerializableRef ) . IsAssignableFrom ( fieldType . GetElementType ( ) ) : iSerializable != null )
264
262
{
265
- value = isArray
263
+ value = isCollection
266
264
? ( existingValue as ISerializableRef [ ] ) ? . Select ( existingRef => GetComponentIfWrongType ( existingRef . SerializedObject , elementType ) ) . ToArray ( )
267
265
: GetComponentIfWrongType ( existingValue , elementType ) ;
268
266
}
269
267
break ;
270
268
271
269
case RefLoc . Self :
272
- value = isArray
270
+ value = isCollection
273
271
? ( object ) component . GetComponents ( elementType )
274
272
: ( object ) component . GetComponent ( elementType ) ;
275
273
break ;
276
274
277
275
case RefLoc . Parent :
278
276
#if UNITY_2020_OR_NEWER
279
- value = isArray
277
+ value = isCollection
280
278
? c . GetComponentsInParent ( elementType , includeInactive )
281
279
: ( object ) c . GetComponentInParent ( elementType , includeInactive ) ;
282
280
#else
283
- value = isArray
281
+ value = isCollection
284
282
? ( object ) component . GetComponentsInParent ( elementType , includeInactive )
285
283
: ( object ) component . GetComponentInParent ( elementType , includeInactive ) ;
286
284
#endif
287
285
288
286
break ;
289
287
290
288
case RefLoc . Child :
291
- value = isArray
289
+ value = isCollection
292
290
? ( object ) component . GetComponentsInChildren ( elementType , includeInactive )
293
291
: ( object ) component . GetComponentInChildren ( elementType , includeInactive ) ;
294
292
break ;
295
293
296
294
case RefLoc . Scene :
297
295
#if UNITY_2020_OR_NEWER
298
- value = isArray
296
+ value = isCollection
299
297
? ( object ) Object . FindObjectsOfType ( elementType , includeInactive )
300
298
: ( object ) Object . FindObjectOfType ( elementType , includeInactive ) ;
301
299
#else
302
300
FindObjectsInactive includeInactiveObjects = includeInactive ? FindObjectsInactive . Include : FindObjectsInactive . Exclude ;
303
- value = isArray
301
+ value = isCollection
304
302
? ( object ) Object . FindObjectsOfType ( elementType )
305
303
: ( object ) Object . FindObjectOfType ( elementType ) ;
306
304
#endif
@@ -317,7 +315,7 @@ object existingValue
317
315
318
316
SceneRefFilter filter = attr . Filter ;
319
317
320
- if ( isArray )
318
+ if ( isCollection )
321
319
{
322
320
Type realElementType = GetElementType ( fieldType ) ;
323
321
@@ -371,13 +369,14 @@ object existingValue
371
369
372
370
if ( iSerializable == null )
373
371
{
374
- bool valueIsEqual = isArray ? Enumerable . SequenceEqual ( ( IEnumerable < object > ) value , ( IEnumerable < object > ) existingValue ) : value . Equals ( existingValue ) ;
375
- if ( existingValue != null && valueIsEqual )
372
+ bool valueIsEqual = existingValue != null &&
373
+ isCollection ? Enumerable . SequenceEqual ( ( IEnumerable < object > ) value , ( IEnumerable < object > ) existingValue ) : value . Equals ( existingValue ) ;
374
+ if ( valueIsEqual )
376
375
{
377
376
return existingValue ;
378
377
}
379
378
380
- if ( ! fieldType . IsArray && typeof ( IEnumerable ) . IsAssignableFrom ( fieldType ) )
379
+ if ( isList )
381
380
{
382
381
Type listType = typeof ( List < > ) ;
383
382
Type [ ] typeArgs = { fieldType . GenericTypeArguments [ 0 ] } ;
@@ -419,10 +418,7 @@ private static Type GetElementType(Type fieldType)
419
418
{
420
419
return fieldType . GetElementType ( ) ;
421
420
}
422
- else
423
- {
424
- return fieldType . GenericTypeArguments [ 0 ] ;
425
- }
421
+ return fieldType . GenericTypeArguments [ 0 ] ;
426
422
}
427
423
428
424
private static object GetComponentIfWrongType ( object existingValue , Type elementType )
@@ -438,28 +434,28 @@ private static object GetComponentIfWrongType(object existingValue, Type element
438
434
private static void ValidateRef ( SceneRefAttribute attr , Component c , FieldInfo field , object value )
439
435
{
440
436
Type fieldType = field . FieldType ;
441
- bool isArray = typeof ( IEnumerable ) . IsAssignableFrom ( fieldType ) ;
437
+ bool isCollection = IsCollectionType ( fieldType , out bool _ , out bool _ ) ;
442
438
443
439
if ( value is ISerializableRef ser )
444
440
{
445
441
value = ser . SerializedObject ;
446
442
}
447
443
448
- if ( IsEmptyOrNull ( value , isArray ) )
444
+ if ( IsEmptyOrNull ( value , isCollection ) )
449
445
{
450
446
if ( ! attr . HasFlags ( Flag . Optional ) )
451
447
{
452
- Type elementType = isArray ? fieldType . GetElementType ( ) : fieldType ;
448
+ Type elementType = isCollection ? fieldType . GetElementType ( ) : fieldType ;
453
449
elementType = typeof ( ISerializableRef ) . IsAssignableFrom ( elementType ) ? elementType ? . GetGenericArguments ( ) [ 0 ] : elementType ;
454
- Debug . LogError ( $ "{ c . GetType ( ) . Name } missing required { elementType ? . Name + ( isArray ? "[]" : "" ) } ref '{ field . Name } '", c . gameObject ) ;
450
+ Debug . LogError ( $ "{ c . GetType ( ) . Name } missing required { elementType ? . Name + ( isCollection ? "[]" : "" ) } ref '{ field . Name } '", c . gameObject ) ;
455
451
}
456
452
return ;
457
453
}
458
454
459
- if ( isArray )
455
+ if ( isCollection )
460
456
{
461
457
IEnumerable a = ( IEnumerable ) value ;
462
- var enumerator = a . GetEnumerator ( ) ;
458
+ IEnumerator enumerator = a . GetEnumerator ( ) ;
463
459
while ( enumerator . MoveNext ( ) )
464
460
{
465
461
object o = enumerator . Current ;
@@ -479,7 +475,7 @@ private static void ValidateRef(SceneRefAttribute attr, Component c, FieldInfo f
479
475
}
480
476
}
481
477
else
482
- {
478
+ {
483
479
ValidateRefLocation ( attr . Loc , c , field , value ) ;
484
480
}
485
481
}
@@ -514,42 +510,29 @@ private static void ValidateRefLocation(RefLoc loc, Component c, FieldInfo field
514
510
515
511
case RefLoc . Self :
516
512
if ( refObj . gameObject != c . gameObject )
517
- {
518
513
Debug . LogError ( $ "{ c . GetType ( ) . Name } requires { field . FieldType . Name } ref '{ field . Name } ' to be on Self", c . gameObject ) ;
519
- }
520
-
521
514
break ;
522
515
523
516
case RefLoc . Parent :
524
517
if ( ! c . transform . IsChildOf ( refObj . transform ) )
525
- {
526
518
Debug . LogError ( $ "{ c . GetType ( ) . Name } requires { field . FieldType . Name } ref '{ field . Name } ' to be a Parent", c . gameObject ) ;
527
- }
528
-
529
519
break ;
530
520
531
521
case RefLoc . Child :
532
522
if ( ! refObj . transform . IsChildOf ( c . transform ) )
533
- {
534
523
Debug . LogError ( $ "{ c . GetType ( ) . Name } requires { field . FieldType . Name } ref '{ field . Name } ' to be a Child", c . gameObject ) ;
535
- }
536
-
537
524
break ;
538
525
539
526
case RefLoc . Scene :
540
527
if ( c == null )
541
- {
542
528
Debug . LogError ( $ "{ c . GetType ( ) . Name } requires { field . FieldType . Name } ref '{ field . Name } ' to be in the scene", c . gameObject ) ;
543
- }
544
-
545
529
break ;
546
530
547
531
default :
548
532
throw new Exception ( $ "Unhandled Loc={ loc } ") ;
549
533
}
550
534
}
551
535
552
- // ReSharper disable once UnusedParameter.Local
553
536
private static void ValidateRefLocationAnywhere ( RefLoc loc , Component c , FieldInfo field )
554
537
{
555
538
switch ( loc )
@@ -569,14 +552,21 @@ private static void ValidateRefLocationAnywhere(RefLoc loc, Component c, FieldIn
569
552
}
570
553
}
571
554
572
- private static bool IsEmptyOrNull ( object obj , bool isArray )
555
+ private static bool IsEmptyOrNull ( object obj , bool isCollection )
573
556
{
574
557
if ( obj is ISerializableRef ser )
575
558
{
576
559
return ! ser . HasSerializedObject ;
577
560
}
578
561
579
- return obj == null || obj . Equals ( null ) || ( isArray && ( ( IEnumerable ) obj ) . CountEnumerable ( ) == 0 ) ;
562
+ return obj == null || obj . Equals ( null ) || ( isCollection && ( ( IEnumerable ) obj ) . CountEnumerable ( ) == 0 ) ;
563
+ }
564
+
565
+ private static bool IsCollectionType ( Type t , out bool isArray , out bool isList )
566
+ {
567
+ isList = t . IsGenericType && t . GetGenericTypeDefinition ( ) == typeof ( List < > ) ;
568
+ isArray = t . IsArray ;
569
+ return isList || isArray ;
580
570
}
581
571
}
582
572
}
0 commit comments