com.wallstop-studios.unity-helpers 2.0.0-rc05 → 2.0.0-rc07

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.
Files changed (46) hide show
  1. package/Runtime/Core/DataStructure/TimedCache.cs +4 -3
  2. package/Runtime/Core/Extension/IListExtensions.cs +2 -2
  3. package/Runtime/Core/Extension/RandomExtensions.cs +23 -4
  4. package/Runtime/Core/Extension/UnityExtensions.cs +278 -90
  5. package/Runtime/Core/Helper/ArrayConverter.cs +39 -0
  6. package/Runtime/Core/Helper/ArrayConverter.cs.meta +3 -0
  7. package/Runtime/Core/Helper/Helpers.cs +133 -563
  8. package/Runtime/Core/Helper/Partials/LogHelpers.cs +13 -0
  9. package/Runtime/Core/Helper/Partials/LogHelpers.cs.meta +3 -0
  10. package/Runtime/Core/Helper/Partials/MathHelpers.cs +30 -0
  11. package/Runtime/Core/Helper/Partials/MathHelpers.cs.meta +3 -0
  12. package/Runtime/Core/Helper/Partials/ObjectHelpers.cs +388 -0
  13. package/Runtime/Core/Helper/Partials/ObjectHelpers.cs.meta +3 -0
  14. package/Runtime/Core/Helper/Partials/TransformHelpers.cs +167 -0
  15. package/Runtime/Core/Helper/Partials/TransformHelpers.cs.meta +3 -0
  16. package/Runtime/Core/Helper/Partials.meta +3 -0
  17. package/Runtime/Core/Helper/WallMath.cs +85 -22
  18. package/Runtime/Core/Random/AbstractRandom.cs +208 -162
  19. package/Runtime/Core/Random/DotNetRandom.cs +3 -5
  20. package/Runtime/Core/Random/PRNG.cs +7 -0
  21. package/Runtime/Core/Random/PRNG.cs.meta +3 -0
  22. package/Runtime/Core/Random/PcgRandom.cs +4 -6
  23. package/Runtime/Core/Random/RandomState.cs +31 -3
  24. package/Runtime/Core/Random/SquirrelRandom.cs +12 -15
  25. package/Runtime/Core/Random/SystemRandom.cs +92 -46
  26. package/Runtime/Core/Random/ThreadLocalRandom.cs +2 -1
  27. package/Runtime/Core/Random/UnityRandom.cs +2 -4
  28. package/Runtime/Core/Random/WyRandom.cs +2 -4
  29. package/Runtime/Core/Random/XorShiftRandom.cs +3 -5
  30. package/Runtime/Core/Serialization/Serializer.cs +36 -14
  31. package/Runtime/Utils/CircleLineRenderer.cs +17 -5
  32. package/Tests/Runtime/DataStructures/SpatialTreeTests.cs +34 -10
  33. package/Tests/Runtime/Helper/ArrayConverterTests.cs +19 -0
  34. package/Tests/Runtime/Helper/ArrayConverterTests.cs.meta +3 -0
  35. package/Tests/Runtime/Helper/ObjectHelperTests.cs +402 -0
  36. package/Tests/Runtime/Helper/ObjectHelperTests.cs.meta +3 -0
  37. package/Tests/Runtime/Helper/WallMathTests.cs +221 -0
  38. package/Tests/Runtime/Helper/WallMathTests.cs.meta +3 -0
  39. package/Tests/Runtime/Helper.meta +3 -0
  40. package/Tests/Runtime/Performance/RandomPerformanceTests.cs +58 -3
  41. package/Tests/Runtime/Performance/SpatialTreePerformanceTest.cs +47 -34
  42. package/Tests/Runtime/Random/RandomTestBase.cs +284 -9
  43. package/Tests/Runtime/Random/SquirrelRandomTests.cs +5 -0
  44. package/Tests/Runtime/Serialization/JsonSerializationTest.cs +24 -11
  45. package/Tests/Runtime/Utils/SpriteRendererMetadataTests.cs +21 -17
  46. package/package.json +1 -1
@@ -3,12 +3,16 @@
3
3
  using System;
4
4
  using System.Collections.Generic;
5
5
  using System.Linq;
