Lumi/companion/plugins/Lumi.Companion.SongOverlay/SongOverlaySettingsStore.cs
2026-07-24 14:44:27 +02:00

69 lines
2.2 KiB
C#

using System.Text.Json;
namespace Lumi.Companion.SongOverlay;
internal sealed class SongOverlaySettingsStore(string path)
{
private readonly SemaphoreSlim _gate = new(1, 1);
public SongOverlaySettings Current { get; private set; } = new();
public async Task LoadAsync(CancellationToken cancellationToken = default)
{
if (!File.Exists(path)) return;
try
{
Current = JsonSerializer.Deserialize<SongOverlaySettings>(
await File.ReadAllBytesAsync(path, cancellationToken),
SongOverlayJson.Options) ?? new();
}
catch (JsonException)
{
Current = new();
}
}
public void Save(SongOverlaySettings settings)
{
_gate.Wait();
try
{
Directory.CreateDirectory(Path.GetDirectoryName(path)!);
var temporary = $"{path}.{Environment.ProcessId}.tmp";
try
{
File.WriteAllBytes(temporary, JsonSerializer.SerializeToUtf8Bytes(settings, SongOverlayJson.Options));
File.Move(temporary, path, true);
}
finally { File.Delete(temporary); }
Current = settings;
}
finally { _gate.Release(); }
}
public async Task SaveAsync(SongOverlaySettings settings, CancellationToken cancellationToken = default)
{
await _gate.WaitAsync(cancellationToken);
try
{
Directory.CreateDirectory(Path.GetDirectoryName(path)!);
var temporary = $"{path}.{Environment.ProcessId}.tmp";
try
{
await File.WriteAllBytesAsync(temporary, JsonSerializer.SerializeToUtf8Bytes(settings, SongOverlayJson.Options), cancellationToken);
File.Move(temporary, path, true);
}
finally { File.Delete(temporary); }
Current = settings;
}
finally { _gate.Release(); }
}
}
internal static class SongOverlayJson
{
public static readonly JsonSerializerOptions Options = new(JsonSerializerDefaults.Web)
{
DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull
};
}