com.wallstop-studios.unity-helpers 2.0.0-rc45 → 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.
@@ -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 bounds check, we're safe
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
- nearestNeighbors.AddRange(nearestNeighborsSet);
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
- return;
283
-
284
- int NearestComparison(T lhs, T rhs) =>
285
- (_elementTransformer(lhs) - position).sqrMagnitude.CompareTo(
286
- (_elementTransformer(rhs) - position).sqrMagnitude
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
- childrenCopy.AddRange(current.children);
238
- childrenCopy.Sort(Comparison);
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
- nearestNeighbors.AddRange(nearestNeighborsSet);
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
- childrenCopy.AddRange(current.children);
295
- childrenCopy.Sort(Comparison);
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
- nearestNeighbors.AddRange(nearestNeighborsSet);
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?.GetHashCode() ?? 0;
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 void Remove(string value)
30
+ public static bool Remove(string value)
31
31
  {
32
- _ = Cache.TryRemove(value, out _);
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 || Helpers.HasEnoughTimePassed(_lastRead.Value, _cacheTtl))
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
- if (useJitter && 0 < _cacheTtl)
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
  }
@@ -45,12 +45,20 @@
45
45
 
46
46
  protected virtual void Start()
47
47
  {
48
- if (_instance != null && _instance != this)
48
+ if (_instance == null || _instance == this)
49
49
  {
50
- this.LogError(
51
- $"Double singleton detected, {_instance.name} conflicts with {name}."
52
- );
53
- gameObject.Destroy();
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
  }
@@ -1,12 +1,21 @@
1
1
  namespace UnityHelpers.Tests.Extensions
2
2
  {
3
3
  using System;
4
+ using System.Collections.Generic;
4
5
  using System.Linq;
5
6
  using Core.Extension;
7
+ using Core.Random;
6
8
  using NUnit.Framework;
7
9
 
8
10
  public sealed class IListExtensionTests
9
11
  {
12
+ private const int NumTries = 1_000;
13
+
14
+ private readonly struct IntComparer : IComparer<int>
15
+ {
16
+ public int Compare(int x, int y) => x.CompareTo(y);
17
+ }
18
+
10
19
  [Test]
11
20
  public void ShiftLeft()
12
21
  {
@@ -72,5 +81,24 @@
72
81
  Assert.Throws<ArgumentException>(() => input.Reverse(1, int.MaxValue));
73
82
  Assert.Throws<ArgumentException>(() => input.Reverse(1, int.MinValue));
74
83
  }
84
+
85
+ [Test]
86
+ public void InsertionSort()
87
+ {
88
+ for (int i = 0; i < NumTries; ++i)
89
+ {
90
+ int[] input = Enumerable
91
+ .Range(0, 100)
92
+ .Select(_ => PRNG.Instance.Next(int.MinValue, int.MaxValue))
93
+ .ToArray();
94
+ int[] conventionalSorted = input.ToArray();
95
+ Array.Sort(conventionalSorted);
96
+
97
+ int[] insertionSorted = input.ToArray();
98
+ insertionSorted.InsertionSort(new IntComparer());
99
+ Assert.That(conventionalSorted, Is.EqualTo(insertionSorted));
100
+ Assert.That(input.OrderBy(x => x), Is.EqualTo(insertionSorted));
101
+ }
102
+ }
75
103
  }
76
104
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "com.wallstop-studios.unity-helpers",
3
- "version": "2.0.0-rc45",
3
+ "version": "2.0.0-rc46",
4
4
  "displayName": "Unity Helpers",
5
5
  "description": "Various Unity Helper Library",
6
6
  "dependencies": {},