From 3d137d738e9f430a4779ce01e2106a9a0837186e Mon Sep 17 00:00:00 2001 From: Ar6yZuK Date: Mon, 4 Mar 2024 09:02:07 +0300 Subject: [PATCH] Now we won't have to lose data on updating Visual Studio. Added (SettingsInFile), (CachedSettingsInFile), (CachedSettings), (CachedSettingsWithSaving). Make all settings to (CachedSettingsInFile) except SessionSettings. Make few TODOs comments. --- HabiticaHourUpVSIX/AppSettings/Settings.cs | 84 +++++++++++++++++-- .../AppSettings/SettingsAbstractions.cs | 1 + .../HabiticaHourUpVSIXPackage.cs | 26 ++++-- 3 files changed, 97 insertions(+), 14 deletions(-) diff --git a/HabiticaHourUpVSIX/AppSettings/Settings.cs b/HabiticaHourUpVSIX/AppSettings/Settings.cs index 01c273a..21de282 100644 --- a/HabiticaHourUpVSIX/AppSettings/Settings.cs +++ b/HabiticaHourUpVSIX/AppSettings/Settings.cs @@ -69,6 +69,78 @@ public override void Save() Source.Save(); } } +internal class SettingsInFile(string fileName, T defaultSettings) : SettingsWithSaving + where T : struct +{ + public override T Read() + { + if (!File.Exists(fileName)) + { + Write(defaultSettings); + return defaultSettings; + } + + string data = File.ReadAllText(fileName); + var result = JsonConvert.DeserializeObject(data); + + return result; + } + + public override void Write(T value) + { + string data = JsonConvert.SerializeObject(value, Formatting.Indented); + WriteDataToFile(fileName, data); + + static void WriteDataToFile(string fileName, string data) + { + CreateDirectoryIfNotExists(Path.GetDirectoryName(fileName)); + File.WriteAllText(fileName, data); + static void CreateDirectoryIfNotExists(string dirPath) + { + if (!Directory.Exists(dirPath)) + Directory.CreateDirectory(dirPath); + } + } + } + +} +// TODO: Maybe add ICachedSettings interface if needed +internal class CachedSettings(Settings settingsToCache, TimeSpan timeOfCache) : Settings + where T : struct +{ + private DateTime _expires; + private T _cachedValue; + + public override T Read() + { + if (_expires > DateTime.Now) + return _cachedValue; + + _expires = DateTime.Now + timeOfCache; + return _cachedValue = settingsToCache.Read(); + } + public override void Write(T value) + { + _expires = DateTime.Now - TimeSpan.FromSeconds(1d); + settingsToCache.Write(value); + } +} +internal class CachedSettingsWithSaving(SettingsWithSaving settings, TimeSpan timeOfCache) : SettingsWithSaving + where T : struct +{ + private readonly CachedSettings _cachedSettings = new(settings, timeOfCache); + + public override T Read() => _cachedSettings.Read(); + public override void Write(T value) => _cachedSettings.Write(value); +} +internal class CachedSettingsInFile(string fileName, T defaultSettings, TimeSpan timeOfCache) : SettingsWithSaving + where T : struct +{ + private readonly CachedSettingsWithSaving _cachedSettingsInFile = new(new SettingsInFile(fileName, defaultSettings), timeOfCache); + + public override T Read() => _cachedSettingsInFile.Read(); + public override void Write(T value) => _cachedSettingsInFile.Write(value); +} internal sealed class HabiticaSettings : SettingsWithSaving { protected override HabiticaSettings1 Source => HabiticaSettings1.Default; @@ -81,13 +153,13 @@ public override void Save() } internal sealed class CredentialsSettings : SettingsWithSaving { - protected override CredentialsSettings1 Source => CredentialsSettings1.Default; + protected override CredentialsSettings1 Source => CredentialsSettings1.Default; - public override void Save() - { - base.Save(); - Source.Save(); - } + public override void Save() + { + base.Save(); + Source.Save(); + } } internal sealed class SessionSettings : Settings { diff --git a/HabiticaHourUpVSIX/AppSettings/SettingsAbstractions.cs b/HabiticaHourUpVSIX/AppSettings/SettingsAbstractions.cs index 66be03a..061b83c 100644 --- a/HabiticaHourUpVSIX/AppSettings/SettingsAbstractions.cs +++ b/HabiticaHourUpVSIX/AppSettings/SettingsAbstractions.cs @@ -7,6 +7,7 @@ public interface ISettings T Read(); void Write(T value); } +// TODO: Maybe add IDisposable public interface ISaveable where T : struct { diff --git a/HabiticaHourUpVSIX/HabiticaHourUpVSIXPackage.cs b/HabiticaHourUpVSIX/HabiticaHourUpVSIXPackage.cs index c46ea57..25e1a50 100644 --- a/HabiticaHourUpVSIX/HabiticaHourUpVSIXPackage.cs +++ b/HabiticaHourUpVSIX/HabiticaHourUpVSIXPackage.cs @@ -47,6 +47,8 @@ protected override async Task InitializeAsync(CancellationToken cancellationToke if (!userSettings.BeepOnSuccess) return; + // TODO: Maybe show error if userSettings.BeepAudioPath was empty + // TODO: Fast fix: always set beepAudioPath SetMusicPathIfNull(userSettings.BeepAudioPath); _soundPlayer.Play(); @@ -54,20 +56,27 @@ void SetMusicPathIfNull(string beepMusicPath) => _soundPlayer.AudioPath = string.IsNullOrEmpty(_soundPlayer.AudioPath) ? beepMusicPath : _soundPlayer.AudioPath; }; + // timeOfCache is expected time of load + var timeOfCache = TimeSpan.FromSeconds(10); + string appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); + string vsixSettingsPath = $"{appDataPath}/Ar6yZuK/VSIX/{Vsix.Name}/"; + SessionSettingsReader = new SessionSettings(); - CredentialsSettings = new CredentialsSettings(); + // TODO: Maybe encrypt HabiticaCredentials somehow + CredentialsSettings = new CachedSettingsInFile($"{vsixSettingsPath}credentials.json", new("", ""), timeOfCache); - UserSettingsReader = new UserSettings(); + UserSettingsModel defaultUserSettings = new(TimeSpan.FromHours(1), "", IsAutoScoreUp: false, ShowErrorOnFailure: true, BeepOnSuccess: true, ""); + UserSettingsReader = new CachedSettingsInFile($"{vsixSettingsPath}user_settings.json", defaultUserSettings, timeOfCache); UserSettingsReader.OnSaving += UserSettingsReader_OnSaving; - HabiticaSettingsReader = new HabiticaSettings(); - HabiticaSettingsModel habiticaSettings = HabiticaSettingsReader.Read(); - - UserSettingsModel vsSettings = UserSettingsReader.Read(); + HabiticaSettingsReader = new CachedSettingsInFile($"{vsixSettingsPath}local_settings.json", new(), timeOfCache); Timer = new MyTimer(); Timer.Tick += Tick; + HabiticaSettingsModel habiticaSettings = HabiticaSettingsReader.Read(); + UserSettingsModel vsSettings = UserSettingsReader.Read(); + TimeSpan tickAfter = habiticaSettings.LastWorkTime <= TimeSpan.Zero ? vsSettings.Divisor : habiticaSettings.LastWorkTime; Timer.Change(tickAfter, vsSettings.Divisor); @@ -122,7 +131,8 @@ private void UserSettingsReader_OnSaving(UserSettingsModel userSettingsModel) private void OnClose() { - this.HabiticaSettingsReader.SetLastTickAfterWithSave(Timer.NextTick); + // TODO: do not remember last work time. Maybe delete property LastWorkTime + this.HabiticaSettingsReader.SetWithSave(x => x.LastWorkTime, Timer.NextTick); } private void AddTicksToAllSettings(int addedTicks) @@ -140,7 +150,7 @@ private void AddTicksToAllSettings(int addedTicks) protected override void Dispose(bool disposing) { - Timer.Dispose(); + Timer?.Dispose(); base.Dispose(disposing); } } \ No newline at end of file