PKHeX/PKHeX.Core/Util/Localization/LocalizationStorage.cs
Kurt b291378e78 Localizations: better thread safety init
No need for a dictionary, just allocate an array and index in via one of the supported languages.

Updates GameInfo to use the abstraction to prevent some duplicate work on a very-hot startup. Threads repeating the same work vs Thread n++ simply waiting for previous thread to finish init is the ~same amount of time, with less overall CPU usage (so this is a positive improvement).

EnterScope is "safer" than explicit `lock (x)` due to the using syntax releasing the lock even on exception (not expected, but might alleviate issues on developer-initiated feature upgrades).

Co-Authored-By: HexByt3 <80122551+hexbyt3@users.noreply.github.com>
2025-08-07 21:15:32 -05:00

40 lines
1.5 KiB
C#

using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Json.Serialization.Metadata;
namespace PKHeX.Core;
public sealed record LocalizationStorage<T>(string Name, JsonTypeInfo<T> Info) : LanguageStorage<T>
where T : notnull
{
#pragma warning disable RCS1158 // Static member in generic type should use a type parameter
public static JsonSerializerOptions Options => new()
{
RespectNullableAnnotations = true,
AllowTrailingCommas = true,
WriteIndented = true,
IndentCharacter = ' ',
IndentSize = 4,
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
};
#pragma warning restore RCS1158 // Static member in generic type should use a type parameter
private string GetJson(string language) => Util.GetStringResource(GetFileName(language));
public string GetFileName(string language) => $"{Name}_{language}.json";
/// <param name="language"><see cref="LanguageID"/> index</param>
/// <inheritdoc cref="Get(LanguageID)"/>
public T Get(LanguageID language) => Get(language.GetLanguageCode());
/// <summary>
/// Gets the localization for the requested language.
/// </summary>
/// <param name="language">Language code</param>
protected override T Create(string language)
{
var text = GetJson(language);
return JsonSerializer.Deserialize(text, Info)
?? throw new JsonException($"Failed to deserialize {nameof(T)} for {language}");
}
}