6
+ using System.Runtime.CompilerServices;
7
+ using Core.Extension;
8
+ using Core.Serialization;
6
9
  using NUnit.Framework;
7
10
  using UnityHelpers.Core.Random;
8
11
 
9
12
  public abstract class RandomTestBase
10
13
  {
11
- private const int SampleCount = 12_500_000;
14
+ private const int NumGeneratorChecks = 1_000;
15
+ private const int SampleCount = 12_750_000;
12
16
 
13
17
  private readonly int[] _samples = new int[1_000];
14
18
 
@@ -27,24 +31,119 @@
27
31
  }
28
32
 
29
33
  [Test]
34
+ [Parallelizable]
35
+ public void Bool()
36
+ {
37
+ TestAndVerify(random => Convert.ToInt32(random.NextBool()), maxLength: 2);
38
+ }
39
+
40
+ [Test]
41
+ [Parallelizable]
30
42
  public void Int()
31
43
  {
32
44
  TestAndVerify(random => random.Next(0, _samples.Length));
33
45
  }
34
46
 
35
47
  [Test]
48
+ [Parallelizable]
49
+ public void IntRange()
50
+ {
51
+ TestAndVerify(random => random.Next(_samples.Length));
52
+ }
53
+
54
+ [Test]
55
+ [Parallelizable]
56
+ public void IntDistribution()
57
+ {
58
+ TestAndVerify(random =>
59
+ (int)(random.Next() / ((1.0 * int.MaxValue) / _samples.Length))
60
+ );
61
+ }
62
+
63
+ [Test]
64
+ [Parallelizable]
65
+ public void IntMaxRange()
66
+ {
67
+ TestAndVerify(random =>
68
+ (int)(
69
+ (random.Next(int.MinValue, int.MaxValue) + (-1.0 * int.MinValue))
70
+ / (1.0 * int.MaxValue - int.MinValue)
71
+ * _samples.Length
72
+ )
73
+ );
74
+ }
75
+
76
+ [Test]
77
+ [Parallelizable]
36
78
  public void Uint()
37
79
  {
38
80
  TestAndVerify(random => (int)random.NextUint(0, (uint)_samples.Length));
39
81
  }
40
82
 
41
83
  [Test]
84
+ [Parallelizable]
85
+ public void UintRange()
86
+ {
87
+ TestAndVerify(random => (int)random.NextUint((uint)_samples.Length));
88
+ }
89
+
90
+ [Test]
91
+ [Parallelizable]
92
+ public void UintDistribution()
93
+ {
94
+ TestAndVerify(random =>
95
+ (int)(random.NextUint() / ((1.0 * uint.MaxValue) / _samples.Length))
96
+ );
97
+ }
98
+
99
+ [Test]
100
+ [Parallelizable]
101
+ public void UintMaxRange()
102
+ {
103
+ TestAndVerify(random =>
104
+ (int)(
105
+ (random.NextUint(uint.MinValue, uint.MaxValue) + (1.0 * uint.MinValue))
106
+ / (1.0 * uint.MaxValue)
107
+ * _samples.Length
108
+ )
109
+ );
110
+ }
111
+
112
+ [Test]
113
+ [Parallelizable]
42
114
  public void Short()
43
115
  {
44
- TestAndVerify(random => random.NextShort(0, (short)_samples.Length));
116
+ TestAndVerify(
117
+ random => random.NextShort(0, (short)_samples.Length),
118
+ maxLength: (short.MaxValue - short.MinValue)
119
+ );
120
+ }
121
+
122
+ [Test]
123
+ [Parallelizable]
124
+ public void ShortRange()
125
+ {
126
+ TestAndVerify(
127
+ random => random.NextShort((short)_samples.Length),
128
+ maxLength: (short.MaxValue - short.MinValue)
129
+ );
130
+ }
131
+
132
+ [Test]
133
+ [Parallelizable]
134
+ public void ShortMaxRange()
135
+ {
136
+ TestAndVerify(random =>
137
+ (int)(
138
+ (random.NextShort(short.MinValue, short.MaxValue) + (-1.0 * short.MinValue))
139
+ / (1.0 * short.MaxValue - short.MinValue)
140
+ * _samples.Length
141
+ )
142
+ );
45
143
  }
