com.wallstop-studios.unity-helpers 2.0.0-rc41 → 2.0.0-rc43
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/AnimationCopier.cs +1 -1
- package/Editor/AnimationCreator.cs +1 -1
- package/Editor/{EnsureTextureSizeWizard.cs → FitTextureSizeWizard.cs} +47 -15
- package/Editor/PrefabCheckWizard.cs +30 -25
- package/Editor/SpriteSettingsApplier.cs +130 -26
- package/Editor/TextureSettingsApplier.cs +7 -0
- package/Editor/WShowIfPropertyDrawer.cs +63 -0
- package/Editor/WShowIfPropertyDrawer.cs.meta +3 -0
- package/Runtime/Core/Attributes/WShowIfAttribute.cs +16 -0
- package/Runtime/Core/Attributes/WShowIfAttribute.cs.meta +3 -0
- package/Runtime/Core/Extension/ColorExtensions.cs +378 -87
- package/Runtime/Core/Extension/SerializedPropertyExtensions.cs +157 -0
- package/Runtime/Core/Extension/SerializedPropertyExtensions.cs.meta +3 -0
- package/Runtime/Core/Helper/Objects.cs +4 -2
- package/Runtime/Core/Helper/Partials/TransformHelpers.cs +2 -6
- package/Runtime/Core/Helper/StringInList.cs +1 -1
- package/Runtime/Core/Threading/SingleThreadedThreadPool.cs +44 -35
- package/Runtime/Utils/Buffers.cs +2 -1
- package/package.json +1 -1
- /package/Editor/{EnsureTextureSizeWizard.cs.meta → FitTextureSizeWizard.cs.meta} +0 -0
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
namespace UnityHelpers.Core.Extension
|
|
2
|
+
{
|
|
3
|
+
#if UNITY_EDITOR
|
|
4
|
+
using UnityEditor;
|
|
5
|
+
using System;
|
|
6
|
+
using System.Reflection;
|
|
7
|
+
|
|
8
|
+
public static class SerializedPropertyExtensions
|
|
9
|
+
{
|
|
10
|
+
/// <summary>
|
|
11
|
+
/// Gets the instance object that contains the given SerializedProperty.
|
|
12
|
+
/// </summary>
|
|
13
|
+
/// <param name="property">The SerializedProperty.</param>
|
|
14
|
+
/// <param name="fieldInfo">Outputs the FieldInfo of the referenced field.</param>
|
|
15
|
+
/// <returns>The instance object that owns the field.</returns>
|
|
16
|
+
public static object GetEnclosingObject(
|
|
17
|
+
this SerializedProperty property,
|
|
18
|
+
out FieldInfo fieldInfo
|
|
19
|
+
)
|
|
20
|
+
{
|
|
21
|
+
fieldInfo = null;
|
|
22
|
+
object obj = property.serializedObject.targetObject;
|
|
23
|
+
if (obj == null)
|
|
24
|
+
{
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
Type type = obj.GetType();
|
|
28
|
+
string[] pathParts = property.propertyPath.Split('.');
|
|
29
|
+
|
|
30
|
+
// Traverse the path but stop at the second-to-last field
|
|
31
|
+
for (int i = 0; i < pathParts.Length - 1; ++i)
|
|
32
|
+
{
|
|
33
|
+
string fieldName = pathParts[i];
|
|
34
|
+
|
|
35
|
+
if (string.Equals(fieldName, "Array", StringComparison.Ordinal))
|
|
36
|
+
{
|
|
37
|
+
// Move to "data[i]", no need to length-check, we're guarded above
|
|
38
|
+
|
|
39
|
+
++i;
|
|
40
|
+
if (
|
|
41
|
+
!int.TryParse(
|
|
42
|
+
pathParts[i]
|
|
43
|
+
.Replace("data[", string.Empty, StringComparison.Ordinal)
|
|
44
|
+
.Replace("]", string.Empty, StringComparison.Ordinal),
|
|
45
|
+
out int index
|
|
46
|
+
)
|
|
47
|
+
)
|
|
48
|
+
{
|
|
49
|
+
// Unexpected, die
|
|
50
|
+
fieldInfo = null;
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
obj = GetElementAtIndex(obj, index);
|
|
54
|
+
type = obj?.GetType();
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
fieldInfo = type?.GetField(
|
|
59
|
+
fieldName,
|
|
60
|
+
BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance
|
|
61
|
+
);
|
|
62
|
+
if (fieldInfo == null)
|
|
63
|
+
{
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Move deeper but stop before the last property in the path
|
|
68
|
+
if (i < pathParts.Length - 2)
|
|
69
|
+
{
|
|
70
|
+
obj = fieldInfo.GetValue(obj);
|
|
71
|
+
type = fieldInfo.FieldType;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return obj;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/// <summary>
|
|
79
|
+
/// Gets the FieldInfo and the instance object that owns the field for a given SerializedProperty.
|
|
80
|
+
/// </summary>
|
|
81
|
+
/// <param name="property">The SerializedProperty to reflect upon.</param>
|
|
82
|
+
/// <param name="fieldInfo">Outputs the FieldInfo of the referenced field.</param>
|
|
83
|
+
/// <returns>The instance object that owns the field.</returns>
|
|
84
|
+
public static object GetTargetObjectWithField(
|
|
85
|
+
this SerializedProperty property,
|
|
86
|
+
out FieldInfo fieldInfo
|
|
87
|
+
)
|
|
88
|
+
{
|
|
89
|
+
fieldInfo = null;
|
|
90
|
+
object obj = property.serializedObject.targetObject;
|
|
91
|
+
if (obj == null)
|
|
92
|
+
{
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
Type type = obj.GetType();
|
|
97
|
+
string[] pathParts = property.propertyPath.Split('.');
|
|
98
|
+
|
|
99
|
+
for (int i = 0; i < pathParts.Length; ++i)
|
|
100
|
+
{
|
|
101
|
+
string fieldName = pathParts[i];
|
|
102
|
+
|
|
103
|
+
if (string.Equals(fieldName, "Array", StringComparison.Ordinal))
|
|
104
|
+
{
|
|
105
|
+
// Move to "data[i]"
|
|
106
|
+
++i;
|
|
107
|
+
if (pathParts.Length <= i)
|
|
108
|
+
{
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (
|
|
113
|
+
!int.TryParse(
|
|
114
|
+
pathParts[i]
|
|
115
|
+
.Replace("data[", string.Empty, StringComparison.Ordinal)
|
|
116
|
+
.Replace("]", string.Empty, StringComparison.Ordinal),
|
|
117
|
+
out int index
|
|
118
|
+
)
|
|
119
|
+
)
|
|
120
|
+
{
|
|
121
|
+
// Unexpected, die
|
|
122
|
+
fieldInfo = null;
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
obj = GetElementAtIndex(obj, index);
|
|
126
|
+
type = obj?.GetType();
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
fieldInfo = type?.GetField(
|
|
131
|
+
fieldName,
|
|
132
|
+
BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance
|
|
133
|
+
);
|
|
134
|
+
if (fieldInfo == null)
|
|
135
|
+
{
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Move deeper into the object tree
|
|
140
|
+
obj = fieldInfo.GetValue(obj);
|
|
141
|
+
type = fieldInfo.FieldType;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return obj;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
private static object GetElementAtIndex(object obj, int index)
|
|
148
|
+
{
|
|
149
|
+
if (obj is System.Collections.IList list && index >= 0 && index < list.Count)
|
|
150
|
+
{
|
|
151
|
+
return list[index];
|
|
152
|
+
}
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
#endif
|
|
157
|
+
}
|
|
@@ -18,7 +18,8 @@
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
21
|
-
public static bool Null(
|
|
21
|
+
public static bool Null<T>(T instance)
|
|
22
|
+
where T : UnityEngine.Object
|
|
22
23
|
{
|
|
23
24
|
return instance == null;
|
|
24
25
|
}
|
|
@@ -29,7 +30,8 @@
|
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
32
|
-
public static bool NotNull(
|
|
33
|
+
public static bool NotNull<T>(T instance)
|
|
34
|
+
where T : UnityEngine.Object
|
|
33
35
|
{
|
|
34
36
|
return instance != null;
|
|
35
37
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
namespace UnityHelpers.Core.Helper
|
|
2
2
|
{
|
|
3
3
|
using System.Collections.Generic;
|
|
4
|
-
using System.Linq;
|
|
5
4
|
using UnityEngine;
|
|
6
5
|
|
|
7
6
|
public static partial class Helpers
|
|
@@ -171,10 +170,9 @@
|
|
|
171
170
|
{
|
|
172
171
|
if (component == null)
|
|
173
172
|
{
|
|
174
|
-
|
|
173
|
+
yield break;
|
|
175
174
|
}
|
|
176
175
|
|
|
177
|
-
Queue<Transform> results = new();
|
|
178
176
|
Queue<Transform> iteration = new();
|
|
179
177
|
iteration.Enqueue(component.transform);
|
|
180
178
|
while (iteration.TryDequeue(out Transform current))
|
|
@@ -182,12 +180,10 @@
|
|
|
182
180
|
for (int i = 0; i < current.childCount; ++i)
|
|
183
181
|
{
|
|
184
182
|
Transform childTransform = current.GetChild(i);
|
|
185
|
-
results.Enqueue(childTransform);
|
|
186
183
|
iteration.Enqueue(childTransform);
|
|
184
|
+
yield return childTransform;
|
|
187
185
|
}
|
|
188
186
|
}
|
|
189
|
-
|
|
190
|
-
return results;
|
|
191
187
|
}
|
|
192
188
|
}
|
|
193
189
|
}
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
public sealed class SingleThreadedThreadPool : IDisposable
|
|
8
8
|
{
|
|
9
9
|
public ConcurrentQueue<Exception> Exceptions => _exceptions;
|
|
10
|
+
public int Count => _work.Count + Interlocked.CompareExchange(ref _working, 0, 0);
|
|
10
11
|
|
|
11
12
|
private int _active;
|
|
12
13
|
private int _working;
|
|
@@ -16,14 +17,14 @@
|
|
|
16
17
|
private bool _disposed;
|
|
17
18
|
private readonly ConcurrentQueue<Exception> _exceptions;
|
|
18
19
|
|
|
19
|
-
public SingleThreadedThreadPool()
|
|
20
|
+
public SingleThreadedThreadPool(bool runInBackground = false)
|
|
20
21
|
{
|
|
21
22
|
_active = 1;
|
|
22
23
|
_working = 1;
|
|
23
24
|
_work = new ConcurrentQueue<Action>();
|
|
24
25
|
_exceptions = new ConcurrentQueue<Exception>();
|
|
25
26
|
_waitHandle = new AutoResetEvent(false);
|
|
26
|
-
_worker = new Thread(DoWork);
|
|
27
|
+
_worker = new Thread(DoWork) { IsBackground = runInBackground };
|
|
27
28
|
_worker.Start();
|
|
28
29
|
}
|
|
29
30
|
|
|
@@ -32,40 +33,12 @@
|
|
|
32
33
|
Dispose(false);
|
|
33
34
|
}
|
|
34
35
|
|
|
35
|
-
private void DoWork()
|
|
36
|
-
{
|
|
37
|
-
while (Interlocked.CompareExchange(ref _active, 0, 0) != 0)
|
|
38
|
-
{
|
|
39
|
-
_ = Interlocked.Exchange(ref _working, 0);
|
|
40
|
-
if (_work.TryDequeue(out Action workItem))
|
|
41
|
-
{
|
|
42
|
-
_ = Interlocked.Exchange(ref _working, 1);
|
|
43
|
-
try
|
|
44
|
-
{
|
|
45
|
-
workItem();
|
|
46
|
-
}
|
|
47
|
-
catch (Exception e)
|
|
48
|
-
{
|
|
49
|
-
_exceptions.Enqueue(e);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
else
|
|
53
|
-
{
|
|
54
|
-
_ = _waitHandle.WaitOne(TimeSpan.FromSeconds(1));
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
_ = Interlocked.Exchange(ref _working, 0);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
36
|
public void Enqueue(Action work)
|
|
62
37
|
{
|
|
63
38
|
_work.Enqueue(work);
|
|
64
39
|
_ = _waitHandle.Set();
|
|
65
40
|
}
|
|
66
41
|
|
|
67
|
-
public int Count => _work.Count + Interlocked.CompareExchange(ref _working, 0, 0);
|
|
68
|
-
|
|
69
42
|
public void Dispose()
|
|
70
43
|
{
|
|
71
44
|
Dispose(true);
|
|
@@ -79,17 +52,16 @@
|
|
|
79
52
|
return;
|
|
80
53
|
}
|
|
81
54
|
|
|
82
|
-
|
|
83
|
-
do
|
|
55
|
+
while (Interlocked.CompareExchange(ref _active, 0, _active) != 0)
|
|
84
56
|
{
|
|
85
|
-
|
|
86
|
-
}
|
|
57
|
+
// Spin
|
|
58
|
+
}
|
|
87
59
|
|
|
88
60
|
if (disposing)
|
|
89
61
|
{
|
|
90
62
|
try
|
|
91
63
|
{
|
|
92
|
-
_worker?.Join();
|
|
64
|
+
_worker?.Join(TimeSpan.FromSeconds(30));
|
|
93
65
|
_waitHandle?.Dispose();
|
|
94
66
|
}
|
|
95
67
|
catch
|
|
@@ -103,5 +75,42 @@
|
|
|
103
75
|
|
|
104
76
|
_disposed = true;
|
|
105
77
|
}
|
|
78
|
+
|
|
79
|
+
private void DoWork()
|
|
80
|
+
{
|
|
81
|
+
while (Interlocked.CompareExchange(ref _active, 0, 0) != 0)
|
|
82
|
+
{
|
|
83
|
+
try
|
|
84
|
+
{
|
|
85
|
+
if (_work.TryDequeue(out Action workItem))
|
|
86
|
+
{
|
|
87
|
+
_ = Interlocked.Exchange(ref _working, 1);
|
|
88
|
+
try
|
|
89
|
+
{
|
|
90
|
+
workItem();
|
|
91
|
+
}
|
|
92
|
+
catch (Exception e)
|
|
93
|
+
{
|
|
94
|
+
_exceptions.Enqueue(e);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
else
|
|
98
|
+
{
|
|
99
|
+
try
|
|
100
|
+
{
|
|
101
|
+
_ = _waitHandle?.WaitOne(TimeSpan.FromSeconds(1));
|
|
102
|
+
}
|
|
103
|
+
catch (ObjectDisposedException)
|
|
104
|
+
{
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
finally
|
|
110
|
+
{
|
|
111
|
+
_ = Interlocked.Exchange(ref _working, 0);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
106
115
|
}
|
|
107
116
|
}
|
package/Runtime/Utils/Buffers.cs
CHANGED
|
@@ -7,7 +7,6 @@
|
|
|
7
7
|
{
|
|
8
8
|
public const int BufferSize = 10_000;
|
|
9
9
|
|
|
10
|
-
public static readonly HashSet<Collider2D> UniqueColliders = new();
|
|
11
10
|
public static readonly Collider2D[] Colliders = new Collider2D[BufferSize];
|
|
12
11
|
public static readonly RaycastHit2D[] RaycastHits = new RaycastHit2D[BufferSize];
|
|
13
12
|
|
|
@@ -16,6 +15,8 @@
|
|
|
16
15
|
DO NOT USE with random values.
|
|
17
16
|
*/
|
|
18
17
|
public static readonly Dictionary<float, WaitForSeconds> WaitForSeconds = new();
|
|
18
|
+
public static readonly Dictionary<float, WaitForSecondsRealtime> WaitForSecondsRealtime =
|
|
19
|
+
new();
|
|
19
20
|
public static readonly System.Random Random = new();
|
|
20
21
|
public static readonly WaitForFixedUpdate WaitForFixedUpdate = new();
|
|
21
22
|
public static readonly WaitForEndOfFrame WaitForEndOfFrame = new();
|
package/package.json
CHANGED
|
File without changes
|