com.wallstop-studios.unity-helpers 2.0.0-rc43 → 2.0.0-rc44

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/README.md CHANGED
@@ -129,6 +129,22 @@ random.NextNoiseMap(width, height); // A configurable noise map generated using
129
129
  - XorShift
130
130
  - XorShiro
131
131
 
132
+ ## Performance (Number of Operations / Second)
133
+
134
+ | Random | NextBool | Next | NextUInt | NextFloat | NextDouble | NextUint - Range | NextInt - Range |
135
+ | ------ | -------- | ---- | -------- | --------- | ---------- | ---------------- | --------------- |
136
+ | PcgRandom | 34,260,478 | 34,303,866 | 35,148,246 | 24,818,438 | 30,034,632 |22,436,474 |20,801,797 |
137
+ | SystemRandom | 28,698,806 | 30,040,782 | 20,435,092 | 24,079,399 | 27,284,147 |20,735,769 |19,861,780 |
138
+ | SquirrelRandom | 33,285,784 | 33,439,909 | 34,611,893 | 23,885,731 | 28,958,725 |21,520,279 |20,311,372 |
139
+ | XorShiftRandom | 34,695,989 | 35,147,320 | 35,997,718 | 25,248,238 | 31,582,991 |22,679,928 |21,255,319 |
140
+ | DotNetRandom | 18,097,489 | 18,191,042 | 18,783,063 | 14,061,444 | 15,730,439 |13,284,050 |12,596,913 |
141
+ | WyRandom | 28,490,852 | 29,086,052 | 29,724,907 | 20,252,065 | 24,542,201 |18,474,790 |17,404,641 |
142
+ | SplitMix64 | 34,301,843 | 34,343,404 | 35,512,284 | 24,289,416 | 30,586,231 |22,470,330 |20,850,965 |
143
+ | RomuDuo | 32,969,889 | 33,413,212 | 34,339,227 | 23,755,059 | 29,483,136 |21,671,641 |20,253,479 |
144
+ | XorShiroRandom | 31,529,025 | 31,717,709 | 32,536,277 | 22,421,715 | 27,619,417 |20,843,993 |19,270,063 |
145
+ | UnityRandom | 24,925,268 | 24,830,594 | 26,429,283 | 17,864,528 | 21,206,384 |16,376,626 |15,528,972 |
146
+ | LinearCongruentialGenerator | 35,013,818 | 35,025,182 | 35,843,533 | 25,093,401 | 31,553,487 |22,579,798 |21,211,175 |
147
+
132
148
  # Spatial Trees
133
149
  There are three implemented 2D immutable spatial trees that can store generic objects, as long as there is some resolution function that can convert them into Vector2 spatial positions.
134
150
 
@@ -0,0 +1,32 @@
1
+ namespace UnityHelpers.Core.Helper
2
+ {
3
+ using System;
4
+
5
+ public static class FormattingHelpers
6
+ {
7
+ public static string FormatBytes(long bytes)
8
+ {
9
+ string[] sizes = { "B", "KB", "MB", "GB", "TB", "PB", "EB" };
10
+ double len = bytes;
11
+ int order = 0;
12
+
13
+ bytes = Math.Max(0, bytes);
14
+
15
+ const int byteInChunk = 1024;
16
+ while (byteInChunk <= len)
17
+ {
18
+ len /= byteInChunk;
19
+ if (order < sizes.Length - 1)
20
+ {
21
+ ++order;
22
+ }
23
+ else
24
+ {
25
+ throw new ArgumentException($"Too many bytes! Cannot parse {bytes}");
26
+ }
27
+ }
28
+
29
+ return $"{len:0.##} {sizes[order]}";
30
+ }
31
+ }
32
+ }
@@ -0,0 +1,3 @@
1
+ fileFormatVersion: 2
2
+ guid: a4bf649a0aef41b48c8afb261c4bd1d1
3
+ timeCreated: 1742614257
@@ -21,6 +21,8 @@
21
21
 