46
144
 
47
145
  [Test]
146
+ [Parallelizable]
48
147
  public void Byte()
49
148
  {
50
149
  TestAndVerify(
@@ -58,6 +157,40 @@
58
157
  }
59
158
 
60
159
  [Test]
160
+ [Parallelizable]
161
+ public void ByteRange()
162
+ {
163
+ TestAndVerify(
164
+ random =>
165
+ random.NextByte(
166
+ (byte)(_samples.Length < byte.MaxValue ? _samples.Length : byte.MaxValue)
167
+ ),
168
+ byte.MaxValue
169
+ );
170
+ }
171
+
172
+ [Test]
173
+ [Parallelizable]
174
+ public void ByteMaxRange()
175
+ {
176
+ int sampleCount = Math.Min((byte.MaxValue - byte.MinValue), _samples.Length);
177
+ TestAndVerify(
178
+ random =>
179
+ Math.Clamp(
180
+ (int)(
181
+ (random.NextByte(byte.MinValue, byte.MaxValue) + (-1.0 * byte.MinValue))
182
+ / (1.0 * byte.MaxValue - byte.MinValue)
183
+ * sampleCount
184
+ ),
185
+ 0,
186
+ sampleCount - 1
187
+ ),
188
+ maxLength: sampleCount
189
+ );
190
+ }
191
+
192
+ [Test]
193
+ [Parallelizable]
61
194
  public void Float()
62
195
  {
63
196
  TestAndVerify(random =>
@@ -70,6 +203,44 @@
70
203
  }
71
204
 
72
205
  [Test]
206
+ [Parallelizable]
207
+ public void FloatRange()
208
+ {
209
+ TestAndVerify(random =>
210
+ Math.Clamp(
211
+ (int)Math.Floor(random.NextFloat(_samples.Length)),
212
+ 0,
213
+ _samples.Length - 1
214
+ )
215
+ );
216
+ }
217
+
218
+ [Test]
219
+ [Parallelizable]
220
+ public void FloatDistribution()
221
+ {
222
+ TestAndVerify(random => (int)(random.NextFloat() * _samples.Length));
223
+ }
224
+
225
+ [Test]
226
+ [Parallelizable]
227
+ public void FloatMaxRange()
228
+ {
229
+ TestAndVerify(random =>
230
+ Math.Clamp(
231
+ (int)(
232
+ (random.NextFloat(float.MinValue, float.MaxValue) + (-1.0 * float.MinValue))
233
+ / (1.0 * float.MaxValue - float.MinValue)
234
+ * _samples.Length
235
+ ),
236
+ 0,
237
+ _samples.Length - 1
238
+ )
239
+ );
240
+ }
241
+
242
+ [Test]
243
+ [Parallelizable]
73
244
  public void Double()
74
245
  {
75
246
  TestAndVerify(random =>
@@ -82,28 +253,103 @@
82
253
  }
83
254
 
84
255
  [Test]
256
+ [Parallelizable]
257
+ public void DoubleRange()
258
+ {
259
+ TestAndVerify(random =>
260
+ Math.Clamp(
261
+ (int)Math.Floor(random.NextDouble(_samples.Length)),
262
+ 0,
263
+ _samples.Length - 1
264
+ )
265
+ );
266
+ }
267
+
268
+ [Test]
269
+ [Parallelizable]
270
+ public void DoubleDistribution()
271
+ {
272
+ TestAndVerify(random => (int)(random.NextDouble() * _samples.Length));
273
+ }
274
+
275
+ [Test]
276
+ [Parallelizable]
277
+ public void DoubleMaxRange()
278
+ {
279
+ IRandom random = NewRandom();
280
+ for (int i = 0; i < SampleCount; ++i)
281
+ {
282
+ double value = random.NextDouble(double.MinValue, double.MaxValue);
283
+ Assert.IsFalse(double.IsNaN(value));
284
+ Assert.IsFalse(double.IsInfinity(value));
285
+ }
286
+ }
287
+
288
+ [Test]
289
+ [Parallelizable]
85
290
  public void Long()
86
291
  {
87
292
  TestAndVerify(random => (int)random.NextLong(0, _samples.Length));
88
293
  }
89
294
 
90
295
  [Test]
296
+ [Parallelizable]
297
+ public void LongRange()
298
+ {
299
+ TestAndVerify(random => (int)random.NextLong(_samples.Length));
300
+ }
301
+
302
+ [Test]
303
+ [Parallelizable]
304
+ public void LongMaxRange()
305
+ {
306
+ TestAndVerify(random =>
307
+ (int)(
308
+ (random.NextLong(long.MinValue, long.MaxValue) + (-1.0 * long.MinValue))
309
+ / (1.0 * long.MaxValue - long.MinValue)
310
+ * _samples.Length
311
+ )
312
+ );
313
+ }
314
+
315
+ [Test]
316
+ [Parallelizable]
91
317
  public void Ulong()
92
318
  {
93
319
  TestAndVerify(random => (int)random.NextUlong(0, (ulong)_samples.Length));
94
320
  }
95
321
 
96
322
  [Test]
323
+ [Parallelizable]
324
+ public void UlongRange()
325
+ {
326
+ TestAndVerify(random => (int)random.NextUlong((ulong)_samples.Length));
327
+ }
328
+
329
+ [Test]
330
+ [Parallelizable]
331
+ public void UlongMaxRange()
332
+ {
333
+ TestAndVerify(random =>
334
+ (int)(
335
+ (random.NextUlong(ulong.MinValue, ulong.MaxValue) + (-1.0 * ulong.MinValue))
336
+ / (1.0 * ulong.MaxValue - ulong.MinValue)
337
+ * _samples.Length
338
+ )
339
+ );
340
+ }
341
+
342
+ [Test]
343
+ [Parallelizable]
97
344
  public void Copy()
98
345
  {
99
- const int numGeneratorChecks = 1_000;
100
346
  IRandom random1 = NewRandom();
101
347
  IRandom random2 = random1.Copy();
102
348
  Assert.AreEqual(random1.InternalState, random2.InternalState);
103
349
  // UnityRandom has shared state, the below test is not possible for it. We did all we could.
104
350
  if (NewRandom() is not UnityRandom)
105
351
  {
106
- for (int i = 0; i < numGeneratorChecks; ++i)
352
+ for (int i = 0; i < NumGeneratorChecks; ++i)
107
353
  {
108
354
  Assert.AreEqual(random1.Next(), random2.Next());
109
355
  Assert.AreEqual(random1.InternalState, random2.InternalState);
@@ -115,7 +361,7 @@
115
361
  Assert.AreEqual(random1.InternalState, random3.InternalState);
116
362
  if (NewRandom() is not UnityRandom)
117
363
  {
118
- for (int i = 0; i < numGeneratorChecks; ++i)
364
+ for (int i = 0; i < NumGeneratorChecks; ++i)
119
365
  {
120
366
  Assert.AreEqual(random1.Next(), random3.Next());
121
367
  Assert.AreEqual(random1.InternalState, random3.InternalState);
@@ -123,13 +369,42 @@
123
369
  }
124
370
  }
125
371
 
126
- private void TestAndVerify(Func<IRandom, int> sample, int? maxLength = null)
372
+ [Test]
373
+ [Parallelizable]
374
+ public void Json()
375
+ {
376
+ IRandom random = NewRandom();
377
+ string json = random.ToJson();
378
+ IRandom deserialized = Serializer.JsonDeserialize<IRandom>(json, random.GetType());
379
+ Assert.AreEqual(random.InternalState, deserialized.InternalState);
380
+
381
+ if (NewRandom() is not UnityRandom)
382
+ {
383
+ for (int i = 0; i < NumGeneratorChecks; ++i)
384
+ {
385
+ Assert.AreEqual(random.Next(), deserialized.Next());
386
+ Assert.AreEqual(random.InternalState, deserialized.InternalState);
387
+ }
388
+ }
389
+ }
390
+
391
+ protected virtual double DeviationFor(string caller)
392
+ {
393
+ return 0.0625;
394
+ }
395
+
396
+ private void TestAndVerify(
397
+ Func<IRandom, int> sample,
398
+ int? maxLength = null,
399
+ [CallerMemberName] string caller = ""
400
+ )
127
401
  {
128
402
  IRandom random = NewRandom();
403
+ int sampleLength = _samples.Length;
129
404
  for (int i = 0; i < SampleCount; ++i)
130
405
  {
131
406
  int index = sample(random);
132
- if (index < 0 || _samples.Length <= index)
407
+ if (index < 0 || sampleLength <= index)
133
408
  {
134
409
  Assert.Fail("Index {0} out of range", index);
135
410
  }
@@ -139,9 +414,9 @@
139
414
  }
140
415
  }
141
416
 
142
- int sampleLength = Math.Min(_samples.Length, maxLength ?? _samples.Length);
417
+ sampleLength = Math.Min(sampleLength, maxLength ?? sampleLength);
143
418
  double average = SampleCount * 1.0 / sampleLength;
144
- double deviationAllowed = average * 0.05;
419
+ double deviationAllowed = average * DeviationFor(caller);
145
420
  List<int> zeroCountIndexes = new();
146
421
  List<int> outsideRange = new();
147
422
  for (int i = 0; i < sampleLength; i++)
@@ -5,5 +5,10 @@
5
5
  public sealed class SquirrelRandomTests : RandomTestBase
6
6
  {
7
7
  protected override IRandom NewRandom() => new SquirrelRandom();
8
+
9
+ protected override double DeviationFor(string caller)
10
+ {
11
+ return 0.075;
12
+ }
8
13
  }
9
14
  }
@@ -29,12 +29,12 @@
29
29
  [Test]
30
30
  public void SerializationWorks()
31
31
  {
32
- IRandom random = PcgRandom.Instance;
32
+ IRandom random = PRNG.Instance;
33
33
  TestDataObject input = new()
34
34
  {
35
35
  field = Guid.NewGuid().ToString(),
36
36
  Property = random.Next(),
37
- NamedProperty = random.NextFloat()
37
+ NamedProperty = random.NextFloat(),
38
38
  };
39
39
 
40
40
  int dictionaryProperties = random.Next(4, 10);
@@ -51,21 +51,34 @@
51
51
 
52
52
  string json = input.ToJson();
53
53
  Assert.IsTrue(
54
- json.Contains("DifferentPropertyName"), $"DifferentPropertyName failed to serialize! JSON: {json}");
54
+ json.Contains("DifferentPropertyName"),
55
+ $"DifferentPropertyName failed to serialize! JSON: {json}"
56
+ );
55
57
 
56
58
  TestDataObject deserialized = Serializer.JsonDeserialize<TestDataObject>(json);
57
- Assert.AreEqual(input.field, deserialized.field, $"Unexpected {nameof(deserialized.field)}! JSON: {json}");
58
59
  Assert.AreEqual(
59
- input.Property, deserialized.Property, $"Unexpected {nameof(deserialized.Property)}! JSON: {json}");
60
+ input.field,
61
+ deserialized.field,
62
+ $"Unexpected {nameof(deserialized.field)}! JSON: {json}"
63
+ );
60
64
  Assert.AreEqual(
61
- input.NamedProperty, deserialized.NamedProperty,
62
- $"Unexpected {nameof(deserialized.NamedProperty)}! JSON: {json}");
63
- Assert.IsTrue(
65
+ input.Property,
66
+ deserialized.Property,
67
+ $"Unexpected {nameof(deserialized.Property)}! JSON: {json}"
68
+ );
69
+ Assert.AreEqual(
70
+ input.NamedProperty,
71
+ deserialized.NamedProperty,
72
+ $"Unexpected {nameof(deserialized.NamedProperty)}! JSON: {json}"
73
+ );
74
+ Assert.IsTrue(
64
75
  input.DictionaryProperty.ContentEquals(deserialized.DictionaryProperty),
65
- $"Unexpected {nameof(deserialized.DictionaryProperty)}! JSON: {json}");
76
+ $"Unexpected {nameof(deserialized.DictionaryProperty)}! JSON: {json}"
77
+ );
66
78
  Assert.IsTrue(
67
79
  input.ListProperty.SequenceEqual(deserialized.ListProperty),
68
- $"Unexpected {nameof(deserialized.ListProperty)}! JSON: {json}");
80
+ $"Unexpected {nameof(deserialized.ListProperty)}! JSON: {json}"
81
+ );
69
82
  }
70
83
  }
