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.
- package/Editor/PrefabChecker.cs +48 -24
- package/Runtime/Core/Attributes/ChildComponentAttribute.cs +37 -33
- package/Runtime/Core/Attributes/ParentComponent.cs +27 -18
- package/Runtime/Core/Attributes/SiblingComponentAttribute.cs +20 -10
- package/Runtime/Core/Extension/StringExtensions.cs +10 -0
- package/Runtime/Core/Helper/Helpers.cs +62 -14
- package/Runtime/Core/Helper/Partials/TransformHelpers.cs +16 -4
- package/Runtime/Core/Helper/ReflectionHelpers.cs +7 -7
- package/Runtime/Utils/Buffers.cs +63 -19
- package/package.json +1 -1
package/Editor/PrefabChecker.cs
CHANGED
|
@@ -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,
|
|
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
|
|
490
|
-
|
|
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
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
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 =
|
|
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.
|
|
527
|
+
if (components.Count != 0 || !buffer.Exists(c => c == null))
|
|
508
528
|
{
|
|
509
529
|
continue;
|
|
510
530
|
}
|
|
511
531
|
|
|
512
|
-
HashSet<GameObject
|
|
513
|
-
.
|
|
514
|
-
|
|
515
|
-
|
|
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.
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
693
|
-
|
|
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
|
-
(
|
|
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
|
-
.
|
|
43
|
-
|
|
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 (
|
|
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 (
|
|
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
|
-
|
|
64
|
-
|
|
65
|
-
|
|
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
|
-
|
|
82
|
+
attribute.includeInactive
|
|
73
83
|
)
|
|
74
84
|
)
|
|
75
85
|
{
|
|
76
|
-
|
|
86
|
+
cache.Add(childComponent);
|
|
77
87
|
}
|
|
78
88
|
}
|
|
79
89
|
|
|
80
|
-
foundChild = 0 <
|
|
90
|
+
foundChild = 0 < cache.Count;
|
|
81
91
|
|
|
82
92
|
Array correctTypedArray = ReflectionHelpers.CreateArray(
|
|
83
93
|
childComponentType,
|
|
84
|
-
|
|
94
|
+
cache.Count
|
|
85
95
|
);
|
|
86
|
-
Array.Copy(
|
|
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
|
-
|
|
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
|
-
!
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 && !
|
|
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
|
-
(
|
|
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
|
-
.
|
|
41
|
-
|
|
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 (
|
|
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 (
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 && !
|
|
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
|
-
(
|
|
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
|
-
.
|
|
40
|
-
|
|
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 (
|
|
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
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
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
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
721
|
-
|
|
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
|
|
57
|
-
|
|
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
|
|
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
|
|
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
|
package/Runtime/Utils/Buffers.cs
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
253
|
+
value = new T[size];
|
|
254
|
+
return new PooledResource<T[]>(value, _onDispose);
|
|
229
255
|
}
|
|
230
256
|
|
|
231
257
|
int lastIndex = pool.Count - 1;
|
|
232
|
-
|
|
258
|
+
value = pool[lastIndex];
|
|
233
259
|
pool.RemoveAt(lastIndex);
|
|
234
|
-
return new PooledResource<T[]>(
|
|
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
|
-
|
|
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
|
|
306
|
+
if (!result.TryPop(out value))
|
|
275
307
|
{
|
|
276
|
-
|
|
308
|
+
value = new T[size];
|
|
277
309
|
}
|
|
278
310
|
|
|
279
|
-
return new PooledResource<T[]>(
|
|
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
|
-
|
|
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
|
|
366
|
+
if (!pool.TryPop(out value))
|
|
329
367
|
{
|
|
330
|
-
|
|
368
|
+
value = new T[size];
|
|
331
369
|
}
|
|
332
370
|
|
|
333
|
-
return new PooledResource<T[]>(
|
|
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
|
-
|
|
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
|
|
512
|
+
if (!pool.TryPop(out value))
|
|
469
513
|
{
|
|
470
|
-
|
|
514
|
+
value = new T[size];
|
|
471
515
|
}
|
|
472
516
|
|
|
473
|
-
return new PooledResource<T[]>(
|
|
517
|
+
return new PooledResource<T[]>(value, _onRelease);
|
|
474
518
|
}
|
|
475
519
|
|
|
476
520
|
private static void Release(T[] resource)
|