com.wallstop-studios.unity-helpers 2.0.0-rc81.2 → 2.0.0-rc81.4

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.
@@ -24,7 +24,7 @@ namespace WallstopStudios.UnityHelpers.Editor
24
24
  private static readonly Dictionary<Type, List<FieldInfo>> ListFieldsByType = new();
25
25
  private static readonly Dictionary<Type, List<FieldInfo>> StringFieldsByType = new();
26
26
  private static readonly Dictionary<Type, List<FieldInfo>> ObjectFieldsByType = new();
27
- private static readonly Dictionary<Type, List<RequireComponent>> RequiredComponentsByType =
27
+ private static readonly Dictionary<Type, RequireComponent[]> RequiredComponentsByType =
28
28
  new();
29
29
 
30
30
  private readonly List<string> _assetPaths = new();
@@ -486,33 +486,59 @@ namespace WallstopStudios.UnityHelpers.Editor
486
486
  List<MonoBehaviour> buffer
487
487
  )
488
488
  {
489
- Transform[] allTransforms = prefabRoot.GetComponentsInChildren<Transform>(true);
490
- foreach (Transform transform in allTransforms)
489
+ using PooledResource<List<Transform>> transformBufferResource =
490
+ Buffers<Transform>.List.Get();
491
+ List<Transform> transforms = transformBufferResource.resource;
492
+ prefabRoot.GetComponentsInChildren(true, transforms);
493
+ foreach (Transform transform in transforms)
491
494
  {
492
- MonoBehaviour[] components = transform.GetComponents<MonoBehaviour>();
493
- if (
494
- components.Length
495
- == buffer.Count(c => c != null && c.gameObject == transform.gameObject)
496
- )
495
+ using PooledResource<List<MonoBehaviour>> componentBuffer =
496
+ Buffers<MonoBehaviour>.List.Get();
497
+ List<MonoBehaviour> components = componentBuffer.resource;
498
+ transform.GetComponents(components);
499
+ int bufferCount = 0;
500
+ foreach (MonoBehaviour c in components)
501
+ {
502
+ if (c != null && c.gameObject == transform.gameObject)
503
+ {
504
+ ++bufferCount;
505
+ }
506
+ }
507
+ if (components.Count == bufferCount)
497
508
  {
498
509
  continue;
499
510
  }
500
511
 
501
- bool foundInNonNullBuffer = components.Any(buffer.Contains);
512
+ bool foundInNonNullBuffer = false;
513
+ foreach (MonoBehaviour c in components)
514
+ {
515
+ if (buffer.Contains(c))
516
+ {
517
+ foundInNonNullBuffer = true;
518
+ break;
519
+ }
520
+ }
521
+
502
522
  if (foundInNonNullBuffer)
503
523
  {
504
524
  return transform.gameObject;
505
525
  }
506
526
 
507
- if (components.Length != 0 || !buffer.Exists(c => c == null))
527
+ if (components.Count != 0 || !buffer.Exists(c => c == null))
508
528
  {
509
529
  continue;
510
530
  }
511
531
 
512
- HashSet<GameObject> gameObjectsWithComponentsInBuffer = buffer
513
- .Where(c => c != null)
514
- .Select(c => c.gameObject)
515
- .ToHashSet();
532
+ using PooledResource<HashSet<GameObject>> setResource =
533
+ Buffers<GameObject>.HashSet.Get();
534
+ HashSet<GameObject> gameObjectsWithComponentsInBuffer = setResource.resource;
535
+ foreach (MonoBehaviour c in buffer)
536
+ {
537
+ if (c != null)
538
+ {
539
+ gameObjectsWithComponentsInBuffer.Add(c.gameObject);
540
+ }
541
+ }
516
542
  if (!gameObjectsWithComponentsInBuffer.Contains(transform.gameObject))
517
543
  {
518
544
  return transform.gameObject;
@@ -535,7 +561,7 @@ namespace WallstopStudios.UnityHelpers.Editor
535
561
  )
536
562
  .Where(field =>
537
563
  field.IsPublic
538
- || field.GetCustomAttributes(typeof(SerializeField), true).Any()
564
+ || field.IsAttributeDefined<SerializeField>(out _, inherit: true)
539
565
  )
540
566
  .ToList()
541
567
  );
@@ -597,15 +623,12 @@ namespace WallstopStudios.UnityHelpers.Editor
597
623
  int issueCount = 0;
598
624
  Type componentType = component.GetType();
599
625
 
600
- List<RequireComponent> required = RequiredComponentsByType.GetOrAdd(
626
+ RequireComponent[] required = RequiredComponentsByType.GetOrAdd(
601
627
  componentType,
602
- type =>
603
- type.GetCustomAttributes(typeof(RequireComponent), true)
604
- .Cast<RequireComponent>()
605
- .ToList()
628
+ type => type.GetAllAttributesSafe<RequireComponent>(inherit: true)
606
629
  );
607
630
 
608
- if (required.Count <= 0)
631
+ if (required.Length <= 0)
609
632
  {
610
633
  return issueCount;
611
634
  }
@@ -688,9 +711,10 @@ namespace WallstopStudios.UnityHelpers.Editor
688
711
  )
689
712
  )
