com.wallstop-studios.unity-helpers 2.0.4 → 2.1.1
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/Docs/DATA_STRUCTURES.md +7 -7
- package/Docs/EFFECTS_SYSTEM.md +836 -8
- package/Docs/EFFECTS_SYSTEM_TUTORIAL.md +77 -18
- package/Docs/HULLS.md +2 -2
- package/Docs/ILIST_SORTING_PERFORMANCE.md +92 -0
- package/Docs/ILIST_SORTING_PERFORMANCE.md.meta +7 -0
- package/Docs/INDEX.md +10 -1
- package/Docs/Images/random_generators.svg +7 -7
- package/Docs/RANDOM_PERFORMANCE.md +18 -15
- package/Docs/REFLECTION_HELPERS.md +1 -1
- package/Docs/RELATIONAL_COMPONENTS.md +51 -6
- package/Docs/SERIALIZATION.md +1 -1
- package/Docs/SINGLETONS.md +2 -2
- package/Docs/SPATIAL_TREES_2D_GUIDE.md +3 -3
- package/Docs/SPATIAL_TREES_3D_GUIDE.md +3 -3
- package/Docs/SPATIAL_TREE_2D_PERFORMANCE.md +64 -64
- package/Docs/SPATIAL_TREE_3D_PERFORMANCE.md +64 -64
- package/Docs/SPATIAL_TREE_SEMANTICS.md +7 -7
- package/Editor/Core/Helper/AnimationEventHelpers.cs +1 -1
- package/Editor/CustomDrawers/WShowIfPropertyDrawer.cs +131 -41
- package/Editor/Utils/ScriptableObjectSingletonCreator.cs +175 -18
- package/README.md +42 -18
- package/Runtime/Core/Extension/IListExtensions.cs +720 -12
- package/Runtime/Core/Helper/UnityMainThreadDispatcher.cs +2 -3
- package/Runtime/Core/Random/AbstractRandom.cs +52 -5
- package/Runtime/Core/Random/DotNetRandom.cs +3 -3
- package/Runtime/Core/Random/FlurryBurstRandom.cs +285 -0
- package/Runtime/Core/Random/FlurryBurstRandom.cs.meta +3 -0
- package/Runtime/Core/Random/IllusionFlow.cs +3 -3
- package/Runtime/Core/Random/LinearCongruentialGenerator.cs +3 -3
- package/Runtime/Core/Random/PcgRandom.cs +6 -6
- package/Runtime/Core/Random/PhotonSpinRandom.cs +387 -0
- package/Runtime/Core/Random/PhotonSpinRandom.cs.meta +3 -0
- package/Runtime/Core/Random/RomuDuo.cs +3 -3
- package/Runtime/Core/Random/SplitMix64.cs +3 -3
- package/Runtime/Core/Random/SquirrelRandom.cs +6 -4
- package/Runtime/Core/Random/StormDropRandom.cs +271 -0
- package/Runtime/Core/Random/StormDropRandom.cs.meta +3 -0
- package/Runtime/Core/Random/UnityRandom.cs +3 -3
- package/Runtime/Core/Random/WyRandom.cs +6 -4
- package/Runtime/Core/Random/XorShiftRandom.cs +3 -3
- package/Runtime/Core/Random/XoroShiroRandom.cs +3 -3
- package/Runtime/Tags/Attribute.cs +144 -24
- package/Runtime/Tags/AttributeEffect.cs +119 -16
- package/Runtime/Tags/AttributeMetadataCache.cs +312 -3
- package/Runtime/Tags/AttributeModification.cs +59 -29
- package/Runtime/Tags/AttributesComponent.cs +20 -0
- package/Runtime/Tags/EffectBehavior.cs +171 -0
- package/Runtime/Tags/EffectBehavior.cs.meta +4 -0
- package/Runtime/Tags/EffectHandle.cs +5 -0
- package/Runtime/Tags/EffectHandler.cs +385 -39
- package/Runtime/Tags/EffectStackKey.cs +79 -0
- package/Runtime/Tags/EffectStackKey.cs.meta +4 -0
- package/Runtime/Tags/PeriodicEffectDefinition.cs +102 -0
- package/Runtime/Tags/PeriodicEffectDefinition.cs.meta +4 -0
- package/Runtime/Tags/PeriodicEffectRuntimeState.cs +40 -0
- package/Runtime/Tags/PeriodicEffectRuntimeState.cs.meta +4 -0
- package/Samples~/DI - Zenject/README.md +0 -2
- package/Tests/Editor/Attributes/WShowIfPropertyDrawerTests.cs +285 -0
- package/Tests/Editor/Attributes/WShowIfPropertyDrawerTests.cs.meta +11 -0
- package/Tests/Editor/Core/Attributes/RelationalComponentAssignerTests.cs +2 -2
- package/Tests/Editor/Tags/AttributeMetadataCacheTests.cs +192 -0
- package/Tests/Editor/Tags/AttributeMetadataCacheTests.cs.meta +11 -0
- package/{node_modules.meta → Tests/Editor/Tags.meta} +1 -1
- package/Tests/Editor/Utils/ScriptableObjectSingletonTests.cs +41 -0
- package/Tests/Runtime/Extensions/IListExtensionTests.cs +187 -1
- package/Tests/Runtime/Helper/ObjectsTests.cs +3 -3
- package/Tests/Runtime/Integrations/Reflex/RelationalComponentsReflexTests.cs +2 -2
- package/Tests/Runtime/Performance/IListSortingPerformanceTests.cs +346 -0
- package/Tests/Runtime/Performance/IListSortingPerformanceTests.cs.meta +11 -0
- package/Tests/Runtime/Performance/RandomPerformanceTests.cs +3 -0
- package/Tests/Runtime/Random/FlurryBurstRandomTests.cs +12 -0
- package/Tests/Runtime/Random/FlurryBurstRandomTests.cs.meta +3 -0
- package/Tests/Runtime/Random/PhotonSpinRandomTests.cs +12 -0
- package/Tests/Runtime/Random/PhotonSpinRandomTests.cs.meta +3 -0
- package/Tests/Runtime/Random/RandomProtoSerializationTests.cs +14 -0
- package/Tests/Runtime/Random/RandomTestBase.cs +39 -4
- package/Tests/Runtime/Random/StormDropRandomTests.cs +12 -0
- package/Tests/Runtime/Random/StormDropRandomTests.cs.meta +3 -0
- package/Tests/Runtime/Serialization/JsonSerializationTest.cs +4 -3
- package/Tests/Runtime/Serialization/ProtoInterfaceResolutionEdgeTests.cs +2 -2
- package/Tests/Runtime/Serialization/ProtoRootRegistrationTests.cs +1 -1
- package/Tests/Runtime/Serialization/ProtoSerializeBehaviorTests.cs +1 -1
- package/Tests/Runtime/Tags/AttributeEffectTests.cs +135 -0
- package/Tests/Runtime/Tags/AttributeEffectTests.cs.meta +3 -0
- package/Tests/Runtime/Tags/AttributeModificationTests.cs +137 -0
- package/Tests/Runtime/Tags/AttributeTests.cs +192 -0
- package/Tests/Runtime/Tags/AttributeTests.cs.meta +3 -0
- package/Tests/Runtime/Tags/EffectBehaviorTests.cs +184 -0
- package/Tests/Runtime/Tags/EffectBehaviorTests.cs.meta +3 -0
- package/Tests/Runtime/Tags/EffectHandlerTests.cs +618 -0
- package/Tests/Runtime/Tags/Helpers/RecordingEffectBehavior.cs +89 -0
- package/Tests/Runtime/Tags/Helpers/RecordingEffectBehavior.cs.meta +4 -0
- package/Tests/Runtime/Tags/PeriodicEffectDefinitionSerializationTests.cs +92 -0
- package/Tests/Runtime/Tags/PeriodicEffectDefinitionSerializationTests.cs.meta +3 -0
- package/package.json +1 -1
- package/scripts/lint-doc-links.ps1 +156 -11
- package/Tests/Runtime/Tags/AttributeDataTests.cs +0 -312
- /package/Tests/Runtime/Tags/{AttributeDataTests.cs.meta → AttributeModificationTests.cs.meta} +0 -0
|
@@ -105,8 +105,7 @@ namespace WallstopStudios.UnityHelpers.Core.Helper
|
|
|
105
105
|
/// </summary>
|
|
106
106
|
public System.Threading.Tasks.Task RunAsync(Action action)
|
|
107
107
|
{
|
|
108
|
-
TaskCompletionSource<bool> tcs =
|
|
109
|
-
new System.Threading.Tasks.TaskCompletionSource<bool>();
|
|
108
|
+
TaskCompletionSource<bool> tcs = new();
|
|
110
109
|
RunOnMainThread(() =>
|
|
111
110
|
{
|
|
112
111
|
try
|
|
@@ -127,7 +126,7 @@ namespace WallstopStudios.UnityHelpers.Core.Helper
|
|
|
127
126
|
/// </summary>
|
|
128
127
|
public System.Threading.Tasks.Task<T> Post<T>(Func<T> func)
|
|
129
128
|
{
|
|
130
|
-
TaskCompletionSource<T> tcs = new
|
|
129
|
+
TaskCompletionSource<T> tcs = new();
|
|
131
130
|
RunOnMainThread(() =>
|
|
132
131
|
{
|
|
133
132
|
try
|
|
@@ -15,9 +15,6 @@ namespace WallstopStudios.UnityHelpers.Core.Random
|
|
|
15
15
|
using Extension;
|
|
16
16
|
#endif
|
|
17
17
|
|
|
18
|
-
[Serializable]
|
|
19
|
-
[DataContract]
|
|
20
|
-
[ProtoContract]
|
|
21
18
|
/// <summary>
|
|
22
19
|
/// Common abstract base for all <see cref="IRandom"/> implementations with protobuf support.
|
|
23
20
|
/// </summary>
|
|
@@ -58,6 +55,9 @@ namespace WallstopStudios.UnityHelpers.Core.Random
|
|
|
58
55
|
/// then use Serializer.ProtoDeserialize<IRandom>.</description></item>
|
|
59
56
|
/// </list>
|
|
60
57
|
/// </remarks>
|
|
58
|
+
[Serializable]
|
|
59
|
+
[DataContract]
|
|
60
|
+
[ProtoContract]
|
|
61
61
|
[ProtoInclude(100, typeof(DotNetRandom))]
|
|
62
62
|
[ProtoInclude(101, typeof(PcgRandom))]
|
|
63
63
|
[ProtoInclude(102, typeof(XorShiftRandom))]
|
|
@@ -70,6 +70,9 @@ namespace WallstopStudios.UnityHelpers.Core.Random
|
|
|
70
70
|
[ProtoInclude(109, typeof(RomuDuo))]
|
|
71
71
|
[ProtoInclude(110, typeof(SplitMix64))]
|
|
72
72
|
[ProtoInclude(111, typeof(IllusionFlow))]
|
|
73
|
+
[ProtoInclude(112, typeof(FlurryBurstRandom))]
|
|
74
|
+
[ProtoInclude(113, typeof(PhotonSpinRandom))]
|
|
75
|
+
[ProtoInclude(114, typeof(StormDropRandom))]
|
|
73
76
|
public abstract class AbstractRandom : IRandom
|
|
74
77
|
{
|
|
75
78
|
#if SINGLE_THREADED
|
|
@@ -107,13 +110,37 @@ namespace WallstopStudios.UnityHelpers.Core.Random
|
|
|
107
110
|
protected int _byteCount;
|
|
108
111
|
|
|
109
112
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
110
|
-
protected RandomState BuildState(
|
|
113
|
+
protected RandomState BuildState(
|
|
114
|
+
ulong state1,
|
|
115
|
+
ulong state2 = 0,
|
|
116
|
+
IReadOnlyList<byte> payload = null
|
|
117
|
+
)
|
|
111
118
|
{
|
|
119
|
+
byte[] payloadCopy = null;
|
|
120
|
+
if (payload != null)
|
|
121
|
+
{
|
|
122
|
+
if (payload is byte[] payloadArray)
|
|
123
|
+
{
|
|
124
|
+
int length = payloadArray.Length;
|
|
125
|
+
payloadCopy = new byte[length];
|
|
126
|
+
Buffer.BlockCopy(payloadArray, 0, payloadCopy, 0, length);
|
|
127
|
+
}
|
|
128
|
+
else
|
|
129
|
+
{
|
|
130
|
+
int count = payload.Count;
|
|
131
|
+
payloadCopy = new byte[count];
|
|
132
|
+
for (int i = 0; i < count; ++i)
|
|
133
|
+
{
|
|
134
|
+
payloadCopy[i] = payload[i];
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
112
139
|
return new RandomState(
|
|
113
140
|
state1,
|
|
114
141
|
state2,
|
|
115
142
|
_cachedGaussian,
|
|
116
|
-
payload:
|
|
143
|
+
payload: payloadCopy,
|
|
117
144
|
bitBuffer: _bitBuffer,
|
|
118
145
|
bitCount: _bitCount,
|
|
119
146
|
byteBuffer: _byteBuffer,
|
|
@@ -1314,5 +1341,25 @@ namespace WallstopStudios.UnityHelpers.Core.Random
|
|
|
1314
1341
|
}
|
|
1315
1342
|
|
|
1316
1343
|
public abstract IRandom Copy();
|
|
1344
|
+
|
|
1345
|
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
1346
|
+
protected internal static uint RotateLeft(uint value, int count)
|
|
1347
|
+
{
|
|
1348
|
+
return (value << count) | (value >> (32 - count));
|
|
1349
|
+
}
|
|
1350
|
+
|
|
1351
|
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
1352
|
+
protected internal static uint Mix32(ref ulong state)
|
|
1353
|
+
{
|
|
1354
|
+
unchecked
|
|
1355
|
+
{
|
|
1356
|
+
state += 0x9E3779B97F4A7C15UL;
|
|
1357
|
+
ulong z = state;
|
|
1358
|
+
z = (z ^ (z >> 30)) * 0xBF58476D1CE4E5B9UL;
|
|
1359
|
+
z = (z ^ (z >> 27)) * 0x94D049BB133111EBUL;
|
|
1360
|
+
z ^= z >> 31;
|
|
1361
|
+
return (uint)z;
|
|
1362
|
+
}
|
|
1363
|
+
}
|
|
1317
1364
|
}
|
|
1318
1365
|
}
|
|
@@ -5,9 +5,6 @@ namespace WallstopStudios.UnityHelpers.Core.Random
|
|
|
5
5
|
using System.Text.Json.Serialization;
|
|
6
6
|
using ProtoBuf;
|
|
7
7
|
|
|
8
|
-
[Serializable]
|
|
9
|
-
[DataContract]
|
|
10
|
-
[ProtoContract(SkipConstructor = true)]
|
|
11
8
|
/// <summary>
|
|
12
9
|
/// A thin wrapper around <c>System.Random</c> that exposes the <see cref="IRandom"/> API and supports state capture.
|
|
13
10
|
/// </summary>
|
|
@@ -46,6 +43,9 @@ namespace WallstopStudios.UnityHelpers.Core.Random
|
|
|
46
43
|
/// float f = compat.NextFloat();
|
|
47
44
|
/// </code>
|
|
48
45
|
/// </example>
|
|
46
|
+
[Serializable]
|
|
47
|
+
[DataContract]
|
|
48
|
+
[ProtoContract(SkipConstructor = true)]
|
|
49
49
|
public sealed class DotNetRandom : AbstractRandom
|
|
50
50
|
{
|
|
51
51
|
public static DotNetRandom Instance => ThreadLocalRandom<DotNetRandom>.Instance;
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
namespace WallstopStudios.UnityHelpers.Core.Random
|
|
2
|
+
{
|
|
3
|
+
using System;
|
|
4
|
+
using System.Buffers.Binary;
|
|
5
|
+
using System.Runtime.CompilerServices;
|
|
6
|
+
using System.Runtime.Serialization;
|
|
7
|
+
using System.Text.Json.Serialization;
|
|
8
|
+
using Extension;
|
|
9
|
+
using Helper;
|
|
10
|
+
using ProtoBuf;
|
|
11
|
+
using WallstopStudios.UnityHelpers.Utils;
|
|
12
|
+
|
|
13
|
+
/// <summary>
|
|
14
|
+
/// FlurryBurst32: a six-word ARX-style generator offering high quality and excellent parallel sequencing.
|
|
15
|
+
/// </summary>
|
|
16
|
+
/// <remarks>
|
|
17
|
+
/// <para>
|
|
18
|
+
/// https://github.com/wileylooper/flurryburst
|
|
19
|
+
/// Based on <c>wileylooper/flurryburst</c>, this implementation captures the 32-bit variant that balances
|
|
20
|
+
/// speed, period (~2<sup>128</sup>) and state size for gameplay workloads. It is suitable as a drop-in
|
|
21
|
+
/// alternative to Xoshiro128** and similar families, while retaining deterministic serialization support.
|
|
22
|
+
/// </para>
|
|
23
|
+
/// <para>Pros:</para>
|
|
24
|
+
/// <list type="bullet">
|
|
25
|
+
/// <item><description>Small state (6×32-bit) with excellent statistical behaviour.</description></item>
|
|
26
|
+
/// <item><description>Deterministic snapshots via <see cref="RandomState"/> and protobuf/JSON.</description></item>
|
|
27
|
+
/// <item><description>Easy to create parallel streams by varying the <c>d</c> word.</description></item>
|
|
28
|
+
/// </list>
|
|
29
|
+
/// <para>Cons:</para>
|
|
30
|
+
/// <list type="bullet">
|
|
31
|
+
/// <item><description>Not cryptographically secure.</description></item>
|
|
32
|
+
/// <item><description>Requires a short warm-up (performed automatically) to avoid transient bias.</description></item>
|
|
33
|
+
/// </list>
|
|
34
|
+
/// <para>When to use:</para>
|
|
35
|
+
/// <list type="bullet">
|
|
36
|
+
/// <item><description>Deterministic gameplay, procedural content, Monte-Carlo style sampling.</description></item>
|
|
37
|
+
/// </list>
|
|
38
|
+
/// <para>When not to use:</para>
|
|
39
|
+
/// <list type="bullet">
|
|
40
|
+
/// <item><description>Security/adversarial contexts.</description></item>
|
|
41
|
+
/// </list>
|
|
42
|
+
/// </remarks>
|
|
43
|
+
/// <example>
|
|
44
|
+
/// <code>
|
|
45
|
+
/// using WallstopStudios.UnityHelpers.Core.Random;
|
|
46
|
+
///
|
|
47
|
+
/// IRandom rng = new FlurryBurstRandom(seed: 123u);
|
|
48
|
+
/// int value = rng.Next(0, 100);
|
|
49
|
+
/// float weight = rng.NextFloat();
|
|
50
|
+
/// </code>
|
|
51
|
+
/// </example>
|
|
52
|
+
[Serializable]
|
|
53
|
+
[DataContract]
|
|
54
|
+
[ProtoContract]
|
|
55
|
+
public sealed class FlurryBurstRandom
|
|
56
|
+
: AbstractRandom,
|
|
57
|
+
IEquatable<FlurryBurstRandom>,
|
|
58
|
+
IComparable,
|
|
59
|
+
IComparable<FlurryBurstRandom>
|
|
60
|
+
{
|
|
61
|
+
private const uint Increment = 1_111_111_111U;
|
|
62
|
+
private const int PayloadByteCount = sizeof(uint) * 2;
|
|
63
|
+
|
|
64
|
+
public static FlurryBurstRandom Instance => ThreadLocalRandom<FlurryBurstRandom>.Instance;
|
|
65
|
+
|
|
66
|
+
public override RandomState InternalState
|
|
67
|
+
{
|
|
68
|
+
get
|
|
69
|
+
{
|
|
70
|
+
ulong state1 = ((ulong)_a << 32) | _b;
|
|
71
|
+
ulong state2 = ((ulong)_c << 32) | _d;
|
|
72
|
+
using PooledResource<byte[]> payloadLease = WallstopArrayPool<byte>.Get(
|
|
73
|
+
PayloadByteCount,
|
|
74
|
+
out byte[] buffer
|
|
75
|
+
);
|
|
76
|
+
Span<byte> payload = buffer.AsSpan(0, PayloadByteCount);
|
|
77
|
+
BinaryPrimitives.WriteUInt32LittleEndian(payload.Slice(0, sizeof(uint)), _e);
|
|
78
|
+
BinaryPrimitives.WriteUInt32LittleEndian(
|
|
79
|
+
payload.Slice(sizeof(uint), sizeof(uint)),
|
|
80
|
+
_f
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
return BuildState(
|
|
84
|
+
state1,
|
|
85
|
+
state2,
|
|
86
|
+
new ArraySegment<byte>(buffer, 0, PayloadByteCount)
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
[ProtoMember(6)]
|
|
92
|
+
private uint _a;
|
|
93
|
+
|
|
94
|
+
[ProtoMember(7)]
|
|
95
|
+
private uint _b;
|
|
96
|
+
|
|
97
|
+
[ProtoMember(8)]
|
|
98
|
+
private uint _c;
|
|
99
|
+
|
|
100
|
+
[ProtoMember(9)]
|
|
101
|
+
private uint _d;
|
|
102
|
+
|
|
103
|
+
[ProtoMember(10)]
|
|
104
|
+
private uint _e;
|
|
105
|
+
|
|
106
|
+
[ProtoMember(11)]
|
|
107
|
+
private uint _f;
|
|
108
|
+
|
|
109
|
+
public FlurryBurstRandom()
|
|
110
|
+
: this(Guid.NewGuid()) { }
|
|
111
|
+
|
|
112
|
+
public FlurryBurstRandom(Guid guid)
|
|
113
|
+
{
|
|
114
|
+
InitializeFromGuid(guid);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
[JsonConstructor]
|
|
118
|
+
public FlurryBurstRandom(RandomState internalState)
|
|
119
|
+
{
|
|
120
|
+
ulong state1 = internalState.State1;
|
|
121
|
+
ulong state2 = internalState.State2;
|
|
122
|
+
_a = (uint)(state1 >> 32);
|
|
123
|
+
_b = (uint)state1;
|
|
124
|
+
_c = (uint)(state2 >> 32);
|
|
125
|
+
_d = (uint)state2;
|
|
126
|
+
|
|
127
|
+
byte[] payload = internalState._payload;
|
|
128
|
+
if (payload != null && payload.Length >= sizeof(uint) * 2)
|
|
129
|
+
{
|
|
130
|
+
_e = BinaryPrimitives.ReadUInt32LittleEndian(payload.AsSpan(0, sizeof(uint)));
|
|
131
|
+
_f = BinaryPrimitives.ReadUInt32LittleEndian(
|
|
132
|
+
payload.AsSpan(sizeof(uint), sizeof(uint))
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
else
|
|
136
|
+
{
|
|
137
|
+
_e = 0;
|
|
138
|
+
_f = 0;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
RestoreCommonState(internalState);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
public override uint NextUint()
|
|
145
|
+
{
|
|
146
|
+
unchecked
|
|
147
|
+
{
|
|
148
|
+
uint mix = RotateLeft(_a, 13);
|
|
149
|
+
|
|
150
|
+
_a = _b;
|
|
151
|
+
_b = _e;
|
|
152
|
+
_c += _d;
|
|
153
|
+
_d += _b;
|
|
154
|
+
_e = _f + Increment;
|
|
155
|
+
_f = _c ^ mix;
|
|
156
|
+
|
|
157
|
+
return (_e >> 1) ^ _f;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
public override IRandom Copy()
|
|
162
|
+
{
|
|
163
|
+
return new FlurryBurstRandom(InternalState);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
public override bool Equals(object obj)
|
|
167
|
+
{
|
|
168
|
+
return Equals(obj as FlurryBurstRandom);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
public bool Equals(FlurryBurstRandom other)
|
|
172
|
+
{
|
|
173
|
+
if (other == null)
|
|
174
|
+
{
|
|
175
|
+
return false;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// ReSharper disable once CompareOfFloatsByEqualityOperator
|
|
179
|
+
return _a == other._a
|
|
180
|
+
&& _b == other._b
|
|
181
|
+
&& _c == other._c
|
|
182
|
+
&& _d == other._d
|
|
183
|
+
&& _e == other._e
|
|
184
|
+
&& _f == other._f
|
|
185
|
+
&& _cachedGaussian == other._cachedGaussian;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
public override int GetHashCode()
|
|
189
|
+
{
|
|
190
|
+
return Objects.HashCode(_a, _b, _c, _d, _e, _f);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
public override string ToString()
|
|
194
|
+
{
|
|
195
|
+
return this.ToJson();
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
public int CompareTo(object obj)
|
|
199
|
+
{
|
|
200
|
+
return CompareTo(obj as FlurryBurstRandom);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
public int CompareTo(FlurryBurstRandom other)
|
|
204
|
+
{
|
|
205
|
+
if (other == null)
|
|
206
|
+
{
|
|
207
|
+
return -1;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
int comparison = _a.CompareTo(other._a);
|
|
211
|
+
if (comparison != 0)
|
|
212
|
+
{
|
|
213
|
+
return comparison;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
comparison = _b.CompareTo(other._b);
|
|
217
|
+
if (comparison != 0)
|
|
218
|
+
{
|
|
219
|
+
return comparison;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
comparison = _c.CompareTo(other._c);
|
|
223
|
+
if (comparison != 0)
|
|
224
|
+
{
|
|
225
|
+
return comparison;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
comparison = _d.CompareTo(other._d);
|
|
229
|
+
if (comparison != 0)
|
|
230
|
+
{
|
|
231
|
+
return comparison;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
comparison = _e.CompareTo(other._e);
|
|
235
|
+
if (comparison != 0)
|
|
236
|
+
{
|
|
237
|
+
return comparison;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
return _f.CompareTo(other._f);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
244
|
+
private static uint RotateLeft(uint value, int count)
|
|
245
|
+
{
|
|
246
|
+
return (value << count) | (value >> (32 - count));
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
private void InitializeFromGuid(Guid guid)
|
|
250
|
+
{
|
|
251
|
+
(ulong seed0, ulong seed1) = RandomUtilities.GuidToUInt64Pair(guid);
|
|
252
|
+
InitializeFromUlongs(seed0, seed1);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
private void InitializeFromUlongs(ulong seed0, ulong seed1)
|
|
256
|
+
{
|
|
257
|
+
ulong mixer = seed0 ^ (seed1 << 1) ^ 0x9E3779B97F4A7C15UL;
|
|
258
|
+
|
|
259
|
+
_a = Mix(ref mixer);
|
|
260
|
+
_b = Mix(ref mixer);
|
|
261
|
+
_c = Mix(ref mixer);
|
|
262
|
+
_d = Mix(ref mixer);
|
|
263
|
+
if (_d == 0)
|
|
264
|
+
{
|
|
265
|
+
_d = 1;
|
|
266
|
+
}
|
|
267
|
+
_e = Mix(ref mixer);
|
|
268
|
+
_f = Mix(ref mixer);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
272
|
+
private static uint Mix(ref ulong state)
|
|
273
|
+
{
|
|
274
|
+
unchecked
|
|
275
|
+
{
|
|
276
|
+
state += 0x9E3779B97F4A7C15UL;
|
|
277
|
+
ulong z = state;
|
|
278
|
+
z = (z ^ (z >> 30)) * 0xBF58476D1CE4E5B9UL;
|
|
279
|
+
z = (z ^ (z >> 27)) * 0x94D049BB133111EBUL;
|
|
280
|
+
z ^= z >> 31;
|
|
281
|
+
return (uint)z;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
@@ -13,9 +13,6 @@ namespace WallstopStudios.UnityHelpers.Core.Random
|
|
|
13
13
|
using System.Text.Json.Serialization;
|
|
14
14
|
using ProtoBuf;
|
|
15
15
|
|
|
16
|
-
[Serializable]
|
|
17
|
-
[DataContract]
|
|
18
|
-
[ProtoContract]
|
|
19
16
|
/// <summary>
|
|
20
17
|
/// IllusionFlow: a modern, high-performance PRNG building on Xoroshiro concepts with additional state and mixing.
|
|
21
18
|
/// </summary>
|
|
@@ -60,6 +57,9 @@ namespace WallstopStudios.UnityHelpers.Core.Random
|
|
|
60
57
|
/// var replay = new IllusionFlow(state);
|
|
61
58
|
/// </code>
|
|
62
59
|
/// </example>
|
|
60
|
+
[Serializable]
|
|
61
|
+
[DataContract]
|
|
62
|
+
[ProtoContract]
|
|
63
63
|
public sealed class IllusionFlow : AbstractRandom
|
|
64
64
|
{
|
|
65
65
|
private const int UintByteCount = sizeof(uint) * 8;
|
|
@@ -5,9 +5,6 @@ namespace WallstopStudios.UnityHelpers.Core.Random
|
|
|
5
5
|
using System.Text.Json.Serialization;
|
|
6
6
|
using ProtoBuf;
|
|
7
7
|
|
|
8
|
-
[Serializable]
|
|
9
|
-
[DataContract]
|
|
10
|
-
[ProtoContract]
|
|
11
8
|
/// <summary>
|
|
12
9
|
/// A simple Linear Congruential Generator (LCG): extremely fast with low-quality randomness.
|
|
13
10
|
/// </summary>
|
|
@@ -43,6 +40,9 @@ namespace WallstopStudios.UnityHelpers.Core.Random
|
|
|
43
40
|
/// // Prefer PCG or IllusionFlow for production gameplay.
|
|
44
41
|
/// </code>
|
|
45
42
|
/// </example>
|
|
43
|
+
[Serializable]
|
|
44
|
+
[DataContract]
|
|
45
|
+
[ProtoContract]
|
|
46
46
|
public sealed class LinearCongruentialGenerator : AbstractRandom
|
|
47
47
|
{
|
|
48
48
|
public static LinearCongruentialGenerator Instance =>
|
|
@@ -5,17 +5,14 @@ namespace WallstopStudios.UnityHelpers.Core.Random
|
|
|
5
5
|
using System.Text.Json.Serialization;
|
|
6
6
|
using ProtoBuf;
|
|
7
7
|
|
|
8
|
-
/// <summary>
|
|
9
|
-
/// Implementation based off of the reference PCG Random, found here: https://www.pcg-random.org/index.html
|
|
10
|
-
/// </summary>
|
|
11
|
-
[Serializable]
|
|
12
|
-
[DataContract]
|
|
13
|
-
[ProtoContract]
|
|
14
8
|
/// <summary>
|
|
15
9
|
/// A high-quality, small-state pseudo-random number generator based on the PCG family.
|
|
16
10
|
/// </summary>
|
|
17
11
|
/// <remarks>
|
|
18
12
|
/// <para>
|
|
13
|
+
/// Implementation based off of the reference PCG Random, found here: https://www.pcg-random.org/index.html
|
|
14
|
+
/// </para>
|
|
15
|
+
/// <para>
|
|
19
16
|
/// PCG (Permuted Congruential Generator) offers excellent statistical quality with very small state
|
|
20
17
|
/// and extremely fast generation. This implementation uses a 64-bit state with 32-bit outputs and
|
|
21
18
|
/// an increment (stream selector) to avoid overlapping sequences when constructing multiple instances.
|
|
@@ -96,6 +93,9 @@ namespace WallstopStudios.UnityHelpers.Core.Random
|
|
|
96
93
|
/// // var index = rng.NextWeightedIndex(new float[] { 0.1f, 0.3f, 0.6f });
|
|
97
94
|
/// </code>
|
|
98
95
|
/// </example>
|
|
96
|
+
[Serializable]
|
|
97
|
+
[DataContract]
|
|
98
|
+
[ProtoContract]
|
|
99
99
|
public sealed class PcgRandom
|
|
100
100
|
: AbstractRandom,
|
|
101
101
|
IEquatable<PcgRandom>,
|