mirror of
https://github.com/kwsch/PKHeX
synced 2024-11-23 04:23:12 +00:00
Remove enumerating when loading event templates
Just allocate the parent array and pass it to HashSet; having an ICollection, prevents resizing repeatedly and gc'ing the temp array is cheap. Actually, only create a hashset if we're adding a gift from external DB. Saves on that allocation, and keeps the final result as an array (fastest iterating).
This commit is contained in:
parent
041074f26c
commit
8222297da8
4 changed files with 122 additions and 36 deletions
|
@ -33,52 +33,73 @@ namespace PKHeX.Core
|
|||
/// <summary>Indicates if the databases are initialized.</summary>
|
||||
public static bool Initialized => MGDB_G3.Count != 0;
|
||||
|
||||
private static HashSet<PCD> GetPCDDB(byte[] bin) => new(ArrayUtil.EnumerateSplit(bin, PCD.Size).Select(d => new PCD(d)));
|
||||
private static PCD[] GetPCDDB(byte[] bin) => Get(bin, PCD.Size, d => new PCD(d));
|
||||
private static PGF[] GetPGFDB(byte[] bin) => Get(bin, PGF.Size, d => new PGF(d));
|
||||
|
||||
private static HashSet<PGF> GetPGFDB(byte[] bin) => new(ArrayUtil.EnumerateSplit(bin, PGF.Size).Select(d => new PGF(d)));
|
||||
private static WC6[] GetWC6DB(byte[] wc6bin, byte[] wc6full) => WC6Full.GetArray(wc6full, wc6bin);
|
||||
private static WC7[] GetWC7DB(byte[] wc7bin, byte[] wc7full) => WC7Full.GetArray(wc7full, wc7bin);
|
||||
|
||||
private static HashSet<WC6> GetWC6DB(byte[] wc6bin, byte[] wc6full) => new(
|
||||
ArrayUtil.EnumerateSplit(wc6full, WC6Full.Size).Select(d => new WC6Full(d).Gift)
|
||||
.Concat(ArrayUtil.EnumerateSplit(wc6bin, WC6.Size).Select(d => new WC6(d))));
|
||||
private static WB7[] GetWB7DB(byte[] bin) => Get(bin, WB7.SizeFull, d => new WB7(d));
|
||||
private static WC8[] GetWC8DB(byte[] bin) => Get(bin, WC8.Size, d => new WC8(d));
|
||||
|
||||
private static HashSet<WC7> GetWC7DB(byte[] wc7bin, byte[] wc7full) => new(
|
||||
ArrayUtil.EnumerateSplit(wc7full, WC7Full.Size).Select(d => new WC7Full(d).Gift)
|
||||
.Concat(ArrayUtil.EnumerateSplit(wc7bin, WC7.Size).Select(d => new WC7(d))));
|
||||
|
||||
private static HashSet<WB7> GetWB7DB(byte[] wc7full) => new(ArrayUtil.EnumerateSplit(wc7full, WB7.SizeFull).Select(d => new WB7(d)));
|
||||
|
||||
private static HashSet<WC8> GetWC8DB(byte[] wc8bin) =>
|
||||
new(ArrayUtil.EnumerateSplit(wc8bin, WC8.Size).Select(d => new WC8(d)));
|
||||
private static T[] Get<T>(byte[] bin, int size, Func<byte[], T> ctor)
|
||||
{
|
||||
var result = new T[bin.Length / size];
|
||||
System.Diagnostics.Debug.Assert(result.Length * size == bin.Length);
|
||||
for (int i = 0; i < result.Length; i++)
|
||||
{
|
||||
var offset = i * size;
|
||||
var slice = bin.Slice(offset, size);
|
||||
result[i] = ctor(slice);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void RefreshMGDB(params string[] paths)
|
||||
{
|
||||
var g4 = GetPCDDB(Util.GetBinaryResource("wc4.pkl"));
|
||||
var g5 = GetPGFDB(Util.GetBinaryResource("pgf.pkl"));
|
||||
var g6 = GetWC6DB(Util.GetBinaryResource("wc6.pkl"), Util.GetBinaryResource("wc6full.pkl"));
|
||||
var g7 = GetWC7DB(Util.GetBinaryResource("wc7.pkl"), Util.GetBinaryResource("wc7full.pkl"));
|
||||
var b7 = GetWB7DB(Util.GetBinaryResource("wb7full.pkl"));
|
||||
var g8 = GetWC8DB(Util.GetBinaryResource("wc8.pkl"));
|
||||
ICollection<PCD> g4 = GetPCDDB(Util.GetBinaryResource("wc4.pkl"));
|
||||
ICollection<PGF> g5 = GetPGFDB(Util.GetBinaryResource("pgf.pkl"));
|
||||
ICollection<WC6> g6 = GetWC6DB(Util.GetBinaryResource("wc6.pkl"), Util.GetBinaryResource("wc6full.pkl"));
|
||||
ICollection<WC7> g7 = GetWC7DB(Util.GetBinaryResource("wc7.pkl"), Util.GetBinaryResource("wc7full.pkl"));
|
||||
ICollection<WB7> b7 = GetWB7DB(Util.GetBinaryResource("wb7full.pkl"));
|
||||
ICollection<WC8> g8 = GetWC8DB(Util.GetBinaryResource("wc8.pkl"));
|
||||
|
||||
foreach (var gift in paths.Where(Directory.Exists).SelectMany(MysteryUtil.GetGiftsFromFolder))
|
||||
{
|
||||
static void AddOrExpand<T>(ref ICollection<T> arr, T obj)
|
||||
{
|
||||
if (arr is HashSet<T>)
|
||||
arr.Add(obj);
|
||||
else
|
||||
arr = new HashSet<T>(arr) {obj};
|
||||
}
|
||||
switch (gift)
|
||||
{
|
||||
case PCD pcd: g4.Add(pcd); continue;
|
||||
case PGF pgf: g5.Add(pgf); continue;
|
||||
case WC6 wc6: g6.Add(wc6); continue;
|
||||
case WC7 wc7: g7.Add(wc7); continue;
|
||||
case WB7 wb7: b7.Add(wb7); continue;
|
||||
case WC8 wc8: g8.Add(wc8); continue;
|
||||
case PCD pcd: AddOrExpand(ref g4, pcd); continue;
|
||||
case PGF pgf: AddOrExpand(ref g5, pgf); continue;
|
||||
case WC6 wc6: AddOrExpand(ref g6, wc6); continue;
|
||||
case WC7 wc7: AddOrExpand(ref g7, wc7); continue;
|
||||
case WB7 wb7: AddOrExpand(ref b7, wb7); continue;
|
||||
case WC8 wc8: AddOrExpand(ref g8, wc8); continue;
|
||||
}
|
||||
}
|
||||
|
||||
static T[] SetArray<T>(ICollection<T> arr)
|
||||
{
|
||||
if (arr is T[] x)
|
||||
return x;
|
||||
var result = new T[arr.Count];
|
||||
((HashSet<T>)arr).CopyTo(result, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
MGDB_G3 = Encounter_WC3; // hardcoded
|
||||
MGDB_G4 = g4.ToArray();
|
||||
MGDB_G5 = g5.ToArray();
|
||||
MGDB_G6 = g6.ToArray();
|
||||
MGDB_G7 = g7.ToArray();
|
||||
MGDB_G7GG = b7.ToArray();
|
||||
MGDB_G8 = g8.ToArray();
|
||||
MGDB_G4 = SetArray(g4);
|
||||
MGDB_G5 = SetArray(g5);
|
||||
MGDB_G6 = SetArray(g6);
|
||||
MGDB_G7 = SetArray(g7);
|
||||
MGDB_G7GG = SetArray(b7);
|
||||
MGDB_G8 = SetArray(g8);
|
||||
}
|
||||
|
||||
public static IEnumerable<MysteryGift> GetAllEvents(bool sorted = true)
|
||||
|
|
|
@ -32,7 +32,7 @@ namespace PKHeX.Core
|
|||
return GetMatchingGifts(pkm, table, chain);
|
||||
}
|
||||
|
||||
private static IReadOnlyList<MysteryGift> GetTable(int generation, PKM pkm) => generation switch
|
||||
private static IReadOnlyCollection<MysteryGift> GetTable(int generation, PKM pkm) => generation switch
|
||||
{
|
||||
3 => MGDB_G3,
|
||||
4 => MGDB_G4,
|
||||
|
@ -43,7 +43,7 @@ namespace PKHeX.Core
|
|||
_ => Array.Empty<MysteryGift>()
|
||||
};
|
||||
|
||||
private static IEnumerable<MysteryGift> GetMatchingPCD(PKM pkm, IReadOnlyList<PCD> DB, IReadOnlyList<DexLevel> chain)
|
||||
private static IEnumerable<MysteryGift> GetMatchingPCD(PKM pkm, IReadOnlyCollection<PCD> DB, IReadOnlyList<DexLevel> chain)
|
||||
{
|
||||
if (PGT.IsRangerManaphy(pkm))
|
||||
{
|
||||
|
@ -55,7 +55,7 @@ namespace PKHeX.Core
|
|||
yield return g;
|
||||
}
|
||||
|
||||
private static IEnumerable<MysteryGift> GetMatchingGifts(PKM pkm, IReadOnlyList<MysteryGift> DB, IReadOnlyList<DexLevel> chain)
|
||||
private static IEnumerable<MysteryGift> GetMatchingGifts(PKM pkm, IReadOnlyCollection<MysteryGift> DB, IReadOnlyList<DexLevel> chain)
|
||||
{
|
||||
foreach (var mg in DB)
|
||||
{
|
||||
|
|
|
@ -5,6 +5,7 @@ namespace PKHeX.Core
|
|||
public sealed class WC6Full
|
||||
{
|
||||
public const int Size = 0x310;
|
||||
private const int GiftStart = Size - WC6.Size;
|
||||
public readonly byte[] Data;
|
||||
public readonly WC6 Gift;
|
||||
|
||||
|
@ -14,7 +15,7 @@ namespace PKHeX.Core
|
|||
public WC6Full(byte[] data)
|
||||
{
|
||||
Data = data;
|
||||
var wc6 = data.SliceEnd(Size - WC6.Size);
|
||||
var wc6 = data.SliceEnd(GiftStart);
|
||||
Gift = new WC6(wc6);
|
||||
var now = DateTime.Now;
|
||||
Gift.RawDate = WC6.SetDate((uint)now.Year, (uint)now.Month, (uint)now.Day);
|
||||
|
@ -22,5 +23,36 @@ namespace PKHeX.Core
|
|||
Gift.RestrictVersion = RestrictVersion;
|
||||
Gift.RestrictLanguage = RestrictLanguage;
|
||||
}
|
||||
public static WC6[] GetArray(byte[] WC6Full, byte[] data)
|
||||
{
|
||||
var countfull = WC6Full.Length / Size;
|
||||
var countgift = data.Length / WC6.Size;
|
||||
var result = new WC6[countfull + countgift];
|
||||
|
||||
var now = DateTime.Now;
|
||||
for (int i = 0; i < countfull; i++)
|
||||
result[i] = ReadWC6(WC6Full, i * Size, now);
|
||||
for (int i = 0; i < countgift; i++)
|
||||
result[i + countfull] = ReadWC6Only(data, i * WC6.Size);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static WC6 ReadWC6(byte[] data, int ofs, DateTime date)
|
||||
{
|
||||
var slice = data.Slice(ofs + GiftStart, WC6.Size);
|
||||
return new WC6(slice)
|
||||
{
|
||||
RestrictVersion = data[ofs],
|
||||
RestrictLanguage = data[ofs + 0x1FF],
|
||||
RawDate = WC6.SetDate((uint)date.Year, (uint)date.Month, (uint)date.Day)
|
||||
};
|
||||
}
|
||||
|
||||
private static WC6 ReadWC6Only(byte[] data, int ofs)
|
||||
{
|
||||
var slice = data.Slice(ofs, WC6.Size);
|
||||
return new WC6(slice);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@ namespace PKHeX.Core
|
|||
public sealed class WC7Full
|
||||
{
|
||||
public const int Size = 0x310;
|
||||
private const int GiftStart = Size - WC7.Size;
|
||||
public readonly byte[] Data;
|
||||
public readonly WC7 Gift;
|
||||
|
||||
|
@ -14,7 +15,7 @@ namespace PKHeX.Core
|
|||
public WC7Full(byte[] data)
|
||||
{
|
||||
Data = data;
|
||||
var wc7 = data.SliceEnd(Size - WC7.Size);
|
||||
var wc7 = data.SliceEnd(GiftStart);
|
||||
Gift = new WC7(wc7);
|
||||
var now = DateTime.Now;
|
||||
Gift.RawDate = WC7.SetDate((uint)now.Year, (uint)now.Month, (uint)now.Day);
|
||||
|
@ -22,5 +23,37 @@ namespace PKHeX.Core
|
|||
Gift.RestrictVersion = RestrictVersion;
|
||||
Gift.RestrictLanguage = RestrictLanguage;
|
||||
}
|
||||
|
||||
public static WC7[] GetArray(byte[] wc7Full, byte[] data)
|
||||
{
|
||||
var countfull = wc7Full.Length / Size;
|
||||
var countgift = data.Length / WC7.Size;
|
||||
var result = new WC7[countfull + countgift];
|
||||
|
||||
var now = DateTime.Now;
|
||||
for (int i = 0; i < countfull; i++)
|
||||
result[i] = ReadWC7(wc7Full, i * Size, now);
|
||||
for (int i = 0; i < countgift; i++)
|
||||
result[i + countfull] = ReadWC7Only(data, i * WC7.Size);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static WC7 ReadWC7(byte[] data, int ofs, DateTime date)
|
||||
{
|
||||
var slice = data.Slice(ofs + GiftStart, WC7.Size);
|
||||
return new WC7(slice)
|
||||
{
|
||||
RestrictVersion = data[ofs],
|
||||
RestrictLanguage = data[ofs + 0x1FF],
|
||||
RawDate = WC7.SetDate((uint) date.Year, (uint) date.Month, (uint) date.Day)
|
||||
};
|
||||
}
|
||||
|
||||
private static WC7 ReadWC7Only(byte[] data, int ofs)
|
||||
{
|
||||
var slice = data.Slice(ofs, WC7.Size);
|
||||
return new WC7(slice);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue