using System; using System.Text.Json; using System.Threading.Tasks; using Godot; using Pong.Scripts.Data; namespace Pong.Scripts.Managers; public partial class SettingsManager : Node { private const string SettingsPath = "user://settings.json"; public Settings SettingsData = Settings.Default; private static readonly JsonSerializerOptions SerializerOptions = new() { IncludeFields = true }; public event Action SettingsChanged; public override async void _EnterTree() { await LoadSettings(); } /// /// load the settings data from the filesystem. /// private async Task LoadSettings() { try { if (!FileAccess.FileExists(SettingsPath)) { await SaveSettings(Settings.Default); return; } using var file = await OpenSettingsFile(FileAccess.ModeFlags.Read); SettingsData = await Task.Run(() => JsonSerializer.Deserialize(file.GetAsText(), SerializerOptions)); SettingsChanged?.Invoke(); } catch (Exception e) { PrintFileError(e); } } /// /// open the settings file from the filesystem. /// /// a godot FileAccess object. private static async Task OpenSettingsFile(FileAccess.ModeFlags flag) { return await Task.Run(() => FileAccess.Open(SettingsPath, flag)); } internal async Task SaveSettings(Settings settings) { try { using var file = await OpenSettingsFile(FileAccess.ModeFlags.WriteRead); var json = await Task.Run(() => JsonSerializer.Serialize(settings, SerializerOptions)); await Task.Run(() => file.StoreBuffer(json.ToUtf8Buffer())); SettingsData = settings; SettingsChanged?.Invoke(); return true; } catch (Exception e) { PrintFileError(e); return false; } } private static void PrintFileError(Exception e) { GD.PrintErr($"a {e.GetType()} has occured while trying to load the settings file: {e}."); GD.PrintErr("default settings will be used."); } }