mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-22 10:34:30 +08:00
- 在SettingsModel中添加事件相关依赖引用 - 在SettingsPersistence中实现设置加载、保存、删除的事件发送机制 - 添加SettingsDeletedEvent用于通知设置删除操作 - 添加SettingsResetEvent和SettingsResetAllEvent支持设置重置功能 - 在SettingsPersistence中新增ResetAsync和ResetAllAsync方法 - 修改TryApply方法为实例方法并添加设置应用过程的事件通知 - 添加SettingsApplyingEvent和SettingsAppliedEvent跟踪设置应用状态 - [skip ci]
185 lines
5.9 KiB
C#
185 lines
5.9 KiB
C#
using GFramework.Core.Abstractions.storage;
|
||
using GFramework.Core.extensions;
|
||
using GFramework.Core.utility;
|
||
using GFramework.Game.Abstractions.setting;
|
||
using GFramework.Game.setting.events;
|
||
|
||
namespace GFramework.Game.setting;
|
||
|
||
/// <summary>
|
||
/// 设置持久化服务类,负责处理设置数据的加载、保存、删除等操作
|
||
/// </summary>
|
||
public class SettingsPersistence : AbstractContextUtility, ISettingsPersistence
|
||
{
|
||
private IStorage _storage = null!;
|
||
|
||
/// <summary>
|
||
/// 异步加载指定类型的设置数据
|
||
/// </summary>
|
||
/// <typeparam name="T">设置数据类型,必须实现ISettingsData接口</typeparam>
|
||
/// <returns>如果存在则返回存储的设置数据,否则返回新创建的实例</returns>
|
||
public async Task<T> LoadAsync<T>() where T : class, ISettingsData, new()
|
||
{
|
||
var key = GetKey<T>();
|
||
|
||
if (await _storage.ExistsAsync(key))
|
||
{
|
||
var result = await _storage.ReadAsync<T>(key);
|
||
this.SendEvent(new SettingsLoadedEvent<T>(result));
|
||
return result;
|
||
}
|
||
|
||
var newSettings = new T();
|
||
this.SendEvent(new SettingsLoadedEvent<T>(newSettings));
|
||
return newSettings;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 异步保存设置数据到存储中
|
||
/// </summary>
|
||
/// <typeparam name="T">设置数据类型,必须实现ISettingsData接口</typeparam>
|
||
/// <param name="section">要保存的设置数据实例</param>
|
||
public async Task SaveAsync<T>(T section) where T : class, ISettingsData
|
||
{
|
||
var key = GetKey<T>();
|
||
await _storage.WriteAsync(key, section);
|
||
this.SendEvent(new SettingsSavedEvent<T>(section));
|
||
}
|
||
|
||
/// <summary>
|
||
/// 检查指定类型的设置数据是否存在
|
||
/// </summary>
|
||
/// <typeparam name="T">设置数据类型,必须实现ISettingsData接口</typeparam>
|
||
/// <returns>如果存在返回true,否则返回false</returns>
|
||
public async Task<bool> ExistsAsync<T>() where T : class, ISettingsData
|
||
{
|
||
var key = GetKey<T>();
|
||
return await _storage.ExistsAsync(key);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 异步删除指定类型的设置数据
|
||
/// </summary>
|
||
/// <typeparam name="T">设置数据类型,必须实现ISettingsData接口</typeparam>
|
||
public async Task DeleteAsync<T>() where T : class, ISettingsData
|
||
{
|
||
var key = GetKey<T>();
|
||
_storage.Delete(key);
|
||
this.SendEvent(new SettingsDeletedEvent(typeof(T)));
|
||
await Task.CompletedTask;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 异步保存所有设置数据到存储中
|
||
/// </summary>
|
||
/// <param name="allData">包含所有设置数据的可枚举集合</param>
|
||
public async Task SaveAllAsync(IEnumerable<ISettingsData> allData)
|
||
{
|
||
var dataList = allData.ToList();
|
||
foreach (var data in dataList)
|
||
{
|
||
var type = data.GetType();
|
||
var key = GetKey(type);
|
||
await _storage.WriteAsync(key, data);
|
||
}
|
||
|
||
this.SendEvent(new SettingsBatchSavedEvent(dataList));
|
||
}
|
||
|
||
/// <summary>
|
||
/// 异步加载所有已知类型的设置数据
|
||
/// </summary>
|
||
/// <param name="knownTypes">已知设置数据类型的集合</param>
|
||
/// <returns>类型与对应设置数据的字典映射</returns>
|
||
public async Task<IDictionary<Type, ISettingsData>> LoadAllAsync(IEnumerable<Type> knownTypes)
|
||
{
|
||
var result = new Dictionary<Type, ISettingsData>();
|
||
var allSettings = new List<ISettingsSection>();
|
||
|
||
foreach (var type in knownTypes)
|
||
{
|
||
var key = GetKey(type);
|
||
|
||
if (!await _storage.ExistsAsync(key)) continue;
|
||
// 使用反射调用泛型方法
|
||
var method = typeof(IStorage)
|
||
.GetMethod(nameof(IStorage.ReadAsync))!
|
||
.MakeGenericMethod(type);
|
||
|
||
var task = (Task)method.Invoke(_storage, [key])!;
|
||
await task;
|
||
|
||
var loaded = (ISettingsData)((dynamic)task).Result;
|
||
result[type] = loaded;
|
||
allSettings.Add(loaded);
|
||
}
|
||
|
||
this.SendEvent(new SettingsAllLoadedEvent(allSettings));
|
||
return result;
|
||
}
|
||
|
||
public async Task<T> ResetAsync<T>() where T : class, ISettingsData, new()
|
||
{
|
||
var type = typeof(T);
|
||
var key = GetKey(type);
|
||
|
||
T oldSettings;
|
||
if (await _storage.ExistsAsync(key))
|
||
{
|
||
oldSettings = await _storage.ReadAsync<T>(key);
|
||
}
|
||
else
|
||
{
|
||
oldSettings = new T();
|
||
}
|
||
|
||
var newSettings = new T();
|
||
await _storage.WriteAsync(key, newSettings);
|
||
|
||
this.SendEvent(new SettingsResetEvent<T>(oldSettings, newSettings));
|
||
return newSettings;
|
||
}
|
||
|
||
public async Task ResetAllAsync()
|
||
{
|
||
var knownTypes = new List<Type>();
|
||
|
||
var audioSettings = await LoadAllAsync(knownTypes);
|
||
var allNewSettings = new List<ISettingsSection>();
|
||
|
||
foreach (var kvp in audioSettings)
|
||
{
|
||
var type = kvp.Key;
|
||
var key = GetKey(type);
|
||
|
||
var newSettings = Activator.CreateInstance(type) as ISettingsSection;
|
||
if (newSettings is null) continue;
|
||
|
||
await _storage.WriteAsync(key, newSettings);
|
||
allNewSettings.Add(newSettings);
|
||
}
|
||
|
||
this.SendEvent(new SettingsResetAllEvent(allNewSettings));
|
||
}
|
||
|
||
protected override void OnInit()
|
||
{
|
||
_storage = this.GetUtility<IStorage>()!;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取指定类型的存储键名
|
||
/// </summary>
|
||
/// <typeparam name="T">设置数据类型</typeparam>
|
||
/// <returns>格式为"Settings_类型名称"的键名</returns>
|
||
private static string GetKey<T>() where T : ISettingsData
|
||
=> GetKey(typeof(T));
|
||
|
||
/// <summary>
|
||
/// 获取指定类型的存储键名
|
||
/// </summary>
|
||
/// <param name="type">设置数据类型</param>
|
||
/// <returns>格式为"Settings_类型名称"的键名</returns>
|
||
private static string GetKey(Type type)
|
||
=> $"Settings_{type.Name}";
|
||
} |