diff --git a/ScriptCore/Math/Random.cs b/ScriptCore/Math/Random.cs index 66bd1ea..5429415 100644 --- a/ScriptCore/Math/Random.cs +++ b/ScriptCore/Math/Random.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; namespace GlitchyEngine.Math; @@ -31,4 +32,13 @@ public static class RandomExtension /// A 32-bit signed integer greater than or equal to and less than ; that is, the range of return values includes but not . If equals , is returned. /// is greater than . public static double Range(this Random random, double min, double max) => random.NextDouble() * (max - min) + min; + + /// + /// Picks a random element from the given list. + /// + /// + /// The list to pick an element from. + /// The type of elements in the list. + /// The randomly picked element. + public static T Pick(this Random random, IList list) => list[random.Range(0, list.Count)]; } diff --git a/ScriptCore/Math/ThreadSafeRandom.cs b/ScriptCore/Math/ThreadSafeRandom.cs new file mode 100644 index 0000000..f6c14fa --- /dev/null +++ b/ScriptCore/Math/ThreadSafeRandom.cs @@ -0,0 +1,38 @@ +using System; + +namespace GlitchyEngine.Math; + +/// +/// A thread safe global random number generator. +/// +/// +/// Based on https://andrewlock.net/building-a-thread-safe-random-implementation-for-dotnet-framework/ +/// +public static class ThreadSafeRandom +{ + [ThreadStatic] + private static Random? _local; + private static readonly Random Global = new(); + + /// + /// Gets a thread safe random number generator. + /// + public static Random Instance + { + get + { + if (_local is null) + { + int seed; + lock (Global) + { + seed = Global.Next(); + } + + _local = new Random(seed); + } + + return _local; + } + } +}