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 +16 -0
- package/Runtime/Core/Helper/FormattingHelpers.cs +32 -0
- package/Runtime/Core/Helper/FormattingHelpers.cs.meta +3 -0
- package/Runtime/Core/Random/AbstractRandom.cs +6 -5
- package/Runtime/Core/Random/DotNetRandom.cs +2 -0
- package/Runtime/Core/Random/IRandom.cs +1 -0
- package/Runtime/Core/Random/LinearCongruentialGenerator.cs +49 -0
- package/Runtime/Core/Random/LinearCongruentialGenerator.cs.meta +3 -0
- package/Runtime/Core/Random/PcgRandom.cs +1 -1
- package/Runtime/Core/Random/RomuDuo.cs +1 -1
- package/Runtime/Core/Random/SplitMix64.cs +1 -1
- package/Runtime/Core/Random/SystemRandom.cs +1 -1
- package/Runtime/Core/Random/WyRandom.cs +1 -1
- package/Runtime/Core/Random/XorShiftRandom.cs +13 -8
- package/Runtime/Core/Random/XorShiroRandom.cs +2 -0
- package/Runtime/UI/LayeredImage.cs +2 -2
- package/Runtime/Utils/SpriteRendererMetadata.cs +104 -42
- package/Tests/Runtime/Performance/RandomPerformanceTests.cs +21 -3
- package/Tests/Runtime/Random/LinearCongruentialGeneratorTests.cs +12 -0
- package/Tests/Runtime/Random/LinearCongruentialGeneratorTests.cs.meta +3 -0
- package/package.json +1 -1
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
|
+
}
|
|
@@ -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
|
|
|
@@ -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
|
+
}
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
IComparable,
|
|
16
16
|
IComparable<PcgRandom>
|
|
17
17
|
{
|
|
18
|
-
public static
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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()
|
|
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
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
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()
|
|
@@ -176,7 +176,7 @@
|
|
|
176
176
|
int maxY = int.MinValue;
|
|
177
177
|
foreach (AnimatedSpriteLayer layer in _layers)
|
|
178
178
|
{
|
|
179
|
-
if (
|
|
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 (
|
|
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 =>
|
|
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 && !
|
|
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 && !
|
|
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
|
-
|
|
86
|
-
if (index < 0)
|
|
88
|
+
foreach ((Component component, Color color) entry in _colorStack)
|
|
87
89
|
{
|
|
88
|
-
|
|
89
|
-
|
|
90
|
+
if (entry.component == component)
|
|
91
|
+
{
|
|
92
|
+
color = entry.color;
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
90
95
|
}
|
|
91
96
|
|
|
92
|
-
color =
|
|
93
|
-
return
|
|
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
|
|
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 && !
|
|
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
|
|
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 && !
|
|
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
|
-
|
|
190
|
-
if (index < 0)
|
|
194
|
+
foreach ((Component component, Material material) entry in _materialStack)
|
|
191
195
|
{
|
|
192
|
-
|
|
193
|
-
|
|
196
|
+
if (entry.component == component)
|
|
197
|
+
{
|
|
198
|
+
material = entry.material;
|
|
199
|
+
return true;
|
|
200
|
+
}
|
|
194
201
|
}
|
|
195
|
-
|
|
196
|
-
|
|
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
|
-
|
|
215
|
+
foreach ((Component component, Color color) entry in _colorStack)
|
|
216
|
+
{
|
|
217
|
+
_colorStackCache.Add(entry);
|
|
218
|
+
}
|
|
208
219
|
_ = InternalPushMaterial(this, _spriteRenderer.material);
|
|
209
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
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
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
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
|
|
13
|
+
TimeSpan timeout = TimeSpan.FromSeconds(1);
|
|
14
14
|
|
|
15
15
|
UnityEngine.Debug.Log(
|
|
16
|
-
|
|
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
|
{
|