com.wallstop-studios.unity-helpers 2.1.0 → 2.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +1 -0
- package/Docs/ILIST_SORTING_PERFORMANCE.md +92 -0
- package/{package-lock.json.meta → Docs/ILIST_SORTING_PERFORMANCE.md.meta} +1 -1
- package/Docs/INDEX.md +11 -1
- package/Docs/Images/random_generators.svg +7 -7
- package/Docs/RANDOM_PERFORMANCE.md +17 -14
- package/Docs/REFLECTION_HELPERS.md +84 -1
- package/Docs/REFLECTION_PERFORMANCE.md +169 -0
- package/Docs/REFLECTION_PERFORMANCE.md.meta +7 -0
- package/Docs/RELATIONAL_COMPONENTS.md +6 -0
- package/Docs/RELATIONAL_COMPONENT_PERFORMANCE.md +63 -0
- package/Docs/RELATIONAL_COMPONENT_PERFORMANCE.md.meta +7 -0
- package/Docs/SPATIAL_TREE_2D_PERFORMANCE.md +64 -64
- package/Docs/SPATIAL_TREE_3D_PERFORMANCE.md +64 -64
- package/Editor/Core/Helper/AnimationEventHelpers.cs +1 -1
- package/Editor/Sprites/AnimationCopier.cs +1 -1
- package/Editor/Sprites/AnimationViewerWindow.cs +4 -4
- package/Editor/Sprites/SpriteSettingsApplierAPI.cs +2 -1
- package/Editor/Sprites/TextureResizerWizard.cs +4 -3
- package/Editor/Utils/ScriptableObjectSingletonCreator.cs +3 -3
- package/README.md +33 -18
- package/Runtime/Core/Attributes/BaseRelationalComponentAttribute.cs +147 -20
- package/Runtime/Core/Attributes/ChildComponentAttribute.cs +630 -117
- package/Runtime/Core/Attributes/NotNullAttribute.cs +5 -2
- package/Runtime/Core/Attributes/ParentComponentAttribute.cs +477 -103
- package/Runtime/Core/Attributes/RelationalComponentAssigner.cs +26 -3
- package/Runtime/Core/Attributes/RelationalComponentExtensions.cs +19 -3
- package/Runtime/Core/Attributes/SiblingComponentAttribute.cs +265 -92
- package/Runtime/Core/CodeGen.meta +8 -0
- package/Runtime/Core/DataStructure/ImmutableBitSet.cs +5 -20
- package/Runtime/Core/Extension/IListExtensions.cs +720 -12
- package/Runtime/Core/Helper/Logging/UnityLogTagFormatter.cs +11 -7
- package/Runtime/Core/Helper/Objects.cs +1 -1
- package/Runtime/Core/Helper/ReflectionHelpers.Factory.cs +5142 -0
- package/Runtime/Core/Helper/ReflectionHelpers.Factory.cs.meta +11 -0
- package/Runtime/Core/Helper/ReflectionHelpers.cs +1812 -1518
- package/Runtime/Core/Helper/UnityMainThreadDispatcher.cs +2 -3
- package/Runtime/Core/Math/Line2D.cs +2 -4
- package/Runtime/Core/Math/Line3D.cs +2 -4
- package/Runtime/Core/Random/AbstractRandom.cs +52 -5
- package/Runtime/Core/Random/DotNetRandom.cs +3 -3
- package/Runtime/Core/Random/FlurryBurstRandom.cs +279 -0
- package/Runtime/Core/Random/FlurryBurstRandom.cs.meta +3 -0
- package/Runtime/Core/Random/IllusionFlow.cs +3 -3
- package/Runtime/Core/Random/LinearCongruentialGenerator.cs +3 -3
- package/Runtime/Core/Random/PcgRandom.cs +6 -6
- package/Runtime/Core/Random/PhotonSpinRandom.cs +387 -0
- package/Runtime/Core/Random/PhotonSpinRandom.cs.meta +3 -0
- package/Runtime/Core/Random/RomuDuo.cs +3 -3
- package/Runtime/Core/Random/SplitMix64.cs +3 -3
- package/Runtime/Core/Random/SquirrelRandom.cs +6 -4
- package/Runtime/Core/Random/StormDropRandom.cs +271 -0
- package/Runtime/Core/Random/StormDropRandom.cs.meta +3 -0
- package/Runtime/Core/Random/UnityRandom.cs +3 -3
- package/Runtime/Core/Random/WyRandom.cs +6 -4
- package/Runtime/Core/Random/XorShiftRandom.cs +3 -3
- package/Runtime/Core/Random/XoroShiroRandom.cs +3 -3
- package/Runtime/Tags/AttributeMetadataCache.cs +316 -9
- package/Runtime/Tags/CosmeticEffectData.cs +1 -1
- package/Runtime/Visuals/UIToolkit/MultiFileSelectorElement.cs +3 -3
- package/Tests/Editor/Helper/HelpersTests.cs +2 -2
- package/Tests/Editor/Helper/ReflectionHelpersTypedEditorTests.cs +87 -0
- package/Tests/Editor/Helper/ReflectionHelpersTypedEditorTests.cs.meta +11 -0
- package/Tests/Editor/Helper/SpriteHelpersTests.cs +1 -1
- package/Tests/Editor/PrefabCheckerReportTests.cs +3 -3
- package/Tests/Editor/Sprites/AnimationCopierFilterTests.cs +18 -12
- package/Tests/Editor/Sprites/AnimationCopierWindowTests.cs +8 -7
- package/Tests/Editor/Sprites/AnimationViewerWindowTests.cs +2 -1
- package/Tests/Editor/Sprites/ScriptableSpriteAtlasEditorTests.cs +6 -5
- package/Tests/Editor/Sprites/SpriteCropperAdditionalTests.cs +2 -1
- package/Tests/Editor/Sprites/SpriteCropperTests.cs +7 -6
- package/Tests/Editor/Sprites/SpritePivotAdjusterAdditionalTests.cs +2 -1
- package/Tests/Editor/Sprites/SpritePivotAdjusterTests.cs +4 -3
- package/Tests/Editor/Sprites/TextureResizerWizardTests.cs +10 -9
- package/Tests/Editor/Sprites/TextureSettingsApplierAPITests.cs +2 -1
- package/Tests/Editor/Tags/AttributeMetadataCacheTests.cs +192 -0
- package/Tests/Editor/Tags/AttributeMetadataCacheTests.cs.meta +11 -0
- package/Tests/Editor/Tags.meta +8 -0
- package/Tests/Runtime/Extensions/IListExtensionTests.cs +187 -1
- package/Tests/Runtime/Helper/ObjectsTests.cs +4 -4
- package/Tests/Runtime/Helper/ReflectionHelperCapabilityMatrixTests.cs +2923 -0
- package/Tests/Runtime/Helper/ReflectionHelperCapabilityMatrixTests.cs.meta +11 -0
- package/Tests/Runtime/Helper/ReflectionHelperTests.cs +660 -0
- package/Tests/Runtime/Integrations/Reflex/RelationalComponentsReflexTests.cs +2 -2
- package/Tests/Runtime/Performance/IListSortingPerformanceTests.cs +346 -0
- package/Tests/Runtime/Performance/IListSortingPerformanceTests.cs.meta +11 -0
- package/Tests/Runtime/Performance/RandomPerformanceTests.cs +3 -0
- package/Tests/Runtime/Performance/ReflectionPerformanceTests.cs +1238 -0
- package/Tests/Runtime/Performance/ReflectionPerformanceTests.cs.meta +11 -0
- package/Tests/Runtime/Performance/RelationalComponentBenchmarkTests.cs +832 -0
- package/Tests/Runtime/Performance/RelationalComponentBenchmarkTests.cs.meta +11 -0
- package/Tests/Runtime/Random/FlurryBurstRandomTests.cs +12 -0
- package/Tests/Runtime/Random/FlurryBurstRandomTests.cs.meta +3 -0
- package/Tests/Runtime/Random/PhotonSpinRandomTests.cs +12 -0
- package/Tests/Runtime/Random/PhotonSpinRandomTests.cs.meta +3 -0
- package/Tests/Runtime/Random/RandomProtoSerializationTests.cs +14 -0
- package/Tests/Runtime/Random/RandomTestBase.cs +39 -4
- package/Tests/Runtime/Random/StormDropRandomTests.cs +12 -0
- package/Tests/Runtime/Random/StormDropRandomTests.cs.meta +3 -0
- package/Tests/Runtime/Serialization/ProtoInterfaceResolutionEdgeTests.cs +2 -2
- package/Tests/Runtime/Serialization/ProtoRootRegistrationTests.cs +1 -1
- package/Tests/Runtime/Serialization/ProtoSerializeBehaviorTests.cs +1 -1
- package/Tests/Runtime/Tags/PeriodicEffectDefinitionSerializationTests.cs +2 -2
- package/package.json +1 -1
- package/Tests/Runtime/Performance/RelationComponentPerformanceTests.cs +0 -60
- package/Tests/Runtime/Performance/RelationComponentPerformanceTests.cs.meta +0 -3
|
@@ -5,6 +5,7 @@ namespace WallstopStudios.UnityHelpers.Tags
|
|
|
5
5
|
using Core.Attributes;
|
|
6
6
|
using UnityEngine;
|
|
7
7
|
using Utils;
|
|
8
|
+
using WallstopStudios.UnityHelpers.Core.Helper;
|
|
8
9
|
|
|
9
10
|
/// <summary>
|
|
10
11
|
/// Serialized cache of attribute metadata to avoid runtime reflection.
|
|
@@ -150,7 +151,8 @@ namespace WallstopStudios.UnityHelpers.Tags
|
|
|
150
151
|
|
|
151
152
|
public bool Equals(ElementTypeKey other)
|
|
152
153
|
{
|
|
153
|
-
return componentType == other.componentType
|
|
154
|
+
return componentType == other.componentType
|
|
155
|
+
&& string.Equals(fieldName, other.fieldName, StringComparison.Ordinal);
|
|
154
156
|
}
|
|
155
157
|
|
|
156
158
|
public override bool Equals(object obj)
|
|
@@ -160,11 +162,7 @@ namespace WallstopStudios.UnityHelpers.Tags
|
|
|
160
162
|
|
|
161
163
|
public override int GetHashCode()
|
|
162
164
|
{
|
|
163
|
-
|
|
164
|
-
{
|
|
165
|
-
return ((componentType?.GetHashCode() ?? 0) * 397)
|
|
166
|
-
^ (fieldName?.GetHashCode() ?? 0);
|
|
167
|
-
}
|
|
165
|
+
return Objects.HashCode(componentType, fieldName);
|
|
168
166
|
}
|
|
169
167
|
}
|
|
170
168
|
|
|
@@ -484,9 +482,15 @@ namespace WallstopStudios.UnityHelpers.Tags
|
|
|
484
482
|
RelationalTypeMetadata[] relationalTypeMetadata
|
|
485
483
|
)
|
|
486
484
|
{
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
485
|
+
string[] normalizedAttributeNames = SortAttributeNames(allAttributeNames);
|
|
486
|
+
TypeFieldMetadata[] normalizedTypeMetadata = SortTypeMetadata(typeMetadata);
|
|
487
|
+
RelationalTypeMetadata[] normalizedRelationalMetadata = SortRelationalTypeMetadata(
|
|
488
|
+
relationalTypeMetadata
|
|
489
|
+
);
|
|
490
|
+
|
|
491
|
+
_allAttributeNames = normalizedAttributeNames;
|
|
492
|
+
_typeMetadata = normalizedTypeMetadata;
|
|
493
|
+
_relationalTypeMetadata = normalizedRelationalMetadata;
|
|
490
494
|
_computedAllAttributeNames = null;
|
|
491
495
|
_computedAllAttributeNamesIncludesTests = false;
|
|
492
496
|
_typeFieldsLookup = null;
|
|
@@ -495,6 +499,309 @@ namespace WallstopStudios.UnityHelpers.Tags
|
|
|
495
499
|
_elementTypeLookup = null;
|
|
496
500
|
UnityEditor.EditorUtility.SetDirty(this);
|
|
497
501
|
}
|
|
502
|
+
|
|
503
|
+
private static string[] SortAttributeNames(string[] attributeNames)
|
|
504
|
+
{
|
|
505
|
+
if (attributeNames == null || attributeNames.Length == 0)
|
|
506
|
+
{
|
|
507
|
+
return Array.Empty<string>();
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
string[] result = new string[attributeNames.Length];
|
|
511
|
+
Array.Copy(attributeNames, result, attributeNames.Length);
|
|
512
|
+
Array.Sort(result, StringComparer.Ordinal);
|
|
513
|
+
return result;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
private static TypeFieldMetadata[] SortTypeMetadata(TypeFieldMetadata[] typeMetadata)
|
|
517
|
+
{
|
|
518
|
+
if (typeMetadata == null || typeMetadata.Length == 0)
|
|
519
|
+
{
|
|
520
|
+
return Array.Empty<TypeFieldMetadata>();
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
int nonNullCount = 0;
|
|
524
|
+
for (int i = 0; i < typeMetadata.Length; i++)
|
|
525
|
+
{
|
|
526
|
+
if (typeMetadata[i] != null)
|
|
527
|
+
{
|
|
528
|
+
nonNullCount++;
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
if (nonNullCount == 0)
|
|
533
|
+
{
|
|
534
|
+
return Array.Empty<TypeFieldMetadata>();
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
TypeFieldMetadata[] result = new TypeFieldMetadata[nonNullCount];
|
|
538
|
+
int resultIndex = 0;
|
|
539
|
+
for (int i = 0; i < typeMetadata.Length; i++)
|
|
540
|
+
{
|
|
541
|
+
TypeFieldMetadata metadata = typeMetadata[i];
|
|
542
|
+
if (metadata == null)
|
|
543
|
+
{
|
|
544
|
+
continue;
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
string typeName = metadata.typeName ?? string.Empty;
|
|
548
|
+
string[] fieldNames = metadata.fieldNames ?? Array.Empty<string>();
|
|
549
|
+
string[] sortedFieldNames =
|
|
550
|
+
fieldNames.Length == 0 ? Array.Empty<string>() : CopyAndSort(fieldNames);
|
|
551
|
+
|
|
552
|
+
result[resultIndex] = new TypeFieldMetadata(typeName, sortedFieldNames);
|
|
553
|
+
resultIndex++;
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
Array.Sort(result, CompareTypeFieldMetadata);
|
|
557
|
+
return result;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
private static RelationalTypeMetadata[] SortRelationalTypeMetadata(
|
|
561
|
+
RelationalTypeMetadata[] relationalTypeMetadata
|
|
562
|
+
)
|
|
563
|
+
{
|
|
564
|
+
if (relationalTypeMetadata == null || relationalTypeMetadata.Length == 0)
|
|
565
|
+
{
|
|
566
|
+
return Array.Empty<RelationalTypeMetadata>();
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
int nonNullCount = 0;
|
|
570
|
+
for (int i = 0; i < relationalTypeMetadata.Length; i++)
|
|
571
|
+
{
|
|
572
|
+
if (relationalTypeMetadata[i] != null)
|
|
573
|
+
{
|
|
574
|
+
nonNullCount++;
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
if (nonNullCount == 0)
|
|
579
|
+
{
|
|
580
|
+
return Array.Empty<RelationalTypeMetadata>();
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
RelationalTypeMetadata[] result = new RelationalTypeMetadata[nonNullCount];
|
|
584
|
+
int resultIndex = 0;
|
|
585
|
+
for (int i = 0; i < relationalTypeMetadata.Length; i++)
|
|
586
|
+
{
|
|
587
|
+
RelationalTypeMetadata metadata = relationalTypeMetadata[i];
|
|
588
|
+
if (metadata == null)
|
|
589
|
+
{
|
|
590
|
+
continue;
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
string typeName = metadata.typeName ?? string.Empty;
|
|
594
|
+
RelationalFieldMetadata[] sortedFields = SortRelationalFields(metadata.fields);
|
|
595
|
+
result[resultIndex] = new RelationalTypeMetadata(typeName, sortedFields);
|
|
596
|
+
resultIndex++;
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
Array.Sort(result, CompareRelationalTypeMetadata);
|
|
600
|
+
return result;
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
private static RelationalFieldMetadata[] SortRelationalFields(
|
|
604
|
+
RelationalFieldMetadata[] relationalFields
|
|
605
|
+
)
|
|
606
|
+
{
|
|
607
|
+
if (relationalFields == null || relationalFields.Length == 0)
|
|
608
|
+
{
|
|
609
|
+
return Array.Empty<RelationalFieldMetadata>();
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
int nonNullCount = 0;
|
|
613
|
+
for (int i = 0; i < relationalFields.Length; i++)
|
|
614
|
+
{
|
|
615
|
+
if (relationalFields[i] != null)
|
|
616
|
+
{
|
|
617
|
+
nonNullCount++;
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
if (nonNullCount == 0)
|
|
622
|
+
{
|
|
623
|
+
return Array.Empty<RelationalFieldMetadata>();
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
RelationalFieldMetadata[] result = new RelationalFieldMetadata[nonNullCount];
|
|
627
|
+
int resultIndex = 0;
|
|
628
|
+
for (int i = 0; i < relationalFields.Length; i++)
|
|
629
|
+
{
|
|
630
|
+
RelationalFieldMetadata field = relationalFields[i];
|
|
631
|
+
if (field == null)
|
|
632
|
+
{
|
|
633
|
+
continue;
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
result[resultIndex] = new RelationalFieldMetadata(
|
|
637
|
+
field.fieldName,
|
|
638
|
+
field.attributeKind,
|
|
639
|
+
field.fieldKind,
|
|
640
|
+
field.elementTypeName,
|
|
641
|
+
field.isInterface
|
|
642
|
+
);
|
|
643
|
+
resultIndex++;
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
Array.Sort(result, CompareRelationalFieldMetadata);
|
|
647
|
+
return result;
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
private static string[] CopyAndSort(string[] values)
|
|
651
|
+
{
|
|
652
|
+
string[] result = new string[values.Length];
|
|
653
|
+
Array.Copy(values, result, values.Length);
|
|
654
|
+
Array.Sort(result, StringComparer.Ordinal);
|
|
655
|
+
return result;
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
private static int CompareTypeFieldMetadata(TypeFieldMetadata left, TypeFieldMetadata right)
|
|
659
|
+
{
|
|
660
|
+
if (ReferenceEquals(left, right))
|
|
661
|
+
{
|
|
662
|
+
return 0;
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
if (left == null)
|
|
666
|
+
{
|
|
667
|
+
return -1;
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
if (right == null)
|
|
671
|
+
{
|
|
672
|
+
return 1;
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
int typeNameComparison = string.CompareOrdinal(left.typeName, right.typeName);
|
|
676
|
+
if (typeNameComparison != 0)
|
|
677
|
+
{
|
|
678
|
+
return typeNameComparison;
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
string[] leftFields = left.fieldNames ?? Array.Empty<string>();
|
|
682
|
+
string[] rightFields = right.fieldNames ?? Array.Empty<string>();
|
|
683
|
+
|
|
684
|
+
int lengthComparison = leftFields.Length.CompareTo(rightFields.Length);
|
|
685
|
+
if (lengthComparison != 0)
|
|
686
|
+
{
|
|
687
|
+
return lengthComparison;
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
for (int i = 0; i < leftFields.Length; i++)
|
|
691
|
+
{
|
|
692
|
+
int fieldComparison = string.CompareOrdinal(leftFields[i], rightFields[i]);
|
|
693
|
+
if (fieldComparison != 0)
|
|
694
|
+
{
|
|
695
|
+
return fieldComparison;
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
return 0;
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
private static int CompareRelationalTypeMetadata(
|
|
703
|
+
RelationalTypeMetadata left,
|
|
704
|
+
RelationalTypeMetadata right
|
|
705
|
+
)
|
|
706
|
+
{
|
|
707
|
+
if (ReferenceEquals(left, right))
|
|
708
|
+
{
|
|
709
|
+
return 0;
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
if (left == null)
|
|
713
|
+
{
|
|
714
|
+
return -1;
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
if (right == null)
|
|
718
|
+
{
|
|
719
|
+
return 1;
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
int typeNameComparison = string.CompareOrdinal(left.typeName, right.typeName);
|
|
723
|
+
if (typeNameComparison != 0)
|
|
724
|
+
{
|
|
725
|
+
return typeNameComparison;
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
RelationalFieldMetadata[] leftFields =
|
|
729
|
+
left.fields ?? Array.Empty<RelationalFieldMetadata>();
|
|
730
|
+
RelationalFieldMetadata[] rightFields =
|
|
731
|
+
right.fields ?? Array.Empty<RelationalFieldMetadata>();
|
|
732
|
+
|
|
733
|
+
int lengthComparison = leftFields.Length.CompareTo(rightFields.Length);
|
|
734
|
+
if (lengthComparison != 0)
|
|
735
|
+
{
|
|
736
|
+
return lengthComparison;
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
for (int i = 0; i < leftFields.Length; i++)
|
|
740
|
+
{
|
|
741
|
+
int fieldComparison = CompareRelationalFieldMetadata(leftFields[i], rightFields[i]);
|
|
742
|
+
if (fieldComparison != 0)
|
|
743
|
+
{
|
|
744
|
+
return fieldComparison;
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
return 0;
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
private static int CompareRelationalFieldMetadata(
|
|
752
|
+
RelationalFieldMetadata left,
|
|
753
|
+
RelationalFieldMetadata right
|
|
754
|
+
)
|
|
755
|
+
{
|
|
756
|
+
if (ReferenceEquals(left, right))
|
|
757
|
+
{
|
|
758
|
+
return 0;
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
if (left == null)
|
|
762
|
+
{
|
|
763
|
+
return -1;
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
if (right == null)
|
|
767
|
+
{
|
|
768
|
+
return 1;
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
int fieldNameComparison = string.CompareOrdinal(left.fieldName, right.fieldName);
|
|
772
|
+
if (fieldNameComparison != 0)
|
|
773
|
+
{
|
|
774
|
+
return fieldNameComparison;
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
int attributeComparison = left.attributeKind.CompareTo(right.attributeKind);
|
|
778
|
+
if (attributeComparison != 0)
|
|
779
|
+
{
|
|
780
|
+
return attributeComparison;
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
int fieldKindComparison = left.fieldKind.CompareTo(right.fieldKind);
|
|
784
|
+
if (fieldKindComparison != 0)
|
|
785
|
+
{
|
|
786
|
+
return fieldKindComparison;
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
int elementTypeComparison = string.CompareOrdinal(
|
|
790
|
+
left.elementTypeName,
|
|
791
|
+
right.elementTypeName
|
|
792
|
+
);
|
|
793
|
+
if (elementTypeComparison != 0)
|
|
794
|
+
{
|
|
795
|
+
return elementTypeComparison;
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
if (left.isInterface == right.isInterface)
|
|
799
|
+
{
|
|
800
|
+
return 0;
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
return left.isInterface ? -1 : 1;
|
|
804
|
+
}
|
|
498
805
|
#endif
|
|
499
806
|
}
|
|
500
807
|
}
|
|
@@ -663,7 +663,7 @@ namespace WallstopStudios.UnityHelpers.Visuals.UIToolkit
|
|
|
663
663
|
if (!string.IsNullOrEmpty(rel))
|
|
664
664
|
{
|
|
665
665
|
// If rel starts with Assets, strip it for subsequent segments
|
|
666
|
-
display = rel.
|
|
666
|
+
display = rel.SanitizePath();
|
|
667
667
|
if (display.StartsWith("Assets/", StringComparison.OrdinalIgnoreCase))
|
|
668
668
|
{
|
|
669
669
|
display = display.Substring("Assets/".Length);
|
|
@@ -712,8 +712,8 @@ namespace WallstopStudios.UnityHelpers.Visuals.UIToolkit
|
|
|
712
712
|
{
|
|
713
713
|
return;
|
|
714
714
|
}
|
|
715
|
-
|
|
716
|
-
if (
|
|
715
|
+
|
|
716
|
+
if ((evt.currentTarget as VisualElement)?.userData is Toggle toggle)
|
|
717
717
|
{
|
|
718
718
|
toggle.value = !toggle.value;
|
|
719
719
|
}
|
|
@@ -28,7 +28,7 @@ namespace WallstopStudios.UnityHelpers.Tests.Editor.Helper
|
|
|
28
28
|
AssetDatabase.CreateFolder("Assets", "TempHelpersPrefabs");
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
string assetPath = Path.Combine(folder, "TestPrefab.prefab").
|
|
31
|
+
string assetPath = Path.Combine(folder, "TestPrefab.prefab").SanitizePath();
|
|
32
32
|
GameObject prefabSource = Track(new GameObject("Helpers_PrefabSource"));
|
|
33
33
|
try
|
|
34
34
|
{
|
|
@@ -63,7 +63,7 @@ namespace WallstopStudios.UnityHelpers.Tests.Editor.Helper
|
|
|
63
63
|
AssetDatabase.CreateFolder("Assets", "TempHelpersScriptables");
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
string assetPath = Path.Combine(folder, "Dummy.asset").
|
|
66
|
+
string assetPath = Path.Combine(folder, "Dummy.asset").SanitizePath();
|
|
67
67
|
DummyScriptableObject asset = Track(
|
|
68
68
|
ScriptableObject.CreateInstance<DummyScriptableObject>()
|
|
69
69
|
);
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
#if UNITY_EDITOR
|
|
2
|
+
namespace WallstopStudios.UnityHelpers.Tests.Editor.Helper
|
|
3
|
+
{
|
|
4
|
+
using System;
|
|
5
|
+
using System.Reflection;
|
|
6
|
+
using NUnit.Framework;
|
|
7
|
+
using WallstopStudios.UnityHelpers.Core.Helper;
|
|
8
|
+
|
|
9
|
+
public sealed class TypedHelperEditorTarget
|
|
10
|
+
{
|
|
11
|
+
public int Field;
|
|
12
|
+
public int Property { get; set; }
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
[TestFixture]
|
|
16
|
+
public sealed class ReflectionHelpersTypedEditorTests
|
|
17
|
+
{
|
|
18
|
+
[Test]
|
|
19
|
+
public void EditorTypedFieldSetterFallbacksWhenCapabilitiesDisabled()
|
|
20
|
+
{
|
|
21
|
+
FieldInfo field = typeof(TypedHelperEditorTarget).GetField(
|
|
22
|
+
nameof(TypedHelperEditorTarget.Field)
|
|
23
|
+
);
|
|
24
|
+
using (
|
|
25
|
+
ReflectionHelpers.OverrideReflectionCapabilities(
|
|
26
|
+
expressions: false,
|
|
27
|
+
dynamicIl: false
|
|
28
|
+
)
|
|
29
|
+
)
|
|
30
|
+
{
|
|
31
|
+
FieldSetter<TypedHelperEditorTarget, int> setter = ReflectionHelpers.GetFieldSetter<
|
|
32
|
+
TypedHelperEditorTarget,
|
|
33
|
+
int
|
|
34
|
+
>(field);
|
|
35
|
+
TypedHelperEditorTarget instance = new();
|
|
36
|
+
setter(ref instance, 12);
|
|
37
|
+
Assert.AreEqual(12, instance.Field);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
[Test]
|
|
42
|
+
public void EditorTypedPropertySetterFallbacksWhenCapabilitiesDisabled()
|
|
43
|
+
{
|
|
44
|
+
PropertyInfo property = typeof(TypedHelperEditorTarget).GetProperty(
|
|
45
|
+
nameof(TypedHelperEditorTarget.Property)
|
|
46
|
+
);
|
|
47
|
+
using (
|
|
48
|
+
ReflectionHelpers.OverrideReflectionCapabilities(
|
|
49
|
+
expressions: false,
|
|
50
|
+
dynamicIl: false
|
|
51
|
+
)
|
|
52
|
+
)
|
|
53
|
+
{
|
|
54
|
+
Action<TypedHelperEditorTarget, int> setter = ReflectionHelpers.GetPropertySetter<
|
|
55
|
+
TypedHelperEditorTarget,
|
|
56
|
+
int
|
|
57
|
+
>(property);
|
|
58
|
+
TypedHelperEditorTarget instance = new();
|
|
59
|
+
setter(instance, 34);
|
|
60
|
+
Assert.AreEqual(34, instance.Property);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
[Test]
|
|
65
|
+
public void EditorTypedPropertyGetterFallbacksWhenCapabilitiesDisabled()
|
|
66
|
+
{
|
|
67
|
+
PropertyInfo property = typeof(TypedHelperEditorTarget).GetProperty(
|
|
68
|
+
nameof(TypedHelperEditorTarget.Property)
|
|
69
|
+
);
|
|
70
|
+
TypedHelperEditorTarget instance = new() { Property = 56 };
|
|
71
|
+
using (
|
|
72
|
+
ReflectionHelpers.OverrideReflectionCapabilities(
|
|
73
|
+
expressions: false,
|
|
74
|
+
dynamicIl: false
|
|
75
|
+
)
|
|
76
|
+
)
|
|
77
|
+
{
|
|
78
|
+
Func<TypedHelperEditorTarget, int> getter = ReflectionHelpers.GetPropertyGetter<
|
|
79
|
+
TypedHelperEditorTarget,
|
|
80
|
+
int
|
|
81
|
+
>(property);
|
|
82
|
+
Assert.AreEqual(56, getter(instance));
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
#endif
|
|
@@ -296,7 +296,7 @@ namespace WallstopStudios.UnityHelpers.Tests.Editor.Helper
|
|
|
296
296
|
private void CreateTestTexture(bool readable, int width = 4, int height = 4)
|
|
297
297
|
{
|
|
298
298
|
_testTexturePath = Path.Combine(TestFolder, $"TestTexture_{System.Guid.NewGuid()}.png")
|
|
299
|
-
.
|
|
299
|
+
.SanitizePath();
|
|
300
300
|
|
|
301
301
|
Texture2D tempTexture = Track(
|
|
302
302
|
new Texture2D(width, height, TextureFormat.RGBA32, false)
|
|
@@ -11,7 +11,7 @@ namespace WallstopStudios.UnityHelpers.Tests.Editor
|
|
|
11
11
|
[Test]
|
|
12
12
|
public void ScanReportConstructorCopiesFolders()
|
|
13
13
|
{
|
|
14
|
-
|
|
14
|
+
PrefabChecker.ScanReport report = new PrefabChecker.ScanReport(new[] { "A", "B" });
|
|
15
15
|
string[] folders = report.folders;
|
|
16
16
|
CollectionAssert.AreEqual(new[] { "A", "B" }, folders);
|
|
17
17
|
}
|
|
@@ -19,10 +19,10 @@ namespace WallstopStudios.UnityHelpers.Tests.Editor
|
|
|
19
19
|
[Test]
|
|
20
20
|
public void ScanReportAddCopiesMessages()
|
|
21
21
|
{
|
|
22
|
-
|
|
22
|
+
PrefabChecker.ScanReport report = new PrefabChecker.ScanReport(Array.Empty<string>());
|
|
23
23
|
report.Add("path.prefab", new List<string> { "m1", "m2" });
|
|
24
24
|
Assert.AreEqual(1, report.items.Count);
|
|
25
|
-
|
|
25
|
+
PrefabChecker.ScanReport.Item first = report.items[0];
|
|
26
26
|
Assert.AreEqual("path.prefab", first.path);
|
|
27
27
|
string[] messages = first.messages;
|
|
28
28
|
CollectionAssert.AreEqual(new[] { "m1", "m2" }, messages);
|
|
@@ -18,20 +18,23 @@ namespace WallstopStudios.UnityHelpers.Tests.Editor.Sprites
|
|
|
18
18
|
public void SortsAscendingAndDescending()
|
|
19
19
|
{
|
|
20
20
|
AnimationCopierWindow wnd = ScriptableObject.CreateInstance<AnimationCopierWindow>();
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
AnimationCopierWindow.AnimationFileInfo a = NewFileInfo("zeta.anim");
|
|
22
|
+
AnimationCopierWindow.AnimationFileInfo b = NewFileInfo("alpha.anim");
|
|
23
|
+
AnimationCopierWindow.AnimationFileInfo c = NewFileInfo("beta.anim");
|
|
24
|
+
List<AnimationCopierWindow.AnimationFileInfo> items =
|
|
25
|
+
new List<AnimationCopierWindow.AnimationFileInfo> { a, b, c };
|
|
25
26
|
|
|
26
27
|
wnd._filterText = string.Empty;
|
|
27
28
|
wnd._filterUseRegex = false;
|
|
28
29
|
wnd._sortAscending = true;
|
|
29
|
-
|
|
30
|
+
List<AnimationCopierWindow.AnimationFileInfo> asc = wnd.ApplyFilterAndSort(items)
|
|
31
|
+
.ToList();
|
|
30
32
|
string[] ascNames = asc.Select(o => o.FileName).ToArray();
|
|
31
33
|
CollectionAssert.AreEqual(new[] { "alpha.anim", "beta.anim", "zeta.anim" }, ascNames);
|
|
32
34
|
|
|
33
35
|
wnd._sortAscending = false;
|
|
34
|
-
|
|
36
|
+
List<AnimationCopierWindow.AnimationFileInfo> desc = wnd.ApplyFilterAndSort(items)
|
|
37
|
+
.ToList();
|
|
35
38
|
string[] descNames = desc.Select(o => o.FileName).ToArray();
|
|
36
39
|
CollectionAssert.AreEqual(new[] { "zeta.anim", "beta.anim", "alpha.anim" }, descNames);
|
|
37
40
|
}
|
|
@@ -40,21 +43,24 @@ namespace WallstopStudios.UnityHelpers.Tests.Editor.Sprites
|
|
|
40
43
|
public void FiltersBySubstringAndRegex()
|
|
41
44
|
{
|
|
42
45
|
AnimationCopierWindow wnd = ScriptableObject.CreateInstance<AnimationCopierWindow>();
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
46
|
+
AnimationCopierWindow.AnimationFileInfo a = NewFileInfo("walk.anim");
|
|
47
|
+
AnimationCopierWindow.AnimationFileInfo b = NewFileInfo("attack.anim");
|
|
48
|
+
AnimationCopierWindow.AnimationFileInfo c = NewFileInfo("idle.anim");
|
|
49
|
+
List<AnimationCopierWindow.AnimationFileInfo> items =
|
|
50
|
+
new List<AnimationCopierWindow.AnimationFileInfo> { a, b, c };
|
|
47
51
|
|
|
48
52
|
wnd._filterText = "ta";
|
|
49
53
|
wnd._filterUseRegex = false;
|
|
50
54
|
wnd._sortAscending = true;
|
|
51
|
-
|
|
55
|
+
List<AnimationCopierWindow.AnimationFileInfo> sub = wnd.ApplyFilterAndSort(items)
|
|
56
|
+
.ToList();
|
|
52
57
|
string[] subNames = sub.Select(o => o.FileName).ToArray();
|
|
53
58
|
CollectionAssert.AreEquivalent(new[] { "attack.anim" }, subNames);
|
|
54
59
|
|
|
55
60
|
wnd._filterText = "^i";
|
|
56
61
|
wnd._filterUseRegex = true;
|
|
57
|
-
|
|
62
|
+
List<AnimationCopierWindow.AnimationFileInfo> rx = wnd.ApplyFilterAndSort(items)
|
|
63
|
+
.ToList();
|
|
58
64
|
string[] rxNames = rx.Select(o => o.FileName).ToArray();
|
|
59
65
|
CollectionAssert.AreEquivalent(new[] { "idle.anim" }, rxNames);
|
|
60
66
|
}
|
|
@@ -5,6 +5,7 @@ namespace WallstopStudios.UnityHelpers.Tests.Editor.Sprites
|
|
|
5
5
|
using NUnit.Framework;
|
|
6
6
|
using UnityEditor;
|
|
7
7
|
using UnityEngine;
|
|
8
|
+
using WallstopStudios.UnityHelpers.Core.Helper;
|
|
8
9
|
using WallstopStudios.UnityHelpers.Editor.Sprites;
|
|
9
10
|
using WallstopStudios.UnityHelpers.Tests.Editor.Utils;
|
|
10
11
|
|
|
@@ -35,7 +36,7 @@ namespace WallstopStudios.UnityHelpers.Tests.Editor.Sprites
|
|
|
35
36
|
[Test]
|
|
36
37
|
public void AnalyzeDetectsNewChangedUnchangedAndOrphans()
|
|
37
38
|
{
|
|
38
|
-
string srcA = Path.Combine(SrcRoot, "A.anim").
|
|
39
|
+
string srcA = Path.Combine(SrcRoot, "A.anim").SanitizePath();
|
|
39
40
|
CreateEmptyClip(srcA);
|
|
40
41
|
AssetDatabase.SaveAssets();
|
|
41
42
|
AssetDatabase.Refresh();
|
|
@@ -55,7 +56,7 @@ namespace WallstopStudios.UnityHelpers.Tests.Editor.Sprites
|
|
|
55
56
|
Assert.AreEqual(0, orphansCount);
|
|
56
57
|
|
|
57
58
|
// Create destination copy to become unchanged
|
|
58
|
-
string dstA = Path.Combine(DstRoot, "A.anim").
|
|
59
|
+
string dstA = Path.Combine(DstRoot, "A.anim").SanitizePath();
|
|
59
60
|
Assert.IsTrue(AssetDatabase.CopyAsset(srcA, dstA));
|
|
60
61
|
AssetDatabase.SaveAssets();
|
|
61
62
|
AssetDatabase.Refresh();
|
|
@@ -66,7 +67,7 @@ namespace WallstopStudios.UnityHelpers.Tests.Editor.Sprites
|
|
|
66
67
|
AssetDatabase.Refresh();
|
|
67
68
|
|
|
68
69
|
// Add orphan in destination
|
|
69
|
-
string dstB = Path.Combine(DstRoot, "B.anim").
|
|
70
|
+
string dstB = Path.Combine(DstRoot, "B.anim").SanitizePath();
|
|
70
71
|
CreateEmptyClip(dstB);
|
|
71
72
|
AssetDatabase.SaveAssets();
|
|
72
73
|
AssetDatabase.Refresh();
|
|
@@ -87,8 +88,8 @@ namespace WallstopStudios.UnityHelpers.Tests.Editor.Sprites
|
|
|
87
88
|
[Test]
|
|
88
89
|
public void CopyChangedPreservesGuidAndOverwrites()
|
|
89
90
|
{
|
|
90
|
-
string srcA = Path.Combine(SrcRoot, "A.anim").
|
|
91
|
-
string dstA = Path.Combine(DstRoot, "A.anim").
|
|
91
|
+
string srcA = Path.Combine(SrcRoot, "A.anim").SanitizePath();
|
|
92
|
+
string dstA = Path.Combine(DstRoot, "A.anim").SanitizePath();
|
|
92
93
|
CreateEmptyClip(srcA);
|
|
93
94
|
AssetDatabase.SaveAssets();
|
|
94
95
|
AssetDatabase.Refresh();
|
|
@@ -121,8 +122,8 @@ namespace WallstopStudios.UnityHelpers.Tests.Editor.Sprites
|
|
|
121
122
|
[Test]
|
|
122
123
|
public void MirrorDeleteRemovesOrphansWhenNotDryRun()
|
|
123
124
|
{
|
|
124
|
-
string srcA = Path.Combine(SrcRoot, "A.anim").
|
|
125
|
-
string dstB = Path.Combine(DstRoot, "B.anim").
|
|
125
|
+
string srcA = Path.Combine(SrcRoot, "A.anim").SanitizePath();
|
|
126
|
+
string dstB = Path.Combine(DstRoot, "B.anim").SanitizePath();
|
|
126
127
|
CreateEmptyClip(srcA);
|
|
127
128
|
CreateEmptyClip(dstB);
|
|
128
129
|
AssetDatabase.SaveAssets();
|
|
@@ -29,7 +29,8 @@ namespace WallstopStudios.UnityHelpers.Tests.Editor.Sprites
|
|
|
29
29
|
keys[2] = new ObjectReferenceKeyframe { time = 0.2f, value = s3 };
|
|
30
30
|
AnimationUtility.SetObjectReferenceCurve(clip, binding, keys);
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
AnimationViewerWindow.EditorLayerData instance =
|
|
33
|
+
new AnimationViewerWindow.EditorLayerData(clip);
|
|
33
34
|
Assert.NotNull(instance);
|
|
34
35
|
Assert.AreEqual(3, instance.Sprites.Count);
|
|
35
36
|
}
|