22
22
  public abstract RandomState InternalState { get; }
23
23
 
24
+ private readonly byte[] _guidBytes = new byte[16];
25
+
24
26
  public virtual int Next()
25
27
  {
26
28
  // Mask out the MSB to ensure the value is within [0, int.MaxValue]
@@ -410,24 +412,23 @@
410
412
  where T : struct, Enum
411
413
  {
412
414
  Type enumType = typeof(T);
413
- T[] enumValues = (T[])EnumTypeCache.GetOrAdd(enumType, Enum.GetValues);
415
+ T[] enumValues = (T[])EnumTypeCache.GetOrAdd(enumType, type => Enum.GetValues(type));
414
416
 
415
417
  return RandomOf(enumValues);
416
418
  }
417
419
 
418
420
  public Guid NextGuid()
419
421
  {
420
- return new Guid(GenerateGuidBytes());
422
+ return new Guid(GenerateGuidBytes(_guidBytes));
421
423
  }
422
424
 
423
425
  public KGuid NextKGuid()
424
426
  {
425
- return new KGuid(GenerateGuidBytes());
427
+ return new KGuid(GenerateGuidBytes(_guidBytes));
426
428
  }
427
429
 
428
- private byte[] GenerateGuidBytes()
430
+ private byte[] GenerateGuidBytes(byte[] guidBytes)
429
431
  {
430
- byte[] guidBytes = new byte[16];
431
432
  NextBytes(guidBytes);
432
433
  SetUuidV4Bits(guidBytes);
433
434
  return guidBytes;
@@ -8,6 +8,8 @@
8
8
  [DataContract]
9
9
  public sealed class DotNetRandom : AbstractRandom
10
10
  {
11
+ public static DotNetRandom Instance => ThreadLocalRandom<DotNetRandom>.Instance;
12
+
11
13
  public override RandomState InternalState =>
12
14
  new RandomState(unchecked((ulong)_seed), state2: _numberGenerated);
13
15
 
@@ -138,6 +138,7 @@
138
138
  double NextGaussian(double mean = 0, double stdDev = 1);
139
139
 
140
140
  Guid NextGuid();
141
+
141
142
  KGuid NextKGuid();
142
143
 
143
144
  T NextOf<T>(IEnumerable<T> enumerable);
@@ -0,0 +1,49 @@
1
+ namespace UnityHelpers.Core.Random
2
+ {
3
+ using System;
4
+ using System.Text.Json.Serialization;
5
+
6
+ public sealed class LinearCongruentialGenerator : AbstractRandom
7
+ {
8
+ public static LinearCongruentialGenerator Instance =>
9
+ ThreadLocalRandom<LinearCongruentialGenerator>.Instance;
10
+
11
+ public override RandomState InternalState => new(_state, 0, _cachedGaussian);
12
+
13
+ private uint _state;
14
+
15
+ public LinearCongruentialGenerator()
16
+ : this(Guid.NewGuid()) { }
17
+
18
+ public LinearCongruentialGenerator(int seed)
19
+ {
20
+ _state = unchecked((uint)seed);
21
+ }
22
+
23
+ public LinearCongruentialGenerator(Guid seed)
24
+ {
25
+ _state = unchecked((uint)seed.GetHashCode());
26
+ }
27
+
28
+ [JsonConstructor]
29
+ public LinearCongruentialGenerator(RandomState internalState)
30
+ {
31
+ _state = unchecked((uint)internalState.State1);
32
+ _cachedGaussian = internalState.Gaussian;
33
+ }
34
+
35
+ public override uint NextUint()
36
+ {
37
+ unchecked
38
+ {
39
+ _state = _state * 1664525U + 1013904223U;
40
+ }
41
+ return _state;
42
+ }
43
+
44
+ public override IRandom Copy()
45
+ {
46
+ return new LinearCongruentialGenerator(InternalState);
47
+ }
48
+ }
49
+ }
@@ -0,0 +1,3 @@
1
+ fileFormatVersion: 2
2
+ guid: 23eaec3a914247e59d9bd39e199b718e
3
+ timeCreated: 1742702544
@@ -15,7 +15,7 @@
15
15
  IComparable,
16
16
  IComparable<PcgRandom>
17
17
  {
18
- public static IRandom Instance => ThreadLocalRandom<PcgRandom>.Instance;
18
+ public static PcgRandom Instance => ThreadLocalRandom<PcgRandom>.Instance;
19
19
 
20
20
  public override RandomState InternalState => new(_state, _increment, _cachedGaussian);
21
21
 
@@ -15,7 +15,7 @@
15
15
  IComparable,
16
16
  IComparable<RomuDuo>
17
17
  {
18
- public static IRandom Instance => ThreadLocalRandom<RomuDuo>.Instance;
18
+ public static RomuDuo Instance => ThreadLocalRandom<RomuDuo>.Instance;
19
19
  public override RandomState InternalState => new(_x, _y, _cachedGaussian);
20
20
 
21
21
  internal ulong _x;
@@ -12,7 +12,7 @@
12
12
  IComparable,
13
13
  IComparable<SplitMix64>
14
14
  {
15
- public static IRandom Instance => ThreadLocalRandom<SplitMix64>.Instance;
15
+ public static SplitMix64 Instance => ThreadLocalRandom<SplitMix64>.Instance;
16
16
 
17
17
  public override RandomState InternalState => new(_state, 0, _cachedGaussian);
18
18
 
@@ -16,7 +16,7 @@
16
16
  private const int SeedArraySize = 56;
17
17
  private const int LastSeedIndex = SeedArraySize - 1;
18
18
 
19
- public static IRandom Instance => ThreadLocalRandom<SystemRandom>.Instance;
19
+ public static SystemRandom Instance => ThreadLocalRandom<SystemRandom>.Instance;
20
20
 
21
21
  public override RandomState InternalState =>
22
22
  new(
@@ -14,7 +14,7 @@
14
14
  private const ulong Prime0 = 0xa0761d6478bd642f;
15
15
  private const ulong Prime1 = 0xe7037ed1a0b428db;
16
16
 
17
- public static IRandom Instance => ThreadLocalRandom<WyRandom>.Instance;
17
+ public static WyRandom Instance => ThreadLocalRandom<WyRandom>.Instance;
18
18
 
19
19
  public override RandomState InternalState => new RandomState(_state);
20
20
 
@@ -8,18 +8,25 @@
8
8
  [DataContract]
9
9
  public sealed class XorShiftRandom : AbstractRandom
10
10
  {
11
- public static IRandom Instance => ThreadLocalRandom<XorShiftRandom>.Instance;
11
+ public static XorShiftRandom Instance => ThreadLocalRandom<XorShiftRandom>.Instance;
12
12
 
13
13
  public override RandomState InternalState => new(_state, 0, _cachedGaussian);
14
14
 
15
15
  private uint _state;
16
16
 
17
17
  public XorShiftRandom()
18
- : this(Guid.NewGuid().GetHashCode()) { }
18
+ : this(Guid.NewGuid()) { }
19
19
 
20
20
  public XorShiftRandom(int state)
21
21
  {
22
22
  _state = unchecked((uint)state);
23
+ _state = _state != 0 ? _state : 2463534242U;
24
+ }
25
+
26
+ public XorShiftRandom(Guid seed)
27
+ {
28
+ _state = unchecked((uint)seed.GetHashCode());
29
+ _state = _state != 0 ? _state : 2463534242U;
23
30
  }
24
31
 
25
32
  [JsonConstructor]
@@ -31,12 +38,10 @@
31
38
 
32
39
  public override uint NextUint()
33
40
  {
34
- uint state = _state;
35
- state ^= state << 13;
36
- state ^= state >> 17;
37
- state ^= state << 5;
38
- _state = state;
39
- return state;
41
+ _state ^= _state << 13;
42
+ _state ^= _state >> 17;
43
+ _state ^= _state << 5;
44
+ return _state;
40
45
  }
41
46
 
42
47
  public override IRandom Copy()
@@ -12,6 +12,8 @@
12
12
  IComparable,
13
13
  IComparable<XorShiroRandom>
14
14
  {
15
+ public static XorShiroRandom Instance => ThreadLocalRandom<XorShiroRandom>.Instance;
16
+
15
17
  public override RandomState InternalState => new(_s0, _s1, _cachedGaussian);
16
18
 
17
19
  internal ulong _s0;
@@ -176,7 +176,7 @@
176
176
  int maxY = int.MinValue;
177
177
  foreach (AnimatedSpriteLayer layer in _layers)
178
178
  {
179
- if (!layer.frames.Any())
179
+ if (layer.frames.Length <= 0)
180
180
  {
181
181
  continue;
182
182
  }
@@ -210,7 +210,7 @@
210
210
 
211
211
  foreach (AnimatedSpriteLayer layer in _layers)
212
212
  {
213
- if (!layer.frames.Any())
213
+ if (layer.frames.Length <= 0)
214
214
  {
215
215
  continue;
216
216
  }
@@ -11,6 +11,8 @@
11
11
  [DisallowMultipleComponent]
12
12
  public sealed class SpriteRendererMetadata : MonoBehaviour
13
13
  {
14
+ private bool Enabled => enabled && gameObject.activeInHierarchy;
15
+
14
16
  private readonly List<(Component component, Color color)> _colorStack = new();
15
17
  private readonly List<(Component component, Material material)> _materialStack = new();
16
18
 
@@ -25,9 +27,10 @@
25
27
 
26
28
  public Material CurrentMaterial => _materialStack[^1].material;
27
29
 
28
- public IEnumerable<Material> Materials => _materialStack.Select(entry => entry.material);
30
+ public IEnumerable<Material> Materials =>
31
+ _materialStack.Select(entry => entry.material).Reverse();
29
32
 
30
- public IEnumerable<Color> Colors => _colorStack.Select(entry => entry.color);
33
+ public IEnumerable<Color> Colors => _colorStack.Select(entry => entry.color).Reverse();
31
34
 
32
35
  [SiblingComponent]
33
36
  [SerializeField]
@@ -42,7 +45,7 @@
42
45
  return;
43
46
  }
44
47
 
45
- if (!force && !enabled)
48
+ if (!force && !Enabled)
46
49
  {
47
50
  return;
48
51
  }
@@ -64,7 +67,7 @@
64
67
  return;
65
68
  }
66
69
 
67
- if (!force && !enabled)
70
+ if (!force && !Enabled)
68
71
  {
69
72
  return;
70
73
  }
@@ -82,15 +85,17 @@
82
85
 
83
86
  public bool TryGetColor(Component component, out Color color)
84
87
  {
85
- int index = _colorStack.FindIndex(value => value.component == component);
86
- if (index < 0)
88
+ foreach ((Component component, Color color) entry in _colorStack)
87
89
  {
88
- color = default;
89
- return false;
90
+ if (entry.component == component)
91
+ {
92
+ color = entry.color;
93
+ return true;
94
+ }
90
95
  }
91
96
 
92
- color = _colorStack[index].color;
93
- return true;
97
+ color = default;
98
+ return false;
94
99
  }
95
100
 
96
101
  /// <summary>
@@ -98,7 +103,7 @@
98
103
  /// </summary>
99
104
  /// <param name="component">Component that owns the material.</param>
100
105
  /// <param name="material">Material to use.</param>
101
- /// <param name="force">If true, overrides the enable check.</param>
106
+ /// <param name="force">If true, overrides the enabled check.</param>
102
107
  /// <returns>The instanced material, if possible.</returns>
103
108
  public Material PushMaterial(Component component, Material material, bool force = false)
104
109
  {
@@ -107,7 +112,7 @@
107
112
  return null;
108
113
  }
109
114
 
110
- if (!force && !enabled)
115
+ if (!force && !Enabled)
111
116
  {
112
117
  return null;
113
118
  }
@@ -135,7 +140,7 @@
135
140
  /// </summary>
136
141
  /// <param name="component">Component that owns the material.</param>
137
142
  /// <param name="material">Material to use.</param>
138
- /// <param name="force">If true, overrides the enable check.</param>
143
+ /// <param name="force">If true, overrides the enabled check.</param>
139
144
  /// <returns>The instanced material, if possible.</returns>
140
145
  public Material PushBackMaterial(Component component, Material material, bool force = false)
141
146
  {
@@ -144,7 +149,7 @@
144
149
  return null;
145
150
  }
146
151
 
147
- if (!force && !enabled)
152
+ if (!force && !Enabled)
148
153
  {
149
154
  return null;
150
155
  }
@@ -186,14 +191,17 @@
186
191
 
187
192
  public bool TryGetMaterial(Component component, out Material material)
188
193
  {
189
- int index = _materialStack.FindIndex(value => value.component == component);
190
- if (index < 0)
194
+ foreach ((Component component, Material material) entry in _materialStack)
191
195
  {
192
- material = default;
193
- return false;
196
+ if (entry.component == component)
197
+ {
198
+ material = entry.material;
199
+ return true;
200
+ }
194
201
  }
195
- material = _materialStack[index].material;
196
- return true;
202
+
203
+ material = default;
204
+ return false;
197
205
  }
198
206
 
199
207
  private void Awake()
@@ -204,9 +212,15 @@
204
212
  }
205
213
 
206
214
  InternalPushColor(this, _spriteRenderer.color);
207
- _colorStackCache.AddRange(_colorStack);
215
+ foreach ((Component component, Color color) entry in _colorStack)
216
+ {
217
+ _colorStackCache.Add(entry);
218
+ }
208
219
  _ = InternalPushMaterial(this, _spriteRenderer.material);
209
- _materialStackCache.AddRange(_materialStack);
220
+ foreach ((Component component, Material material) entry in _materialStack)
221
+ {
222
+ _materialStackCache.Add(entry);
223
+ }
210
224
  }
211
225
 
212
226
  private void OnEnable()
@@ -219,13 +233,20 @@
219
233
  }
220
234
 
221
235
  _colorStack.Clear();
222
- _colorStack.Add(_colorStackCache[0]);
236
+ if (0 < _colorStackCache.Count)
237
+ {
238
+ _colorStack.Add(_colorStackCache[0]);
239
+ }
240
+
223
241
  List<(Component component, Color color)> colorBuffer = Buffers<(
224
242
  Component component,
225
243
  Color color
226
244
  )>.List;
227
245
  colorBuffer.Clear();
228
- colorBuffer.AddRange(_colorStackCache);
246
+ foreach ((Component component, Color color) entry in _colorStackCache)
247
+ {
248
+ colorBuffer.Add(entry);
249
+ }
229
250
  for (int i = 1; i < colorBuffer.Count; ++i)
230
251
  {
231
252
  (Component component, Color color) entry = colorBuffer[i];
@@ -233,13 +254,20 @@
233
254
  }
234
255
 
235
256
  _materialStack.Clear();
236
- _materialStack.Add(_materialStackCache[0]);
257
+ if (0 < _materialStackCache.Count)
258
+ {
259
+ _materialStack.Add(_materialStackCache[0]);
260
+ }
261
+
237
262
  List<(Component component, Material material)> materialBuffer = Buffers<(
238
263
  Component component,
239
264
  Material material
240
265
  )>.List;
241
266
  materialBuffer.Clear();
242
- materialBuffer.AddRange(_materialStackCache);
267
+ foreach ((Component component, Material material) entry in _materialStackCache)
268
+ {
269
+ materialBuffer.Add(entry);
270
+ }
243
271
  for (int i = 1; i < materialBuffer.Count; ++i)
244
272
  {
245
273
  (Component component, Material material) entry = materialBuffer[i];
@@ -254,21 +282,30 @@
254
282
  Color color
255
283
  )>.List;
256
284
  colorBuffer.Clear();
257
- colorBuffer.AddRange(_colorStack);
285
+ foreach ((Component component, Color color) entry in _colorStack)
286
+ {
287
+ colorBuffer.Add(entry);
288
+ }
258
289
  for (int i = colorBuffer.Count - 1; 1 <= i; --i)
259
290
  {
260
291
  PopColor(colorBuffer[i].component);
261
292
  }
262
293
 
263
294
  _colorStackCache.Clear();
264
- _colorStackCache.AddRange(colorBuffer);
295
+ foreach ((Component component, Color color) entry in colorBuffer)
296
+ {
297
+ _colorStackCache.Add(entry);
298
+ }
265
299
 
266
300
  List<(Component component, Material material)> materialBuffer = Buffers<(
267
301
  Component component,
268
302
  Material material
269
303
  )>.List;
270
304
  materialBuffer.Clear();
271
- materialBuffer.AddRange(_materialStack);
305
+ foreach ((Component component, Material material) entry in _materialStack)
306
+ {
307
+ materialBuffer.Add(entry);
308
+ }
272
309
 
273
310
  for (int i = materialBuffer.Count - 1; 1 <= i; --i)
274
311
  {
@@ -276,7 +313,10 @@
276
313
  }
277
314
 
278
315
  _materialStackCache.Clear();
279
- _materialStackCache.AddRange(materialBuffer);
316
+ foreach ((Component component, Material material) entry in materialBuffer)
317
+ {
318
+ _materialStackCache.Add(entry);
319
+ }
280
320
  }
281
321
 
282
322
  private void RemoveColor(Component component)
@@ -286,12 +326,23 @@
286
326
  return;
287
327
  }
288
328
 
289
- _ = _colorStack.RemoveAll(existingComponent =>
290
- existingComponent.component == component || existingComponent.component == null
291
- );
292
- _ = _colorStackCache.RemoveAll(existingComponent =>
293
- existingComponent.component == component || existingComponent.component == null
294
- );
329
+ for (int i = _colorStack.Count - 1; 0 <= i; --i)
330
+ {
331
+ (Component component, Color color) stackEntry = _colorStack[i];
332
+ if (stackEntry.component == component || stackEntry.component == null)
333
+ {
334
+ _colorStack.RemoveAt(i);
335
+ }
336
+ }
337
+
338
+ for (int i = _colorStackCache.Count - 1; 0 <= i; --i)
339
+ {
340
+ (Component component, Color color) stackEntry = _colorStackCache[i];
341
+ if (stackEntry.component == component || stackEntry.component == null)
342
+ {
343
+ _colorStackCache.RemoveAt(i);
344
+ }
345
+ }
295
346
  }
296
347
 
297
348
  private void RemoveMaterial(Component component)
@@ -301,12 +352,23 @@
301
352
  return;
302
353
  }
303
354
 
304
- _ = _materialStack.RemoveAll(existingComponent =>
305
- existingComponent.component == component || existingComponent.component == null
306
- );
307
- _ = _materialStackCache.RemoveAll(existingComponent =>
308
- existingComponent.component == component || existingComponent.component == null
309
- );
355
+ for (int i = _materialStack.Count - 1; 0 <= i; --i)
356
+ {
357
+ (Component component, Material material) stackEntry = _materialStack[i];
358
+ if (stackEntry.component == component || stackEntry.component == null)
359
+ {
360
+ _materialStack.RemoveAt(i);
361
+ }
362
+ }
363
+
364
+ for (int i = _materialStackCache.Count - 1; 0 <= i; --i)
365
+ {
366
+ (Component component, Material material) stackEntry = _materialStackCache[i];
367
+ if (stackEntry.component == component || stackEntry.component == null)
368
+ {
369
+ _materialStackCache.RemoveAt(i);
370
+ }
371
+ }
310
372
  }
311
373
  }
312
374
  }
