From 5a971593248cb5e3d2f3881f172e8c24de73b16a Mon Sep 17 00:00:00 2001 From: Oliver Wong Date: Fri, 22 May 2026 10:42:41 +0800 Subject: [PATCH] =?UTF-8?q?WIP:=20=E4=BD=BF=E7=94=A8Preferences=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- src/Core/Database.cs | 2 +- src/Core/Preferences.cs | 100 +--------------------- src/Core/PreferencesManager.cs | 150 +++++++++++++++++++++++++++++++++ 4 files changed, 153 insertions(+), 101 deletions(-) create mode 100644 src/Core/PreferencesManager.cs diff --git a/README.md b/README.md index b458205..cabc416 100755 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ ### Mac 数据库: ~/Library/Application Support/Resonance/Databases -偏好设置: ~/Library/Preferences/com.oces.Resonance.plist +偏好设置: ~/Library/Preferences/com.oces.Resonance.json 缓存数据: ~/Library/Caches/com.oces.Resonance ### Windows diff --git a/src/Core/Database.cs b/src/Core/Database.cs index 74e8136..1d17671 100755 --- a/src/Core/Database.cs +++ b/src/Core/Database.cs @@ -13,7 +13,7 @@ public static class Database /// 数据库连接 internal static IDbConnection GetConnection(string dbName = "default") { - string connectionString = $"Data Source={dbName}.rdb;Version=3;"; + string connectionString = $"Data Source={Path.Combine(PreferencesManager.GetDefaultDatabasePath(), dbName)}.rdb;Version=3;"; return new SQLiteConnection(connectionString); } diff --git a/src/Core/Preferences.cs b/src/Core/Preferences.cs index 6da8bb0..0c10bc3 100644 --- a/src/Core/Preferences.cs +++ b/src/Core/Preferences.cs @@ -1,108 +1,10 @@ -using Newtonsoft.Json; - namespace OCES.Resonance.Core; /// -/// 应用偏好设置,单例模式,负责平台路径解析与 JSON 持久化。 +/// 应用偏好设置数据模型,由 统一管理生命周期。 /// public class Preferences { - private static readonly Lazy _instance = new(() => new Preferences()); - - /// 单例访问入口 - public static Preferences Instance - { - get { return _instance.Value; } - } - /// 数据库文件存放目录 public string DatabasePath { get; set; } = string.Empty; - - /// 偏好设置 JSON 文件的完整路径 - public string PreferencesPath { get; set; } = string.Empty; - - /// - /// 私有构造函数 —— 根据运行时平台设置 。 - /// JSON 反序列化时也会调用此构造函数,随后由 JSON 属性覆盖路径值。 - /// - [JsonConstructor] - Preferences() - { - if (OperatingSystem.IsMacOS()) - { - string home = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); - DatabasePath = Path.Combine(home, "OCES","Resonance", "Databases"); - PreferencesPath = Path.Combine(home, "Library", "Preferences", "com.oces.Resonance.json"); - } - else if (OperatingSystem.IsWindows()) - { - string localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); - string roamingAppData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); - DatabasePath = Path.Combine(localAppData, "OCES", "Resonance", "Databases"); - PreferencesPath = Path.Combine(roamingAppData, "OCES", "Resonance", "preferences.json"); - } - else if (OperatingSystem.IsLinux()) - { - string home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); - string xdgDataHome = Environment.GetEnvironmentVariable("XDG_DATA_HOME") - ?? Path.Combine(home, ".local", "share"); - string xdgConfigHome = Environment.GetEnvironmentVariable("XDG_CONFIG_HOME") - ?? Path.Combine(home, ".config"); - DatabasePath = Path.Combine(xdgDataHome, "Resonance", "Databases"); - PreferencesPath = Path.Combine(xdgConfigHome, "Resonance", "preferences.json"); - } - } - - /// - /// 将传入的 实例序列化为 JSON 文件,保存到 。 - /// - /// 待序列化的偏好设置实例 - /// 成功返回 true,失败返回 false - public bool Serialize(Preferences preferences) - { - try - { - string? directory = Path.GetDirectoryName(PreferencesPath); - if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory)) - { - Directory.CreateDirectory(directory); - } - - string json = JsonConvert.SerializeObject(preferences, Formatting.Indented); - File.WriteAllText(PreferencesPath, json); - return true; - } - catch - { - //调用房根据自己的情况,自己处理接到false该怎么办。 - return false; - } - } - - /// - /// 从指定路径读取 JSON 文件并反序列化为 实例。 - /// - /// JSON 文件的完整路径 - /// 反序列化成功返回 Preferences 实例,失败返回 null - public Preferences? Deserialize(string preferencesPath) - { - try - { - if (!File.Exists(preferencesPath)) - { - return null; - } - - string json = File.ReadAllText(preferencesPath); - JsonSerializerSettings settings = new() - { - ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor, - }; - return JsonConvert.DeserializeObject(json, settings); - } - catch - { - return null; - } - } } diff --git a/src/Core/PreferencesManager.cs b/src/Core/PreferencesManager.cs new file mode 100644 index 0000000..58d04b8 --- /dev/null +++ b/src/Core/PreferencesManager.cs @@ -0,0 +1,150 @@ +using Newtonsoft.Json; + +namespace OCES.Resonance.Core; + +/// +/// 偏好设置管理器,负责平台路径解析、JSON 持久化以及 实例的生命周期管理。 +/// +public static class PreferencesManager +{ + /// 当前活动的偏好设置实例, 调用前为 null + public static Preferences? CurrentPreferences { get; set; } + + /// + /// 加载偏好设置。先尝试从硬盘反序列化;若文件不存在则创建带平台默认路径的新实例。 + /// + public static void Load() + { + string preferencesPath = GetDefaultPreferencesPath(); + + // 尝试从硬盘加载 + Preferences? loaded = Deserialize(preferencesPath); + if (loaded != null) + { + CurrentPreferences = loaded; + return; + } + + // 文件不存在或反序列化失败 → 创建默认实例 + CurrentPreferences = new Preferences + { + DatabasePath = GetDefaultDatabasePath() + }; + + // 立即落盘,确保下次启动能直接读取 + Serialize(CurrentPreferences); + } + + /// + /// 将当前 序列化到硬盘。 + /// + public static void Save() + { + if (CurrentPreferences == null) return; + Serialize(CurrentPreferences); + } + + /// + /// 根据运行时平台返回数据库文件存放目录。 + /// + public static string GetDefaultDatabasePath() + { + if (OperatingSystem.IsMacOS()) + { + string library = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); + return Path.Combine(library, "OCES", "Resonance", "Databases"); + } + + if (OperatingSystem.IsWindows()) + { + string localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); + return Path.Combine(localAppData, "OCES", "Resonance", "Databases"); + } + + if (OperatingSystem.IsLinux()) + { + string home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); + string xdgDataHome = Environment.GetEnvironmentVariable("XDG_DATA_HOME") + ?? Path.Combine(home, ".local", "share"); + return Path.Combine(xdgDataHome, "Resonance", "Databases"); + } + + return string.Empty; + } + + /// + /// 根据运行时平台返回偏好设置 JSON 文件的完整路径。 + /// + public static string GetDefaultPreferencesPath() + { + if (OperatingSystem.IsMacOS()) + { + string library = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); + return Path.Combine(library, "Preferences", "com.oces.Resonance.json"); + } + + if (OperatingSystem.IsWindows()) + { + string roamingAppData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); + return Path.Combine(roamingAppData, "OCES", "Resonance", "preferences.json"); + } + + if (OperatingSystem.IsLinux()) + { + string home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); + string xdgConfigHome = Environment.GetEnvironmentVariable("XDG_CONFIG_HOME") + ?? Path.Combine(home, ".config"); + return Path.Combine(xdgConfigHome, "Resonance", "preferences.json"); + } + + return string.Empty; + } + + /// + /// 将 实例序列化为 JSON 文件,保存到平台默认偏好设置路径。 + /// + /// 成功返回 true,失败返回 false + static bool Serialize(Preferences preferences) + { + try + { + string path = GetDefaultPreferencesPath(); + string? directory = Path.GetDirectoryName(path); + if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory)) + { + Directory.CreateDirectory(directory); + } + + string json = JsonConvert.SerializeObject(preferences, Formatting.Indented); + File.WriteAllText(path, json); + return true; + } + catch + { + // 调用方根据自己的情况处理 false + return false; + } + } + + /// + /// 从指定路径读取 JSON 文件并反序列化为 实例。 + /// + /// 反序列化成功返回实例,失败返回 null + static Preferences? Deserialize(string preferencesPath) + { + try + { + if (!File.Exists(preferencesPath)) + { + return null; + } + + string json = File.ReadAllText(preferencesPath); + return JsonConvert.DeserializeObject(json); + } + catch + { + return null; + } + } +}