com.wallstop-studios.unity-helpers 2.0.0-rc44 → 2.0.0-rc46
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/Runtime/Core/DataStructure/CyclicBuffer.cs +1 -3
- package/Runtime/Core/DataStructure/KDTree.cs +10 -8
- package/Runtime/Core/DataStructure/QuadTree.cs +16 -8
- package/Runtime/Core/DataStructure/RTree.cs +18 -8
- package/Runtime/Core/DataStructure/StringWrapper.cs +4 -4
- package/Runtime/Core/DataStructure/TimedCache.cs +20 -5
- package/Runtime/Core/Extension/IListExtensions.cs +17 -0
- package/Runtime/Core/Helper/FormattingHelpers.cs +5 -5
- package/Runtime/Core/Helper/Objects.cs +2 -2
- package/Runtime/Core/Helper/ReflectionHelpers.cs +156 -1
- package/Runtime/Core/Helper/SpriteHelpers.cs +7 -52
- package/Runtime/Core/Helper/WallMath.cs +5 -5
- package/Runtime/Utils/RuntimeSingleton.cs +13 -5
- package/Tests/Runtime/Extensions/IListExtensionTests.cs +28 -0
- package/Tests/Runtime/Helper/ArrayConverterTests.cs +3 -3
- package/Tests/Runtime/Helper/FormattingHelperTests.cs +129 -0
- package/Tests/Runtime/Helper/FormattingHelperTests.cs.meta +3 -0
- package/Tests/Runtime/Helper/ObjectHelperTests.cs +2 -2
- package/Tests/Runtime/Helper/ReflectionHelperTests.cs +356 -35
- package/Tests/Runtime/Helper/WallMathTests.cs +4 -4
- package/package.json +1 -1
|
@@ -12,7 +12,6 @@
|
|
|
12
12
|
{
|
|
13
13
|
public int Capacity { get; private set; }
|
|
14
14
|
public int Count { get; private set; }
|
|
15
|
-
public bool IsReadOnly => false;
|
|
16
15
|
|
|
17
16
|
private readonly List<T> _buffer;
|
|
18
17
|
private int _position;
|
|
@@ -52,7 +51,7 @@
|
|
|
52
51
|
{
|
|
53
52
|
for (int i = 0; i < Count; ++i)
|
|
54
53
|
{
|
|
55
|
-
// No need for
|
|
54
|
+
// No need for bound check, we're safe
|
|
56
55
|
yield return _buffer[AdjustedIndexFor(i)];
|
|
57
56
|
}
|
|
58
57
|
}
|
|
@@ -87,7 +86,6 @@
|
|
|
87
86
|
|
|
88
87
|
public void Clear()
|
|
89
88
|
{
|
|
90
|
-
/* Simply reset state */
|
|
91
89
|
Count = 0;
|
|
92
90
|
_position = 0;
|
|
93
91
|
_buffer.Clear();
|
|
@@ -272,19 +272,21 @@
|
|
|
272
272
|
}
|
|
273
273
|
}
|
|
274
274
|
|
|
275
|
-
|
|
275
|
+
foreach (T element in nearestNeighborsSet)
|
|
276
|
+
{
|
|
277
|
+
nearestNeighbors.Add(element);
|
|
278
|
+
}
|
|
276
279
|
if (count < nearestNeighbors.Count)
|
|
277
280
|
{
|
|
281
|
+
Vector2 localPosition = position;
|
|
278
282
|
nearestNeighbors.Sort(NearestComparison);
|
|
279
283
|
nearestNeighbors.RemoveRange(count, nearestNeighbors.Count - count);
|
|
280
|
-
}
|
|
281
284
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
);
|
|
285
|
+
int NearestComparison(T lhs, T rhs) =>
|
|
286
|
+
(_elementTransformer(lhs) - localPosition).sqrMagnitude.CompareTo(
|
|
287
|
+
(_elementTransformer(rhs) - localPosition).sqrMagnitude
|
|
288
|
+
);
|
|
289
|
+
}
|
|
288
290
|
}
|
|
289
291
|
}
|
|
290
292
|
}
|
|
@@ -231,11 +231,15 @@
|
|
|
231
231
|
HashSet<T> nearestNeighborsSet = nearestNeighborBuffer ?? new HashSet<T>(count);
|
|
232
232
|
nearestNeighborsSet.Clear();
|
|
233
233
|
|
|
234
|
+
Comparison<QuadTreeNode<T>> comparison = Comparison;
|
|
234
235
|
while (!current.isTerminal)
|
|
235
236
|
{
|
|
236
237
|
childrenCopy.Clear();
|
|
237
|
-
|
|
238
|
-
|
|
238
|
+
foreach (QuadTreeNode<T> child in current.children)
|
|
239
|
+
{
|
|
240
|
+
childrenCopy.Add(child);
|
|
241
|
+
}
|
|
242
|
+
childrenCopy.Sort(comparison);
|
|
239
243
|
for (int i = childrenCopy.Count - 1; 0 <= i; --i)
|
|
240
244
|
{
|
|
241
245
|
stack.Push(childrenCopy[i]);
|
|
@@ -256,11 +260,20 @@
|
|
|
256
260
|
}
|
|
257
261
|
}
|
|
258
262
|
|
|
259
|
-
|
|
263
|
+
foreach (T element in nearestNeighborsSet)
|
|
264
|
+
{
|
|
265
|
+
nearestNeighbors.Add(element);
|
|
266
|
+
}
|
|
260
267
|
if (count < nearestNeighbors.Count)
|
|
261
268
|
{
|
|
269
|
+
Vector2 localPosition = position;
|
|
262
270
|
nearestNeighbors.Sort(NearestComparison);
|
|
263
271
|
nearestNeighbors.RemoveRange(count, nearestNeighbors.Count - count);
|
|
272
|
+
|
|
273
|
+
int NearestComparison(T lhs, T rhs) =>
|
|
274
|
+
(_elementTransformer(lhs) - localPosition).sqrMagnitude.CompareTo(
|
|
275
|
+
(_elementTransformer(rhs) - localPosition).sqrMagnitude
|
|
276
|
+
);
|
|
264
277
|
}
|
|
265
278
|
|
|
266
279
|
return;
|
|
@@ -269,11 +282,6 @@
|
|
|
269
282
|
((Vector2)lhs.boundary.center - position).sqrMagnitude.CompareTo(
|
|
270
283
|
((Vector2)rhs.boundary.center - position).sqrMagnitude
|
|
271
284
|
);
|
|
272
|
-
|
|
273
|
-
int NearestComparison(T lhs, T rhs) =>
|
|
274
|
-
(_elementTransformer(lhs) - position).sqrMagnitude.CompareTo(
|
|
275
|
-
(_elementTransformer(rhs) - position).sqrMagnitude
|
|
276
|
-
);
|
|
277
285
|
}
|
|
278
286
|
}
|
|
279
287
|
}
|
|
@@ -288,11 +288,15 @@
|
|
|
288
288
|
HashSet<T> nearestNeighborsSet = nearestNeighborsBuffer ?? new HashSet<T>(count);
|
|
289
289
|
nearestNeighborsSet.Clear();
|
|
290
290
|
|
|
291
|
+
Comparison<RTreeNode<T>> comparison = Comparison;
|
|
291
292
|
while (!current.isTerminal)
|
|
292
293
|
{
|
|
293
294
|
childrenCopy.Clear();
|
|
294
|
-
|
|
295
|
-
|
|
295
|
+
foreach (RTreeNode<T> child in current.children)
|
|
296
|
+
{
|
|
297
|
+
childrenCopy.Add(child);
|
|
298
|
+
}
|
|
299
|
+
childrenCopy.Sort(comparison);
|
|
296
300
|
for (int i = childrenCopy.Count - 1; 0 <= i; --i)
|
|
297
301
|
{
|
|
298
302
|
stack.Push(childrenCopy[i]);
|
|
@@ -313,11 +317,22 @@
|
|
|
313
317
|
}
|
|
314
318
|
}
|
|
315
319
|
|
|
316
|
-
|
|
320
|
+
foreach (T element in nearestNeighborsSet)
|
|
321
|
+
{
|
|
322
|
+
nearestNeighbors.Add(element);
|
|
323
|
+
}
|
|
317
324
|
if (count < nearestNeighbors.Count)
|
|
318
325
|
{
|
|
326
|
+
Vector2 localPosition = position;
|
|
319
327
|
nearestNeighbors.Sort(NearestComparison);
|
|
320
328
|
nearestNeighbors.RemoveRange(count, nearestNeighbors.Count - count);
|
|
329
|
+
|
|
330
|
+
int NearestComparison(T lhs, T rhs) =>
|
|
331
|
+
(
|
|
332
|
+
(Vector2)_elementTransformer(lhs).center - localPosition
|
|
333
|
+
).sqrMagnitude.CompareTo(
|
|
334
|
+
((Vector2)_elementTransformer(rhs).center - localPosition).sqrMagnitude
|
|
335
|
+
);
|
|
321
336
|
}
|
|
322
337
|
|
|
323
338
|
return;
|
|
@@ -326,11 +341,6 @@
|
|
|
326
341
|
((Vector2)lhs.boundary.center - position).sqrMagnitude.CompareTo(
|
|
327
342
|
((Vector2)rhs.boundary.center - position).sqrMagnitude
|
|
328
343
|
);
|
|
329
|
-
|
|
330
|
-
int NearestComparison(T lhs, T rhs) =>
|
|
331
|
-
((Vector2)_elementTransformer(lhs).center - position).sqrMagnitude.CompareTo(
|
|
332
|
-
((Vector2)_elementTransformer(rhs).center - position).sqrMagnitude
|
|
333
|
-
);
|
|
334
344
|
}
|
|
335
345
|
}
|
|
336
346
|
}
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
private StringWrapper(string value)
|
|
20
20
|
{
|
|
21
21
|
this.value = value;
|
|
22
|
-
_hashCode = value
|
|
22
|
+
_hashCode = value.GetHashCode();
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
public static StringWrapper Get(string value)
|
|
@@ -27,9 +27,9 @@
|
|
|
27
27
|
return Cache.GetOrAdd(value, key => new StringWrapper(key));
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
public static
|
|
30
|
+
public static bool Remove(string value)
|
|
31
31
|
{
|
|
32
|
-
|
|
32
|
+
return Cache.TryRemove(value, out _);
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
public bool Equals(StringWrapper other)
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
return false;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
return string.Equals(value, other.value);
|
|
52
|
+
return string.Equals(value, other.value, StringComparison.Ordinal);
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
public int CompareTo(StringWrapper other)
|
|
@@ -11,10 +11,23 @@
|
|
|
11
11
|
{
|
|
12
12
|
get
|
|
13
13
|
{
|
|
14
|
-
if (!_lastRead.HasValue
|
|
14
|
+
if (!_lastRead.HasValue)
|
|
15
15
|
{
|
|
16
16
|
Reset();
|
|
17
17
|
}
|
|
18
|
+
else if (
|
|
19
|
+
Helpers.HasEnoughTimePassed(
|
|
20
|
+
_lastRead.Value,
|
|
21
|
+
_cacheTtl + (_shouldUseJitter && !_usedJitter ? _jitterAmount : 0f)
|
|
22
|
+
)
|
|
23
|
+
)
|
|
24
|
+
{
|
|
25
|
+
if (_shouldUseJitter)
|
|
26
|
+
{
|
|
27
|
+
_usedJitter = true;
|
|
28
|
+
}
|
|
29
|
+
Reset();
|
|
30
|
+
}
|
|
18
31
|
|
|
19
32
|
return _value;
|
|
20
33
|
}
|
|
@@ -26,6 +39,10 @@
|
|
|
26
39
|
private float? _lastRead;
|
|
27
40
|
private T _value;
|
|
28
41
|
|
|
42
|
+
private bool _usedJitter;
|
|
43
|
+
private readonly bool _shouldUseJitter;
|
|
44
|
+
private readonly float _jitterAmount;
|
|
45
|
+
|
|
29
46
|
public TimedCache(Func<T> valueProducer, float cacheTtl, bool useJitter = false)
|
|
30
47
|
{
|
|
31
48
|
_valueProducer =
|
|
@@ -36,10 +53,8 @@
|
|
|
36
53
|
}
|
|
37
54
|
|
|
38
55
|
_cacheTtl = cacheTtl;
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
_cacheTtl += PRNG.Instance.NextFloat(_cacheTtl);
|
|
42
|
-
}
|
|
56
|
+
_shouldUseJitter = useJitter;
|
|
57
|
+
_jitterAmount = useJitter ? PRNG.Instance.NextFloat(0f, cacheTtl) : 0f;
|
|
43
58
|
}
|
|
44
59
|
|
|
45
60
|
public void Reset()
|
|
@@ -85,5 +85,22 @@
|
|
|
85
85
|
list[index] = last;
|
|
86
86
|
list.RemoveAt(lastIndex);
|
|
87
87
|
}
|
|
88
|
+
|
|
89
|
+
public static void InsertionSort<T, TComparer>(this IList<T> array, TComparer comparer)
|
|
90
|
+
where TComparer : struct, IComparer<T>
|
|
91
|
+
{
|
|
92
|
+
int arrayCount = array.Count;
|
|
93
|
+
for (int i = 1; i < arrayCount; ++i)
|
|
94
|
+
{
|
|
95
|
+
T key = array[i];
|
|
96
|
+
int j = i - 1;
|
|
97
|
+
while (j >= 0 && comparer.Compare(array[j], key) > 0)
|
|
98
|
+
{
|
|
99
|
+
array[j + 1] = array[j];
|
|
100
|
+
j--;
|
|
101
|
+
}
|
|
102
|
+
array[j + 1] = key;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
88
105
|
}
|
|
89
106
|
}
|
|
@@ -4,19 +4,19 @@
|
|
|
4
4
|
|
|
5
5
|
public static class FormattingHelpers
|
|
6
6
|
{
|
|
7
|
+
private static readonly string[] ByteSizes = { "B", "KB", "MB", "GB", "TB", "PB", "EB" };
|
|
8
|
+
|
|
7
9
|
public static string FormatBytes(long bytes)
|
|
8
10
|
{
|
|
9
|
-
|
|
11
|
+
bytes = Math.Max(0L, bytes);
|
|
10
12
|
double len = bytes;
|
|
11
13
|
int order = 0;
|
|
12
14
|
|
|
13
|
-
bytes = Math.Max(0, bytes);
|
|
14
|
-
|
|
15
15
|
const int byteInChunk = 1024;
|
|
16
16
|
while (byteInChunk <= len)
|
|
17
17
|
{
|
|
18
18
|
len /= byteInChunk;
|
|
19
|
-
if (order <
|
|
19
|
+
if (order < ByteSizes.Length - 1)
|
|
20
20
|
{
|
|
21
21
|
++order;
|
|
22
22
|
}
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
return $"{len:0.##} {
|
|
29
|
+
return $"{len:0.##} {ByteSizes[order]}";
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
}
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
|
|
8
8
|
public static class Objects
|
|
9
9
|
{
|
|
10
|
-
private const int HashBase =
|
|
11
|
-
private const int HashMultiplier =
|
|
10
|
+
private const int HashBase = 5556137;
|
|
11
|
+
private const int HashMultiplier = 95785853;
|
|
12
12
|
|
|
13
13
|
public static T FromWeakReference<T>(WeakReference weakReference)
|
|
14
14
|
where T : class
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
public static Array CreateArray(Type type, int length)
|
|
21
21
|
{
|
|
22
22
|
return ArrayCreators
|
|
23
|
+
// ReSharper disable once ConvertClosureToMethodGroup
|
|
23
24
|
.GetOrAdd(type, elementType => GetArrayCreator(elementType))
|
|
24
25
|
.Invoke(length);
|
|
25
26
|
}
|
|
@@ -28,6 +29,7 @@
|
|
|
28
29
|
public static IList CreateList(Type elementType, int length)
|
|
29
30
|
{
|
|
30
31
|
return ListWithCapacityCreators
|
|
32
|
+
// ReSharper disable once ConvertClosureToMethodGroup
|
|
31
33
|
.GetOrAdd(elementType, type => GetListWithCapacityCreator(type))
|
|
32
34
|
.Invoke(length);
|
|
33
35
|
}
|
|
@@ -35,6 +37,7 @@
|
|
|
35
37
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
36
38
|
public static IList CreateList(Type elementType)
|
|
37
39
|
{
|
|
40
|
+
// ReSharper disable once ConvertClosureToMethodGroup
|
|
38
41
|
return ListCreators.GetOrAdd(elementType, type => GetListCreator(type)).Invoke();
|
|
39
42
|
}
|
|
40
43
|
|
|
@@ -44,7 +47,7 @@
|
|
|
44
47
|
return field.GetValue;
|
|
45
48
|
#else
|
|
46
49
|
DynamicMethod dynamicMethod = new(
|
|
47
|
-
$"Get{
|
|
50
|
+
$"Get{field.DeclaringType.Name}{field.Name}",
|
|
48
51
|
typeof(object),
|
|
49
52
|
new[] { typeof(object) },
|
|
50
53
|
field.DeclaringType,
|
|
@@ -72,6 +75,41 @@
|
|
|
72
75
|
#endif
|
|
73
76
|
}
|
|
74
77
|
|
|
78
|
+
public static Func<object> GetStaticFieldGetter(FieldInfo field)
|
|
79
|
+
{
|
|
80
|
+
if (!field.IsStatic)
|
|
81
|
+
{
|
|
82
|
+
throw new ArgumentException(nameof(field));
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
#if WEB_GL
|
|
86
|
+
return () => field.GetValue(null);
|
|
87
|
+
#else
|
|
88
|
+
DynamicMethod dynamicMethod = new(
|
|
89
|
+
$"Get{field.DeclaringType.Name}{field.Name}",
|
|
90
|
+
typeof(object),
|
|
91
|
+
Type.EmptyTypes, // No parameters for static fields
|
|
92
|
+
field.DeclaringType,
|
|
93
|
+
true
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
ILGenerator il = dynamicMethod.GetILGenerator();
|
|
97
|
+
|
|
98
|
+
// Load the static field
|
|
99
|
+
il.Emit(OpCodes.Ldsfld, field);
|
|
100
|
+
|
|
101
|
+
// If the field's type is a value type, box it.
|
|
102
|
+
if (field.FieldType.IsValueType)
|
|
103
|
+
{
|
|
104
|
+
il.Emit(OpCodes.Box, field.FieldType);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
il.Emit(OpCodes.Ret);
|
|
108
|
+
|
|
109
|
+
return (Func<object>)dynamicMethod.CreateDelegate(typeof(Func<object>));
|
|
110
|
+
#endif
|
|
111
|
+
}
|
|
112
|
+
|
|
75
113
|
public static Func<TInstance, TValue> GetFieldGetter<TInstance, TValue>(FieldInfo field)
|
|
76
114
|
{
|
|
77
115
|
#if WEB_GL
|
|
@@ -142,6 +180,59 @@
|
|
|
142
180
|
#endif
|
|
143
181
|
}
|
|
144
182
|
|
|
183
|
+
public static Func<TValue> GetStaticFieldGetter<TValue>(FieldInfo field)
|
|
184
|
+
{
|
|
185
|
+
if (!field.IsStatic)
|
|
186
|
+
{
|
|
187
|
+
throw new ArgumentException(nameof(field));
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
#if WEB_GL
|
|
191
|
+
return Getter;
|
|
192
|
+
TValue Getter()
|
|
193
|
+
{
|
|
194
|
+
return (TValue)field.GetValue(null);
|
|
195
|
+
}
|
|
196
|
+
#else
|
|
197
|
+
DynamicMethod dynamicMethod = new(
|
|
198
|
+
$"GetGenericStatic{field.DeclaringType.Name}{field.Name}",
|
|
199
|
+
typeof(TValue),
|
|
200
|
+
Type.EmptyTypes, // no parameters needed for static fields
|
|
201
|
+
field.DeclaringType,
|
|
202
|
+
true
|
|
203
|
+
);
|
|
204
|
+
|
|
205
|
+
ILGenerator il = dynamicMethod.GetILGenerator();
|
|
206
|
+
|
|
207
|
+
// Load the static field.
|
|
208
|
+
il.Emit(OpCodes.Ldsfld, field);
|
|
209
|
+
|
|
210
|
+
// Handle conversion from the field type to TValue.
|
|
211
|
+
if (field.FieldType.IsValueType)
|
|
212
|
+
{
|
|
213
|
+
if (!typeof(TValue).IsValueType)
|
|
214
|
+
{
|
|
215
|
+
il.Emit(OpCodes.Box, field.FieldType);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
else
|
|
219
|
+
{
|
|
220
|
+
if (typeof(TValue).IsValueType)
|
|
221
|
+
{
|
|
222
|
+
il.Emit(OpCodes.Unbox_Any, typeof(TValue));
|
|
223
|
+
}
|
|
224
|
+
else if (typeof(TValue) != field.FieldType)
|
|
225
|
+
{
|
|
226
|
+
il.Emit(OpCodes.Castclass, typeof(TValue));
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
il.Emit(OpCodes.Ret);
|
|
231
|
+
|
|
232
|
+
return (Func<TValue>)dynamicMethod.CreateDelegate(typeof(Func<TValue>));
|
|
233
|
+
#endif
|
|
234
|
+
}
|
|
235
|
+
|
|
145
236
|
public static FieldSetter<TInstance, TValue> GetFieldSetter<TInstance, TValue>(
|
|
146
237
|
FieldInfo field
|
|
147
238
|
)
|
|
@@ -184,6 +275,36 @@
|
|
|
184
275
|
#endif
|
|
185
276
|
}
|
|
186
277
|
|
|
278
|
+
public static Action<TValue> GetStaticFieldSetter<TValue>(FieldInfo field)
|
|
279
|
+
{
|
|
280
|
+
if (!field.IsStatic)
|
|
281
|
+
{
|
|
282
|
+
throw new ArgumentException(nameof(field));
|
|
283
|
+
}
|
|
284
|
+
#if WEB_GL
|
|
285
|
+
return Setter;
|
|
286
|
+
void Setter(TValue newValue)
|
|
287
|
+
{
|
|
288
|
+
field.SetValue(null, newValue);
|
|
289
|
+
}
|
|
290
|
+
#else
|
|
291
|
+
DynamicMethod dynamicMethod = new(
|
|
292
|
+
$"SetFieldGenericStatic{field.DeclaringType.Name}{field.Name}",
|
|
293
|
+
typeof(void),
|
|
294
|
+
new[] { typeof(TValue) },
|
|
295
|
+
field.Module,
|
|
296
|
+
true
|
|
297
|
+
);
|
|
298
|
+
|
|
299
|
+
ILGenerator il = dynamicMethod.GetILGenerator();
|
|
300
|
+
il.Emit(OpCodes.Ldarg_0);
|
|
301
|
+
il.Emit(OpCodes.Stsfld, field);
|
|
302
|
+
il.Emit(OpCodes.Ret);
|
|
303
|
+
|
|
304
|
+
return (Action<TValue>)dynamicMethod.CreateDelegate(typeof(Action<TValue>));
|
|
305
|
+
#endif
|
|
306
|
+
}
|
|
307
|
+
|
|
187
308
|
public static Action<object, object> GetFieldSetter(FieldInfo field)
|
|
188
309
|
{
|
|
189
310
|
#if WEB_GL
|
|
@@ -217,6 +338,40 @@
|
|
|
217
338
|
#endif
|
|
218
339
|
}
|
|
219
340
|
|
|
341
|
+
public static Action<object> GetStaticFieldSetter(FieldInfo field)
|
|
342
|
+
{
|
|
343
|
+
if (!field.IsStatic)
|
|
344
|
+
{
|
|
345
|
+
throw new ArgumentException(nameof(field));
|
|
346
|
+
}
|
|
347
|
+
#if WEB_GL
|
|
348
|
+
return value => field.SetValue(null, value);
|
|
349
|
+
#else
|
|
350
|
+
DynamicMethod dynamicMethod = new(
|
|
351
|
+
$"SetFieldStatic{field.DeclaringType.Name}{field.Name}",
|
|
352
|
+
null,
|
|
353
|
+
new[] { typeof(object) },
|
|
354
|
+
field.DeclaringType.Module,
|
|
355
|
+
true
|
|
356
|
+
);
|
|
357
|
+
|
|
358
|
+
ILGenerator il = dynamicMethod.GetILGenerator();
|
|
359
|
+
|
|
360
|
+
// Load the new value (argument 0)
|
|
361
|
+
il.Emit(OpCodes.Ldarg_0);
|
|
362
|
+
// Convert the object to the field's type (unbox or cast as needed)
|
|
363
|
+
il.Emit(
|
|
364
|
+
field.FieldType.IsValueType ? OpCodes.Unbox_Any : OpCodes.Castclass,
|
|
365
|
+
field.FieldType
|
|
366
|
+
);
|
|
367
|
+
// Set the static field
|
|
368
|
+
il.Emit(OpCodes.Stsfld, field);
|
|
369
|
+
il.Emit(OpCodes.Ret);
|
|
370
|
+
|
|
371
|
+
return (Action<object>)dynamicMethod.CreateDelegate(typeof(Action<object>));
|
|
372
|
+
#endif
|
|
373
|
+
}
|
|
374
|
+
|
|
220
375
|
public static Func<int, Array> GetArrayCreator(Type elementType)
|
|
221
376
|
{
|
|
222
377
|
#if WEB_GL
|
|
@@ -3,13 +3,12 @@
|
|
|
3
3
|
using Extension;
|
|
4
4
|
using UnityEditor;
|
|
5
5
|
using UnityEngine;
|
|
6
|
-
using Utils;
|
|
7
6
|
|
|
8
7
|
public static class SpriteHelpers
|
|
9
8
|
{
|
|
10
9
|
public static void MakeReadable(this Texture2D texture)
|
|
11
10
|
{
|
|
12
|
-
if (texture.isReadable)
|
|
11
|
+
if (texture == null || texture.isReadable)
|
|
13
12
|
{
|
|
14
13
|
return;
|
|
15
14
|
}
|
|
@@ -29,58 +28,14 @@
|
|
|
29
28
|
return;
|
|
30
29
|
}
|
|
31
30
|
|
|
32
|
-
tImporter.isReadable
|
|
33
|
-
EditorUtility.SetDirty(tImporter);
|
|
34
|
-
tImporter.SaveAndReimport();
|
|
35
|
-
EditorUtility.SetDirty(texture);
|
|
36
|
-
#endif
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
public static void SetSpritePivot(string fullSpritePath, Vector2 pivot)
|
|
40
|
-
{
|
|
41
|
-
#if UNITY_EDITOR
|
|
42
|
-
SetSpritePivot(AssetImporter.GetAtPath(fullSpritePath) as TextureImporter, pivot);
|
|
43
|
-
#endif
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
public static void SetSpritePivot(Sprite sprite, Vector2 pivot)
|
|
47
|
-
{
|
|
48
|
-
#if UNITY_EDITOR
|
|
49
|
-
SetSpritePivot(
|
|
50
|
-
AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(sprite)) as TextureImporter,
|
|
51
|
-
pivot
|
|
52
|
-
);
|
|
53
|
-
#endif
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
#if UNITY_EDITOR
|
|
57
|
-
public static void SetSpritePivot(TextureImporter textureImporter, Vector2 pivot)
|
|
58
|
-
{
|
|
59
|
-
if (textureImporter == null)
|
|
31
|
+
if (!tImporter.isReadable)
|
|
60
32
|
{
|
|
61
|
-
|
|
33
|
+
tImporter.isReadable = true;
|
|
34
|
+
EditorUtility.SetDirty(tImporter);
|
|
35
|
+
tImporter.SaveAndReimport();
|
|
36
|
+
EditorUtility.SetDirty(texture);
|
|
62
37
|
}
|
|
63
|
-
|
|
64
|
-
TextureImporterSettings textureImportSettings = new TextureImporterSettings();
|
|
65
|
-
textureImporter.ReadTextureSettings(textureImportSettings);
|
|
66
|
-
textureImportSettings.spriteAlignment = (int)SpriteAlignment.Custom;
|
|
67
|
-
textureImportSettings.wrapMode = TextureWrapMode.Clamp;
|
|
68
|
-
textureImportSettings.filterMode = FilterMode.Trilinear;
|
|
69
|
-
textureImporter.SetTextureSettings(textureImportSettings);
|
|
70
|
-
|
|
71
|
-
TextureImporterPlatformSettings importerSettings = new TextureImporterPlatformSettings
|
|
72
|
-
{
|
|
73
|
-
resizeAlgorithm = TextureResizeAlgorithm.Bilinear,
|
|
74
|
-
maxTextureSize = SetTextureImportData.RegularTextureSize,
|
|
75
|
-
textureCompression = TextureImporterCompression.Compressed,
|
|
76
|
-
format = TextureImporterFormat.Automatic,
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
textureImporter.SetPlatformTextureSettings(importerSettings);
|
|
80
|
-
textureImporter.isReadable = true;
|
|
81
|
-
textureImporter.spritePivot = pivot;
|
|
82
|
-
textureImporter.SaveAndReimport();
|
|
83
|
-
}
|
|
84
38
|
#endif
|
|
39
|
+
}
|
|
85
40
|
}
|
|
86
41
|
}
|
|
@@ -125,12 +125,12 @@
|
|
|
125
125
|
if (0 < direction.x)
|
|
126
126
|
{
|
|
127
127
|
float t2 = (max.x - center.x) / direction.x;
|
|
128
|
-
tMax =
|
|
128
|
+
tMax = Mathf.Min(tMax, t2);
|
|
129
129
|
}
|
|
130
130
|
else
|
|
131
131
|
{
|
|
132
132
|
float t1 = (min.x - center.x) / direction.x;
|
|
133
|
-
tMax =
|
|
133
|
+
tMax = Mathf.Min(tMax, t1);
|
|
134
134
|
}
|
|
135
135
|
}
|
|
136
136
|
|
|
@@ -139,12 +139,12 @@
|
|
|
139
139
|
if (direction.y > 0)
|
|
140
140
|
{
|
|
141
141
|
float t2 = (max.y - center.y) / direction.y;
|
|
142
|
-
tMax =
|
|
142
|
+
tMax = Mathf.Min(tMax, t2);
|
|
143
143
|
}
|
|
144
144
|
else
|
|
145
145
|
{
|
|
146
146
|
float t1 = (min.y - center.y) / direction.y;
|
|
147
|
-
tMax =
|
|
147
|
+
tMax = Mathf.Min(tMax, t1);
|
|
148
148
|
}
|
|
149
149
|
}
|
|
150
150
|
|
|
@@ -160,7 +160,7 @@
|
|
|
160
160
|
|
|
161
161
|
public static bool Approximately(this float lhs, float rhs, float tolerance = 0.045f)
|
|
162
162
|
{
|
|
163
|
-
return
|
|
163
|
+
return Mathf.Abs(lhs - rhs) <= tolerance;
|
|
164
164
|
}
|
|
165
165
|
}
|
|
166
166
|
}
|
|
@@ -45,12 +45,20 @@
|
|
|
45
45
|
|
|
46
46
|
protected virtual void Start()
|
|
47
47
|
{
|
|
48
|
-
if (_instance
|
|
48
|
+
if (_instance == null || _instance == this)
|
|
49
49
|
{
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
this.LogError($"Double singleton detected, {_instance.name} conflicts with {name}.");
|
|
54
|
+
gameObject.Destroy();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
protected virtual void OnDestroy()
|
|
58
|
+
{
|
|
59
|
+
if (_instance == this)
|
|
60
|
+
{
|
|
61
|
+
_instance = null;
|
|
54
62
|
}
|
|
55
63
|
}
|
|
56
64
|
}
|