71
- }
84
+ }
@@ -32,7 +32,11 @@
32
32
 
33
33
  private SpriteRendererMetadata CreateMetadata()
34
34
  {
35
- GameObject go = new("TestSpriteRendererMetadata", typeof(SpriteRenderer), typeof(SpriteRendererMetadata));
35
+ GameObject go = new(
36
+ "TestSpriteRendererMetadata",
37
+ typeof(SpriteRenderer),
38
+ typeof(SpriteRendererMetadata)
39
+ );
36
40
  _spawned.Add(go);
37
41
  return go.GetComponent<SpriteRendererMetadata>();
38
42
  }
@@ -44,8 +48,13 @@
44
48
 
45
49
  private Color CreateColor()
46
50
  {
47
- IRandom random = PcgRandom.Instance;
48
- Color color = new(random.NextFloat(), random.NextFloat(), random.NextFloat(), random.NextFloat());
51
+ IRandom random = PRNG.Instance;
52
+ Color color = new(
53
+ random.NextFloat(),
54
+ random.NextFloat(),
55
+ random.NextFloat(),
56
+ random.NextFloat()
57
+ );
49
58
  return color;
50
59
  }
51
60
 
@@ -74,9 +83,8 @@
74
83
  Material originalMaterial = metadata.OriginalMaterial;