@@ -10,13 +10,13 @@
10
10
  [Test]
11
11
  public void Benchmark()
12
12
  {
13
- TimeSpan timeout = TimeSpan.FromSeconds(1.125);
13
+ TimeSpan timeout = TimeSpan.FromSeconds(1);
14
14
 
15
15
  UnityEngine.Debug.Log(
16
- $"| Random | NextBool | Next | NextUInt | NextFloat | NextDouble | NextUint - Range | "
16
+ "| Random | NextBool | Next | NextUInt | NextFloat | NextDouble | NextUint - Range | NextInt - Range |"
17
17
  );
18
18
  UnityEngine.Debug.Log(
19
- $"| ------ | -------- | ---- | -------- | --------- | ---------- | ---------------- |"
19
+ "| ------ | -------- | ---- | -------- | --------- | ---------- | ---------------- | --------------- |"
20
20
  );
21
21
 
22
22
  RunTest(new PcgRandom(), timeout);
@@ -28,6 +28,8 @@
28
28
  RunTest(new SplitMix64(), timeout);
29
29
  RunTest(new RomuDuo(), timeout);
30
30
  RunTest(new XorShiroRandom(), timeout);
31
+ RunTest(new UnityRandom(), timeout);
32
+ RunTest(new LinearCongruentialGenerator(), timeout);
31
33
  }
