com.wallstop-studios.unity-helpers 2.0.0-rc42 → 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.
@@ -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
+ }
@@ -0,0 +1,3 @@
1
+ fileFormatVersion: 2
2
+ guid: f58cbae584d8414a89cc3996d16fc5b0
3
+ timeCreated: 1742507900
@@ -18,7 +18,8 @@
18
18
  }
19
19
 
20
20
  [MethodImpl(MethodImplOptions.AggressiveInlining)]
21
- public static bool Null(UnityEngine.Object instance)
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(UnityEngine.Object instance)
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
@@ -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
- int active;
83
- do
55
+ while (Interlocked.CompareExchange(ref _active, 0, _active) != 0)
84
56
  {
85
- active = Interlocked.CompareExchange(ref _active, 0, _active);
86
- } while (active != 0);
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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "com.wallstop-studios.unity-helpers",
3
- "version": "2.0.0-rc42",
3
+ "version": "2.0.0-rc43",
4
4
  "displayName": "Unity Helpers",
5
5
  "description": "Various Unity Helper Library",
6
6
  "dependencies": {},