PKHeX/PKHeX.Core/Legality/Structures/IVersion.cs
Kurt c301ce88ab Update Random to be a bit more thread safe
Random isn't thread safe; users of PKHeX.Core.dll might run multithreaded operations (see PKSM + ALM), so we need to have a thread-specific RNG available.

Thread Local get; to improve performance, save the random object locally whenever it is used more than once in the method.

https://docs.microsoft.com/en-us/dotnet/api/system.threading.threadlocal-1?redirectedfrom=MSDN&view=netframework-4.8
https://stackoverflow.com/questions/18333885/threadstatic-v-s-threadlocalt-is-generic-better-than-attribute/18337158#18337158
2020-01-25 21:49:52 -08:00

50 lines
1.5 KiB
C#

using System.Collections.Generic;
namespace PKHeX.Core
{
public interface IVersion
{
GameVersion Version { get; set; }
}
public static partial class Extensions
{
public static bool CanBeReceivedBy(this IVersion ver, GameVersion game) => ver.Version.Contains(game);
public static GameVersion GetCompatibleVersion(this IVersion ver, GameVersion prefer)
{
if (ver.CanBeReceivedBy(prefer) || ver.Version <= GameVersion.Unknown)
return prefer;
return ver.GetSingleVersion();
}
internal static void SetVersion(this IEnumerable<IVersion> arr, GameVersion game)
{
foreach (var z in arr)
{
if (z.Version <= 0)
z.Version = game;
}
}
internal static void SetVersion(this IEnumerable<EncounterArea> arr, GameVersion game)
{
foreach (var area in arr)
area.Slots.SetVersion(game);
}
private static GameVersion GetSingleVersion(this IVersion ver)
{
const int max = (int) GameVersion.RB;
if ((int)ver.Version < max)
return ver.Version;
var rnd = Util.Rand;
while (true) // this isn't optimal, but is low maintenance
{
var game = (GameVersion)rnd.Next(1, max);
if (ver.CanBeReceivedBy(game))
return game;
}
}
}
}