75
84
  do
76
85
  {
77
- newColor.r = PcgRandom.Instance.NextFloat();
78
- }
79
- while (newColor == originalColor);
86
+ newColor.r = PRNG.Instance.NextFloat();
87
+ } while (newColor == originalColor);
80
88
 
81
89
  SpriteRendererMetadata second = CreateMetadata();
82
90
  SpriteRenderer spriteRenderer = metadata.GetComponent<SpriteRenderer>();
@@ -91,9 +99,8 @@
91
99
  Color updatedColor = newColor;
92
100
  do
93
101
  {
94
- updatedColor.g = PcgRandom.Instance.NextFloat();
95
- }
96
- while (updatedColor == newColor);
102
+ updatedColor.g = PRNG.Instance.NextFloat();
103
+ } while (updatedColor == newColor);
97
104
 
98
105
  metadata.PushColor(spriteRenderer, updatedColor);
99
106
  Assert.AreEqual(spriteRenderer.color, metadata.CurrentColor);
@@ -108,9 +115,8 @@
108
115
  Color latestColor = updatedColor;
109
116
  do
110
117
  {
111
- latestColor.b = PcgRandom.Instance.NextFloat();
112
- }
113
- while (latestColor == updatedColor);
118
+ latestColor.b = PRNG.Instance.NextFloat();
119
+ } while (latestColor == updatedColor);
114
120
 