690
713
  {
691
- bool hasValidateAttribute = field
692
- .GetCustomAttributes(typeof(ValidateAssignmentAttribute), true)
693
- .Any();
714
+ bool hasValidateAttribute = field.IsAttributeDefined<ValidateAssignmentAttribute>(
715
+ out _,
716
+ inherit: true
717
+ );
694
718
 
695
719
  if (_onlyCheckNullObjectsWithAttribute && !hasValidateAttribute)
696
720
  {
@@ -22,16 +22,19 @@ namespace WallstopStudios.UnityHelpers.Core.Attributes
22
22
 
23
23
  public static class ChildComponentExtensions
24
24
  {
25
- private static readonly List<Component> ChildCache = new();
26
25
  private static readonly Dictionary<
27
26
  Type,
28
- (FieldInfo field, Action<object, object> setter)[]
27
+ (FieldInfo field, ChildComponentAttribute attribute, Action<object, object> setter)[]
29
28
  > FieldsByType = new();
30
29
 
31
30
  public static void AssignChildComponents(this Component component)
32
31
  {
33
32
  Type componentType = component.GetType();
34
- (FieldInfo field, Action<object, object> setter)[] fields = FieldsByType.GetOrAdd(
33
+ (
34
+ FieldInfo field,
35
+ ChildComponentAttribute attribute,
36
+ Action<object, object> setter
37
+ )[] fields = FieldsByType.GetOrAdd(
35
38
  componentType,
36
39
  type =>
37
40
  {
@@ -39,51 +42,58 @@ namespace WallstopStudios.UnityHelpers.Core.Attributes
39
42
  BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic
40
43
  );
41
44
  return fields
42
- .Where(field => field.IsAttributeDefined<ChildComponentAttribute>(out _))
43
- .Select(field => (field, ReflectionHelpers.GetFieldSetter(field)))
45
+ .Select(field =>
46
+ field.IsAttributeDefined(out ChildComponentAttribute attribute)
47
+ ? (field, attribute, ReflectionHelpers.GetFieldSetter(field))
48
+ : (null, null, null)
49
+ )
50
+ .Where(tuple => tuple.attribute != null)
44
51
  .ToArray();
45
52
  }
46
53
  );
47
54
 
48
- foreach ((FieldInfo field, Action<object, object> setter) in fields)
55
+ foreach (
56
+ (
57
+ FieldInfo field,
58
+ ChildComponentAttribute attribute,
59
+ Action<object, object> setter
60
+ ) in fields
61
+ )
49
62
  {
50
- if (!field.IsAttributeDefined(out ChildComponentAttribute customAttribute))
51
- {
52
- continue;
53
- }
54
-
55
63
  Type fieldType = field.FieldType;
56
64
  bool isArray = fieldType.IsArray;
57
65
  Type childComponentType = isArray ? fieldType.GetElementType() : fieldType;
58
66
  bool foundChild;
59
- if (customAttribute.onlyDescendents)
67
+ if (attribute.onlyDescendents)
60
68
  {
69
+ using PooledResource<List<Transform>> childBufferResource =
70
+ Buffers<Transform>.List.Get();
71
+ List<Transform> childBuffer = childBufferResource.resource;
61
72
  if (isArray)
62
73
  {
63
- ChildCache.Clear();
64
- using PooledResource<List<Transform>> childBufferResource =
65
- Buffers<Transform>.List.Get();
66
- List<Transform> childBuffer = childBufferResource.resource;
74
+ using PooledResource<List<Component>> componentResource =
75
+ Buffers<Component>.List.Get();
76
+ List<Component> cache = componentResource.resource;
67
77
  foreach (Transform child in component.IterateOverAllChildren(childBuffer))
68
78
  {
69
79
  foreach (
70
80
  Component childComponent in child.GetComponentsInChildren(
71
81
  childComponentType,
72
- customAttribute.includeInactive
82
+ attribute.includeInactive
73
83
  )
74
84
  )
75
85
  {
76
- ChildCache.Add(childComponent);
86
+ cache.Add(childComponent);
77
87
  }
78
88
  }
79
89
 
80
- foundChild = 0 < ChildCache.Count;
90
+ foundChild = 0 < cache.Count;
81
91
 
82
92
  Array correctTypedArray = ReflectionHelpers.CreateArray(
83
93
  childComponentType,
84
- ChildCache.Count
94
+ cache.Count
85
95
  );
86
- Array.Copy(ChildCache.ToArray(), correctTypedArray, ChildCache.Count);
96
+ Array.Copy(cache.ToArray(), correctTypedArray, cache.Count);
87
97
  setter(component, correctTypedArray);
88
98
  }
89
99
  else if (
@@ -95,15 +105,12 @@ namespace WallstopStudios.UnityHelpers.Core.Attributes
95
105
 
96
106
  IList instance = ReflectionHelpers.CreateList(childComponentType);
97
107
  foundChild = false;
98
- using PooledResource<List<Transform>> childBufferResource =
99
- Buffers<Transform>.List.Get();
100
- List<Transform> childBuffer = childBufferResource.resource;
101
108
  foreach (Transform child in component.IterateOverAllChildren(childBuffer))
102
109
  {
103
110
  foreach (
104
111
  Component childComponent in child.GetComponentsInChildren(
105
112
  childComponentType,
106
- customAttribute.includeInactive
113
+ attribute.includeInactive
107
114
  )
108
115
  )
109
116
  {
@@ -118,9 +125,6 @@ namespace WallstopStudios.UnityHelpers.Core.Attributes
118
125
  {
119
126
  foundChild = false;
120
127
  Component childComponent = null;
121
- using PooledResource<List<Transform>> childBufferResource =
122
- Buffers<Transform>.List.Get();
123
- List<Transform> childBuffer = childBufferResource.resource;
124
128
  foreach (
125
129
  Transform child in component.IterateOverAllChildrenRecursivelyBreadthFirst(
126
130
  childBuffer
@@ -131,7 +135,7 @@ namespace WallstopStudios.UnityHelpers.Core.Attributes
131
135
  if (
132
136
  childComponent == null
133
137
  || (
134
- !customAttribute.includeInactive
138
+ !attribute.includeInactive
135
139
  && (
136
140
  !childComponent.gameObject.activeInHierarchy
137
141
  || childComponent is Behaviour { enabled: false }
@@ -157,7 +161,7 @@ namespace WallstopStudios.UnityHelpers.Core.Attributes
157
161
  {
158
162
  Component[] childComponents = component.GetComponentsInChildren(
159
163
  childComponentType,
160
- customAttribute.includeInactive
164
+ attribute.includeInactive
161
165
  );
162
166
  foundChild = 0 < childComponents.Length;
163
167
 
@@ -188,7 +192,7 @@ namespace WallstopStudios.UnityHelpers.Core.Attributes
188
192
  foreach (
189
193
  Component childComponent in component.GetComponentsInChildren(
190
194
  childComponentType,
191
- customAttribute.includeInactive
195
+ attribute.includeInactive
192
196
  )
193
197
  )
194
198
  {
@@ -202,7 +206,7 @@ namespace WallstopStudios.UnityHelpers.Core.Attributes
202
206
  {
203
207
  Component childComponent = component.GetComponentInChildren(
204
208
  childComponentType,
205
- customAttribute.includeInactive
209
+ attribute.includeInactive
206
210
  );
207
211
  foundChild = childComponent != null;
208
212
  if (foundChild)
@@ -212,7 +216,7 @@ namespace WallstopStudios.UnityHelpers.Core.Attributes
212
216
  }
213
217
  }
214
218
 
215
- if (!foundChild && !customAttribute.optional)
219
+ if (!foundChild && !attribute.optional)
216
220
  {
217
221
  component.LogError($"Unable to find child component of type {fieldType}");
218
222
  }
@@ -23,13 +23,17 @@ namespace WallstopStudios.UnityHelpers.Core.Attributes
23
23
  {
24
24
  private static readonly Dictionary<
25
25
  Type,
26
- (FieldInfo field, Action<object, object> setter)[]
26
+ (FieldInfo field, ParentComponentAttribute attribute, Action<object, object> setter)[]
27
27
  > FieldsByType = new();
28
28
 
29
29
  public static void AssignParentComponents(this Component component)
30
30
  {
31
31
  Type componentType = component.GetType();
32
- (FieldInfo field, Action<object, object> setter)[] fields = FieldsByType.GetOrAdd(
32
+ (
33
+ FieldInfo field,
34
+ ParentComponentAttribute attribute,
35
+ Action<object, object> setter
36
+ )[] fields = FieldsByType.GetOrAdd(
33
37
  componentType,
34
38
  type =>
35
39
  {
@@ -37,24 +41,29 @@ namespace WallstopStudios.UnityHelpers.Core.Attributes
37
41
  BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic
38
42
  );
39
43
  return fields
40
- .Where(field => field.IsAttributeDefined<ParentComponentAttribute>(out _))
41
- .Select(field => (field, ReflectionHelpers.GetFieldSetter(field)))
44
+ .Select(field =>
45
+ field.IsAttributeDefined(out ParentComponentAttribute attribute)
46
+ ? (field, attribute, ReflectionHelpers.GetFieldSetter(field))
47
+ : (null, null, null)
48
+ )
49
+ .Where(tuple => tuple.attribute != null)
42
50
  .ToArray();
43
51
  }
44
52
  );
45
53
 
46
- foreach ((FieldInfo field, Action<object, object> setter) in fields)
54
+ foreach (
55
+ (
56
+ FieldInfo field,
57
+ ParentComponentAttribute attribute,
58
+ Action<object, object> setter
59
+ ) in fields
60
+ )
47
61
  {
48
- if (!field.IsAttributeDefined(out ParentComponentAttribute customAttribute))
49
- {
50
- continue;
51
- }
52
-
53
62
  Type fieldType = field.FieldType;
54
63
  bool isArray = fieldType.IsArray;
55
64
  Type parentComponentType = isArray ? fieldType.GetElementType() : fieldType;
56
65
  bool foundParent;
57
- if (customAttribute.onlyAncestors)
66
+ if (attribute.onlyAncestors)
58
67
  {
59
68
  Transform parent = component.transform.parent;
60
69
  if (parent == null)
@@ -65,7 +74,7 @@ namespace WallstopStudios.UnityHelpers.Core.Attributes
65
74
  {
66
75
  Component[] parentComponents = parent.GetComponentsInParent(
67
76
  parentComponentType,
68
- customAttribute.includeInactive
77
+ attribute.includeInactive
69
78
  );
70
79
  foundParent = 0 < parentComponents.Length;
71
80
 
@@ -85,7 +94,7 @@ namespace WallstopStudios.UnityHelpers.Core.Attributes
85
94
 
86
95
  Component[] parents = parent.GetComponentsInParent(
87
96
  parentComponentType,
88
- customAttribute.includeInactive
97
+ attribute.includeInactive
89
98
  );
90
99
 
91
100
  IList instance = ReflectionHelpers.CreateList(
@@ -106,7 +115,7 @@ namespace WallstopStudios.UnityHelpers.Core.Attributes
106
115
  {
107
116
  Component childComponent = parent.GetComponentInParent(
108
117
  parentComponentType,
109
- customAttribute.includeInactive
118
+ attribute.includeInactive
110
119
  );
111
120
  foundParent = childComponent != null;
112
121
  if (foundParent)
@@ -121,7 +130,7 @@ namespace WallstopStudios.UnityHelpers.Core.Attributes
121
130
  {
122
131
  Component[] parentComponents = component.GetComponentsInParent(
123
132
  parentComponentType,
124
- customAttribute.includeInactive
133
+ attribute.includeInactive
125
134
  );
126
135
  foundParent = 0 < parentComponents.Length;
127
136
 
@@ -140,7 +149,7 @@ namespace WallstopStudios.UnityHelpers.Core.Attributes
140
149
  parentComponentType = fieldType.GenericTypeArguments[0];
141
150
  Component[] parents = component.GetComponentsInParent(
142
151
  parentComponentType,
143
- customAttribute.includeInactive
152
+ attribute.includeInactive
144
153
  );
145
154
 
146
155
  IList instance = ReflectionHelpers.CreateList(
@@ -160,7 +169,7 @@ namespace WallstopStudios.UnityHelpers.Core.Attributes
160
169
  {
161
170
  Component childComponent = component.GetComponentInParent(
162
171
  parentComponentType,
163
- customAttribute.includeInactive
172
+ attribute.includeInactive
164
173
  );
165
174
  foundParent = childComponent != null;
166
175
  if (foundParent)
@@ -170,7 +179,7 @@ namespace WallstopStudios.UnityHelpers.Core.Attributes
170
179
  }
171
180
  }
172
181
 
173
- if (!foundParent && !customAttribute.optional)
182
+ if (!foundParent && !attribute.optional)
174
183
  {
175
184
  component.LogError($"Unable to find parent component of type {fieldType}");
176
185
  }
@@ -22,13 +22,17 @@ namespace WallstopStudios.UnityHelpers.Core.Attributes
22
22
  {
23
23
  private static readonly Dictionary<
24
24
  Type,
25
- (FieldInfo field, Action<object, object> setter)[]
25
+ (FieldInfo field, SiblingComponentAttribute attribute, Action<object, object> setter)[]
26
26
  > FieldsByType = new();
27
27
 
28
28
  public static void AssignSiblingComponents(this Component component)
29
29
  {
30
30
  Type componentType = component.GetType();
31
- (FieldInfo field, Action<object, object> setter)[] fields = FieldsByType.GetOrAdd(
31
+ (
32
+ FieldInfo field,
33
+ SiblingComponentAttribute attribute,
34
+ Action<object, object> setter
35
+ )[] fields = FieldsByType.GetOrAdd(
32
36
  componentType,
33
37
  type =>
34
38
  {
@@ -36,13 +40,23 @@ namespace WallstopStudios.UnityHelpers.Core.Attributes
36
40
  BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic
37
41
  );
38
42
  return fields
39
- .Where(field => field.IsAttributeDefined<SiblingComponentAttribute>(out _))
40
- .Select(field => (field, ReflectionHelpers.GetFieldSetter(field)))
43
+ .Select(field =>
44
+ field.IsAttributeDefined(out SiblingComponentAttribute attribute)
45
+ ? (field, attribute, ReflectionHelpers.GetFieldSetter(field))
46
+ : (null, null, null)
47
+ )
48
+ .Where(tuple => tuple.attribute != null)
41
49
  .ToArray();
42
50
  }
43
51
  );
44
52
 
45
- foreach ((FieldInfo field, Action<object, object> setter) in fields)
53
+ foreach (
54
+ (
55
+ FieldInfo field,
56
+ SiblingComponentAttribute attribute,
57
+ Action<object, object> setter
58
+ ) in fields
59
+ )
46
60
  {
47
61
  Type fieldType = field.FieldType;
48
62
  bool isArray = fieldType.IsArray;
@@ -113,11 +127,7 @@ namespace WallstopStudios.UnityHelpers.Core.Attributes
113
127
  }
114
128
  }
115
129
 
116
- if (
117
- !foundSibling
118
- && field.IsAttributeDefined(out SiblingComponentAttribute customAttribute)
119
- && !customAttribute.optional
120
- )
130
+ if (!foundSibling && !attribute.optional)
121
131
  {
122
132
  component.LogError($"Unable to find sibling component of type {fieldType}");
123
133
  }
@@ -1,5 +1,6 @@
1
1
  namespace WallstopStudios.UnityHelpers.Core.Extension
2
2
  {
3
+ using System;
3
4
  using System.Collections.Generic;
4
5
  using System.Text;
5
6
  using System.Threading;
@@ -36,6 +37,10 @@ namespace WallstopStudios.UnityHelpers.Core.Extension
36
37
 
37
38
  public static byte[] GetBytes(this string input)
38
39
  {
40
+ if (string.IsNullOrEmpty(input))
41
+ {
42
+ return Array.Empty<byte>();
43
+ }
39
44
  return Encoding.Default.GetBytes(input);
40
45
  }
41
46
 
@@ -99,6 +104,11 @@ namespace WallstopStudios.UnityHelpers.Core.Extension
99
104
 
100
105
  public static string ToPascalCase(this string value, string separator = "")
101
106
  {
107
+ if (string.IsNullOrEmpty(value))
108
+ {
109
+ return string.Empty;
110
+ }
111
+
102
112
  int startIndex = 0;
103
113
  StringBuilder stringBuilder = StringBuilderCache.Value;
104
114
  stringBuilder.Clear();
@@ -2,6 +2,7 @@ namespace WallstopStudios.UnityHelpers.Core.Helper
2
2
  {
3
3
  using System;
4
4
  using System.Collections;
5
+ using System.Collections.Concurrent;
5
6
  using System.Collections.Generic;
6
7
  using System.Linq;
7
8
  using System.Reflection;
@@ -18,7 +19,11 @@ namespace WallstopStudios.UnityHelpers.Core.Helper
18
19
  public static partial class Helpers
19
20
  {
20
21
  private static readonly WaitForEndOfFrame WaitForEndOfFrame = new();
22
+ #if SINGLE_THREADED
21
23
  private static readonly Dictionary<Type, MethodInfo> AwakeMethodsByType = new();
24
+ #else
25
+ private static readonly ConcurrentDictionary<Type, MethodInfo> AwakeMethodsByType = new();
26
+ #endif
22
27
  private static readonly Object LogObject = new();
23
28
  private static readonly Dictionary<string, Object> ObjectsByTag = new(
24
29
  StringComparer.Ordinal
@@ -221,10 +226,23 @@ namespace WallstopStudios.UnityHelpers.Core.Helper
221
226
 
222
227
  public static GameObject FindChildGameObjectWithTag(this GameObject gameObject, string tag)
223
228
  {
224
- return gameObject
225
- .transform.IterateOverAllChildrenRecursively(includeSelf: true)
226
- .Select(t => t.gameObject)
227
- .FirstOrDefault(child => child.CompareTag(tag));
229
+ using PooledResource<List<Transform>> bufferResource = Buffers<Transform>.List.Get();
230
+ foreach (
231
+ Transform t in gameObject.transform.IterateOverAllChildrenRecursively(
232
+ bufferResource.resource,
233
+ includeSelf: true
234
+ )
235
+ )
236
+ {
237
+ GameObject go = t.gameObject;
238
+
239
+ if (go.CompareTag(tag))
240
+ {
241
+ return go;
242
+ }
243
+ }
244
+
245
+ return null;
228
246
  }
229
247
 
230
248
  public static Coroutine StartFunctionAsCoroutine(
@@ -548,10 +566,22 @@ namespace WallstopStudios.UnityHelpers.Core.Helper
548
566
  string tag
549
567
  )
550
568
  {
551
- return gameObject
552
- .transform.IterateOverAllChildrenRecursively(includeSelf: true)
553
- .Select(t => t.gameObject)
554
- .FirstOrDefault(go => go.CompareTag(tag));
569
+ using PooledResource<List<Transform>> bufferResource = Buffers<Transform>.List.Get();
570
+ foreach (
571
+ Transform t in gameObject.transform.IterateOverAllChildrenRecursively(
572
+ bufferResource.resource,
573
+ includeSelf: true
574
+ )
575
+ )
576
+ {
577
+ GameObject go = t.gameObject;
578
+ if (go.CompareTag(tag))
579
+ {
580
+ return go;
581
+ }
582
+ }
583
+
584
+ return null;
555
585
  }
556
586
 
557
587
  //https://answers.unity.com/questions/722748/refreshing-the-polygon-collider-2d-upon-sprite-cha.html
@@ -559,7 +589,7 @@ namespace WallstopStudios.UnityHelpers.Core.Helper
559
589
  {
560
590
  if (
561
591
  !component.TryGetComponent(out SpriteRenderer spriteRenderer)
562
- || component.TryGetComponent(out PolygonCollider2D collider)
592
+ || !component.TryGetComponent(out PolygonCollider2D collider)
563
593
  )
564
594
  {
565
595
  return;
@@ -577,7 +607,8 @@ namespace WallstopStudios.UnityHelpers.Core.Helper
577
607
 
578
608
  int pathCount = collider.pathCount = sprite.GetPhysicsShapeCount();
579
609
 
580
- List<Vector2> path = new();
610
+ using PooledResource<List<Vector2>> pathResource = Buffers<Vector2>.List.Get();
611
+ List<Vector2> path = pathResource.resource;
581
612
  for (int i = 0; i < pathCount; ++i)
582
613
  {
583
614
  path.Clear();
@@ -712,15 +743,32 @@ namespace WallstopStudios.UnityHelpers.Core.Helper
712
743
 
713
744
  public static void AwakeObject(this GameObject gameObject)
714
745
  {
715
- foreach (MonoBehaviour script in gameObject.GetComponentsInChildren<MonoBehaviour>())
746
+ using PooledResource<List<MonoBehaviour>> componentResource =
747
+ Buffers<MonoBehaviour>.List.Get();
748
+ List<MonoBehaviour> components = componentResource.resource;
749
+ gameObject.GetComponentsInChildren(false, components);
750
+ foreach (MonoBehaviour script in components)
716
751
  {
717
752
  MethodInfo awakeInfo = AwakeMethodsByType.GetOrAdd(
718
753
  script.GetType(),
719
754
  type =>
720
- type.GetMethod(
721
- "Awake",
755
+ {
756
+ MethodInfo[] methods = type.GetMethods(
722
757
  BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic
723
- )
758
+ );
759
+ foreach (MethodInfo method in methods)
760
+ {
761
+ if (
762
+ string.Equals(method.Name, "Awake", StringComparison.Ordinal)
763
+ && method.GetParameters().Length == 0
764
+ )
765
+ {
766
+ return method;
767
+ }
768
+ }
769
+
770
+ return null;
771
+ }
724
772
  );
725
773
  if (awakeInfo != null)
726
774
  {
@@ -53,8 +53,16 @@ namespace WallstopStudios.UnityHelpers.Core.Helper
53
53
  yield break;
54
54
  }
55
55
 
56
- List<T> buffer = new();
57
- foreach (Transform parent in IterateOverAllParents(component, includeSelf))
56
+ using PooledResource<List<T>> bufferResource = Buffers<T>.List.Get();
57
+ List<T> buffer = bufferResource.resource;
58
+ using PooledResource<List<Transform>> transformResource = Buffers<Transform>.List.Get();
59
+ foreach (
60
+ Transform parent in IterateOverAllParents(
61
+ component,
62
+ transformResource.resource,
63
+ includeSelf
64
+ )
65
+ )
58
66
  {
59
67
  parent.GetComponents(buffer);
60
68
  foreach (T c in buffer)
@@ -111,7 +119,8 @@ namespace WallstopStudios.UnityHelpers.Core.Helper
111
119
  yield break;
112
120
  }
113
121
 
114
- List<T> buffer = new();
122
+ using PooledResource<List<T>> bufferResource = Buffers<T>.List.Get();
123
+ List<T> buffer = bufferResource.resource;
115
124
  if (includeSelf)
116
125
  {
117
126
  component.GetComponents(buffer);
@@ -249,11 +258,13 @@ namespace WallstopStudios.UnityHelpers.Core.Helper
249
258
  yield return transform;
250
259
  }
251
260
 
261
+ using PooledResource<List<Transform>> transformResource = Buffers<Transform>.List.Get();
252
262
  for (int i = 0; i < transform.childCount; ++i)
253
263
  {
254
264
  foreach (
255
265
  Transform child in IterateOverAllChildrenRecursively(
256
266
  transform.GetChild(i),
267
+ transformResource.resource,
257
268
  includeSelf: true
258
269
  )
259
270
  )
@@ -315,7 +326,8 @@ namespace WallstopStudios.UnityHelpers.Core.Helper
315
326
  yield return transform;
316
327
  }
317
328
 
318
- Queue<Transform> iteration = new();
329
+ using PooledResource<Queue<Transform>> queueResource = Buffers<Transform>.Queue.Get();
330
+ Queue<Transform> iteration = queueResource.resource;
319
331
  iteration.Enqueue(transform);
320
332
  while (iteration.TryDequeue(out Transform current))
321
333
  {
@@ -1116,7 +1116,7 @@ namespace WallstopStudios.UnityHelpers.Core.Helper
1116
1116
  }
1117
1117
 
1118
1118
  public static TAttribute[] GetAllAttributesSafe<TAttribute>(
1119
- ICustomAttributeProvider provider,
1119
+ this ICustomAttributeProvider provider,
1120
1120
  bool inherit = true
1121
1121
  )
1122
1122
  where TAttribute : Attribute
@@ -1144,7 +1144,7 @@ namespace WallstopStudios.UnityHelpers.Core.Helper
1144
1144
  }
1145
1145
 
1146
1146
  public static Attribute[] GetAllAttributesSafe(
1147
- ICustomAttributeProvider provider,
1147
+ this ICustomAttributeProvider provider,
1148
1148
  bool inherit = true
1149
1149
  )
1150
1150
  {
@@ -1164,7 +1164,7 @@ namespace WallstopStudios.UnityHelpers.Core.Helper
1164
1164
  }
1165
1165
 
1166
1166
  public static Attribute[] GetAllAttributesSafe(
1167
- ICustomAttributeProvider provider,
1167
+ this ICustomAttributeProvider provider,
1168
1168
  Type attributeType,
1169
1169
  bool inherit = true
1170
1170
  )
@@ -1192,7 +1192,7 @@ namespace WallstopStudios.UnityHelpers.Core.Helper
1192
1192
  }
1193
1193
 
1194
1194
  public static Dictionary<string, object> GetAllAttributeValuesSafe(
1195
- ICustomAttributeProvider provider,
1195
+ this ICustomAttributeProvider provider,
1196
1196
  bool inherit = true
1197
1197
  )
1198
1198
  {
@@ -1222,7 +1222,7 @@ namespace WallstopStudios.UnityHelpers.Core.Helper
1222
1222
  }
1223
1223
 
1224
1224
  public static MethodInfo[] GetMethodsWithAttributeSafe<TAttribute>(
1225
- Type type,
1225
+ this Type type,
1226
1226
  bool inherit = true
1227
1227
  )
1228
1228
  where TAttribute : Attribute
@@ -1251,7 +1251,7 @@ namespace WallstopStudios.UnityHelpers.Core.Helper
1251
1251
  }
1252
1252
 
1253
1253
  public static PropertyInfo[] GetPropertiesWithAttributeSafe<TAttribute>(
1254
- Type type,
1254
+ this Type type,
1255
1255
  bool inherit = true
1256
1256
  )
1257
1257
  where TAttribute : Attribute
@@ -1280,7 +1280,7 @@ namespace WallstopStudios.UnityHelpers.Core.Helper
1280
1280
  }
1281
1281
 
1282
1282
  public static FieldInfo[] GetFieldsWithAttributeSafe<TAttribute>(
1283
- Type type,
1283
+ this Type type,
1284
1284
  bool inherit = true
1285
1285
  )
1286
1286
  where TAttribute : Attribute
@@ -8,16 +8,25 @@ namespace WallstopStudios.UnityHelpers.Utils
8
8
  using System.Collections.Generic;
9
9
  using System.Text;
10
10
  using UnityEngine;
11
- using WallstopStudios.UnityHelpers.Core.Extension;
12
11
  #if !SINGLE_THREADED
13
12
  using System.Threading;
14
13
  using System.Collections.Concurrent;
14
+ #else
15
+ using WallstopStudios.UnityHelpers.Core.Extension;
15
16
  #endif
16
17
  public static class Buffers
17
18
  {
19
+ #if SINGLE_THREADED
18
20
  private static readonly Dictionary<float, WaitForSeconds> WaitForSeconds = new();
19
21
  private static readonly Dictionary<float, WaitForSecondsRealtime> WaitForSecondsRealtime =
20
22
  new();
23
+ #else
24
+ private static readonly ConcurrentDictionary<float, WaitForSeconds> WaitForSeconds = new();
25
+ private static readonly ConcurrentDictionary<
26
+ float,
27
+ WaitForSecondsRealtime
28
+ > WaitForSecondsRealtime = new();
29
+ #endif
21
30
 
22
31
  public static readonly WaitForFixedUpdate WaitForFixedUpdate = new();
23
32
  public static readonly WaitForEndOfFrame WaitForEndOfFrame = new();
@@ -110,7 +119,12 @@ namespace WallstopStudios.UnityHelpers.Utils
110
119
 
111
120
  public PooledResource<T> Get()
112
121
  {
113
- if (!_pool.TryPop(out T value))
122
+ return Get(out _);
123
+ }
124
+
125
+ public PooledResource<T> Get(out T value)
126
+ {
127
+ if (!_pool.TryPop(out value))
114
128
  {
115
129
  value = _producer();
116
130
  }
@@ -168,7 +182,12 @@ namespace WallstopStudios.UnityHelpers.Utils
168
182
 
169
183
  public PooledResource<T> Get()
170
184
  {
171
- if (!_pool.TryPop(out T value))
185
+ return Get(out _);
186
+ }
187
+
188
+ public PooledResource<T> Get(out T value)
189
+ {
190
+ if (!_pool.TryPop(out value))
172
191
  {
173
192
  value = _producer();
174
193
  }
@@ -200,6 +219,11 @@ namespace WallstopStudios.UnityHelpers.Utils
200
219
  private static readonly Action<T[]> _onDispose = Release;
201
220
 
202
221
  public static PooledResource<T[]> Get(int size)
222
+ {
223
+ return Get(size, out _);
224
+ }
225
+
226
+ public static PooledResource<T[]> Get(int size, out T[] value)
203
227
  {
204
228
  switch (size)
205
229
  {
@@ -213,7 +237,8 @@ namespace WallstopStudios.UnityHelpers.Utils
213
237
  }
214
238
  case 0:
215
239
  {
216
- return new PooledResource<T[]>(Array.Empty<T>(), _ => { });
240
+ value = Array.Empty<T>();
241
+ return new PooledResource<T[]>(value, _ => { });
217
242
  }
218
243
  }
219
244
 
@@ -225,13 +250,14 @@ namespace WallstopStudios.UnityHelpers.Utils
225
250
 
226
251
  if (pool.Count == 0)
227
252
  {
228
- return new PooledResource<T[]>(new T[size], _onDispose);
253
+ value = new T[size];
254
+ return new PooledResource<T[]>(value, _onDispose);
229
255
  }
230
256
 
231
257
  int lastIndex = pool.Count - 1;
232
- T[] instance = pool[lastIndex];
258
+ value = pool[lastIndex];
233
259
  pool.RemoveAt(lastIndex);
234
- return new PooledResource<T[]>(instance, _onDispose);
260
+ return new PooledResource<T[]>(value, _onDispose);
235
261
  }
236
262
 
237
263
  private static void Release(T[] resource)
@@ -253,6 +279,11 @@ namespace WallstopStudios.UnityHelpers.Utils
253
279
  private static readonly Action<T[]> _onRelease = Release;
254
280
 
255
281
  public static PooledResource<T[]> Get(int size)
282
+ {
283
+ return Get(size, out _);
284
+ }
285
+
286
+ public static PooledResource<T[]> Get(int size, out T[] value)
256
287
  {
257
288
  switch (size)
258
289
  {
@@ -266,17 +297,18 @@ namespace WallstopStudios.UnityHelpers.Utils
266
297
  }
267
298
  case 0:
268
299
  {
269
- return new PooledResource<T[]>(Array.Empty<T>(), _ => { });
300
+ value = Array.Empty<T>();
301
+ return new PooledResource<T[]>(value, _ => { });
270
302
  }
271
303
  }
272
304
 
273
305
  ConcurrentStack<T[]> result = _pool.GetOrAdd(size, _ => new ConcurrentStack<T[]>());
274
- if (!result.TryPop(out T[] array))
306
+ if (!result.TryPop(out value))
275
307
  {
276
- array = new T[size];
308
+ value = new T[size];
277
309
  }
278
310
 
279
- return new PooledResource<T[]>(array, _onRelease);
311
+ return new PooledResource<T[]>(value, _onRelease);
280
312
  }
281
313
 
282
314
  private static void Release(T[] resource)
@@ -296,6 +328,11 @@ namespace WallstopStudios.UnityHelpers.Utils
296
328
  private static readonly Action<T[]> _onRelease = Release;
297
329
 
298
330
  public static PooledResource<T[]> Get(int size)
331
+ {
332
+ return Get(size, out _);
333
+ }
334
+
335
+ public static PooledResource<T[]> Get(int size, out T[] value)
299
336
  {
300
337
  switch (size)
301
338
  {
@@ -309,7 +346,8 @@ namespace WallstopStudios.UnityHelpers.Utils
309
346
  }
310
347
  case 0:
311
348
  {
312
- return new PooledResource<T[]>(Array.Empty<T>(), _ => { });
349
+ value = Array.Empty<T>();
350
+ return new PooledResource<T[]>(value, _ => { });
313
351
  }
314
352
  }
315
353
 
@@ -325,12 +363,12 @@ namespace WallstopStudios.UnityHelpers.Utils
325
363
  _pool[size] = pool;
326
364
  }
327
365
 
328
- if (!pool.TryPop(out T[] instance))
366
+ if (!pool.TryPop(out value))
329
367
  {
330
- instance = new T[size];
368
+ value = new T[size];
331
369
  }
332
370
 
333
- return new PooledResource<T[]>(instance, _onRelease);
371
+ return new PooledResource<T[]>(value, _onRelease);
334
372
  }
335
373
 
336
374
  private static void Release(T[] resource)
@@ -346,6 +384,11 @@ namespace WallstopStudios.UnityHelpers.Utils
346
384
  private static readonly Action<T[]> _onRelease = Release;
347
385
 
348
386
  public static PooledResource<T[]> Get(int size)
387
+ {
388
+ return Get(size, out _);
389
+ }
390
+
391
+ public static PooledResource<T[]> Get(int size, out T[] value)
349
392
  {
350
393
  switch (size)
351
394
  {
@@ -359,7 +402,8 @@ namespace WallstopStudios.UnityHelpers.Utils
359
402
  }
360
403
  case 0:
361
404
  {
362
- return new PooledResource<T[]>(Array.Empty<T>(), _ => { });
405
+ value = Array.Empty<T>();
406
+ return new PooledResource<T[]>(value, _ => { });
363
407
  }
364
408
  }
365
409
 
@@ -465,12 +509,12 @@ namespace WallstopStudios.UnityHelpers.Utils
465
509
  }
466
510
  }
467
511
 
468
- if (!pool.TryPop(out T[] instance))
512
+ if (!pool.TryPop(out value))
469
513
  {
470
- instance = new T[size];
514
+ value = new T[size];
471
515
  }
472
516
 
473
- return new PooledResource<T[]>(instance, _onRelease);
517
+ return new PooledResource<T[]>(value, _onRelease);
474
518
  }
475
519
 
476
520
  private static void Release(T[] resource)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "com.wallstop-studios.unity-helpers",
3
- "version": "2.0.0-rc81.2",
3
+ "version": "2.0.0-rc81.4",
4
4
  "displayName": "Unity Helpers",
5
5
  "description": "Various Unity Helper Library",
6
6
  "dependencies": {},