32
34
 
33
35
  private static void RunTest<T>(T random, TimeSpan timeout)
@@ -39,6 +41,7 @@
39
41
  int nextFloat = RunNextFloat(timeout, random);
40
42
  int nextDouble = RunNextDouble(timeout, random);
41
43
  int nextUintRange = RunNextUintRange(timeout, random);
44
+ int nextIntRange = RunNextIntRange(timeout, random);
42
45
 
43
46
  UnityEngine.Debug.Log(
44
47
  $"| {random.GetType().Name} | "
@@ -48,6 +51,7 @@
48
51
  + $"{(nextFloat / timeout.TotalSeconds):N0} | "
49
52
  + $"{(nextDouble / timeout.TotalSeconds):N0} |"
50
53
  + $"{(nextUintRange / timeout.TotalSeconds):N0} |"
54
+ + $"{(nextIntRange / timeout.TotalSeconds):N0} |"
51
55
  );
52
56
  }
53
57
 
@@ -108,6 +112,20 @@
108
112
  return count;
109
113
  }
110
114
 
115
+ private static int RunNextIntRange<T>(TimeSpan timeout, T random)
116
+ where T : IRandom
117
+ {
118
+ int count = 0;
119
+ Stopwatch timer = Stopwatch.StartNew();
120
+ do
121
+ {
122
+ _ = random.Next(1_000);
123
+ ++count;
124
+ } while (timer.Elapsed < timeout);
125
+
126
+ return count;
127
+ }
128
+
111
129
  private static int RunNextFloat<T>(TimeSpan timeout, T random)
112
130
  where T : IRandom
113
131
  {
@@ -0,0 +1,12 @@
1
+ namespace UnityHelpers.Tests.Random
2
+ {
3
+ using Core.Random;
4
+
5
+ public sealed class LinearCongruentialGeneratorTests : RandomTestBase
6
+ {
7
+ protected override IRandom NewRandom()
8
+ {
9
+ return new LinearCongruentialGenerator();
10
+ }
11
+ }
12
+ }
@@ -0,0 +1,3 @@
1
+ fileFormatVersion: 2
2
+ guid: 7859c541d79a4af7893bd98abfe7fea8
3
+ timeCreated: 1742702856
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "com.wallstop-studios.unity-helpers",
3
- "version": "2.0.0-rc43",
3
+ "version": "2.0.0-rc44",
4
4
  "displayName": "Unity Helpers",
5
5
  "description": "Various Unity Helper Library",
6
6
  "dependencies": {},