115
121
  metadata.PushColor(second, latestColor);
116
122
  Assert.AreEqual(spriteRenderer.color, metadata.CurrentColor);
@@ -120,9 +126,8 @@
120
126
  Assert.IsFalse(metadata.Colors.Contains(newColor));
121
127
  do
122
128
  {
123
- newColor.a = PcgRandom.Instance.NextFloat();
124
- }
125
- while (newColor == latestColor);
129
+ newColor.a = PRNG.Instance.NextFloat();
130
+ } while (newColor == latestColor);
126
131
 
127
132
  metadata.PushColor(second, newColor);
128
133
  Assert.AreEqual(spriteRenderer.color, metadata.CurrentColor);
@@ -189,7 +194,6 @@
189
194
  yield break;
190
195
  }
191
196
 
192
-
193
197
  [UnityTest]
194
198
  public IEnumerator PopColorIdempotent()
195
199
  {
@@ -392,4 +396,4 @@
392
396
  yield break;
393
397
  }
394
398
  }
395
- }
399
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "com.wallstop-studios.unity-helpers",
3
- "version": "2.0.0-rc05",
3
+ "version": "2.0.0-rc07",
4
4
  "displayName": "Unity Helpers",
5
5
  "description": "Various Unity Helper Library",
6
6
  "dependencies": {},