feat(setting): 添加设置系统事件通知和重置功能

- 在SettingsModel中添加事件相关依赖引用
- 在SettingsPersistence中实现设置加载、保存、删除的事件发送机制
- 添加SettingsDeletedEvent用于通知设置删除操作
- 添加SettingsResetEvent和SettingsResetAllEvent支持设置重置功能
- 在SettingsPersistence中新增ResetAsync和ResetAllAsync方法
- 修改TryApply方法为实例方法并添加设置应用过程的事件通知
- 添加SettingsApplyingEvent和SettingsAppliedEvent跟踪设置应用状态
- [skip ci]
This commit is contained in:
GeWuYou 2026-01-17 13:43:15 +08:00
parent ce6cb3f8df
commit 267d7cc84d
6 changed files with 193 additions and 8 deletions

View File

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using GFramework.Core.Abstractions.utility;
@ -40,4 +40,14 @@ public interface ISettingsPersistence : IContextUtility
/// 加载所有已知类型的设置数据
/// </summary>
Task<IDictionary<Type, ISettingsData>> LoadAllAsync(IEnumerable<Type> knownTypes);
/// <summary>
/// 重置指定类型的设置数据为默认值
/// </summary>
Task<T> ResetAsync<T>() where T : class, ISettingsData, new();
/// <summary>
/// 重置所有设置数据为默认值
/// </summary>
Task ResetAllAsync();
}

View File

@ -1,7 +1,8 @@
using GFramework.Core.Abstractions.storage;
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;
@ -23,10 +24,14 @@ public class SettingsPersistence : AbstractContextUtility, ISettingsPersistence
if (await _storage.ExistsAsync(key))
{
return await _storage.ReadAsync<T>(key);
var result = await _storage.ReadAsync<T>(key);
this.SendEvent(new SettingsLoadedEvent<T>(result));
return result;
}
return new T();
var newSettings = new T();
this.SendEvent(new SettingsLoadedEvent<T>(newSettings));
return newSettings;
}
/// <summary>
@ -38,6 +43,7 @@ public class SettingsPersistence : AbstractContextUtility, ISettingsPersistence
{
var key = GetKey<T>();
await _storage.WriteAsync(key, section);
this.SendEvent(new SettingsSavedEvent<T>(section));
}
/// <summary>
@ -59,6 +65,7 @@ public class SettingsPersistence : AbstractContextUtility, ISettingsPersistence
{
var key = GetKey<T>();
_storage.Delete(key);
this.SendEvent(new SettingsDeletedEvent(typeof(T)));
await Task.CompletedTask;
}
@ -68,12 +75,15 @@ public class SettingsPersistence : AbstractContextUtility, ISettingsPersistence
/// <param name="allData">包含所有设置数据的可枚举集合</param>
public async Task SaveAllAsync(IEnumerable<ISettingsData> allData)
{
foreach (var data in 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>
@ -84,6 +94,7 @@ public class SettingsPersistence : AbstractContextUtility, ISettingsPersistence
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)
{
@ -100,11 +111,57 @@ public class SettingsPersistence : AbstractContextUtility, ISettingsPersistence
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>()!;

View File

@ -1,6 +1,7 @@
using GFramework.Core.extensions;
using GFramework.Core.extensions;
using GFramework.Core.system;
using GFramework.Game.Abstractions.setting;
using GFramework.Game.setting.events;
namespace GFramework.Game.setting;
@ -79,11 +80,22 @@ public class SettingsSystem : AbstractSystem, ISettingsSystem
/// 尝试应用可应用的设置配置
/// </summary>
/// <param name="section">设置配置对象</param>
private static void TryApply(ISettingsSection section)
private void TryApply(ISettingsSection section)
{
if (section is IApplyAbleSettings applyable)
{
applyable.Apply();
this.SendEvent(new SettingsApplyingEvent<ISettingsSection>(section));
try
{
applyable.Apply();
this.SendEvent(new SettingsAppliedEvent<ISettingsSection>(section, true));
}
catch (Exception ex)
{
this.SendEvent(new SettingsAppliedEvent<ISettingsSection>(section, false, ex));
throw;
}
}
}
}

View File

@ -0,0 +1,24 @@
using GFramework.Game.Abstractions.setting;
namespace GFramework.Game.setting.events;
/// <summary>
/// 表示设置删除事件
/// </summary>
public class SettingsDeletedEvent(Type settingsType) : ISettingsChangedEvent
{
/// <summary>
/// 获取被删除的设置类型
/// </summary>
public Type SettingsType { get; } = settingsType;
/// <summary>
/// 获取设置实例,删除事件中返回 null
/// </summary>
public ISettingsSection Settings => null!;
/// <summary>
/// 获取删除时间
/// </summary>
public DateTime ChangedAt { get; } = DateTime.UtcNow;
}

View File

@ -0,0 +1,30 @@
using GFramework.Game.Abstractions.setting;
namespace GFramework.Game.setting.events;
/// <summary>
/// 表示所有设置重置完成事件
/// </summary>
/// <param name="newSettings">重置后的所有设置</param>
public class SettingsResetAllEvent(IEnumerable<ISettingsSection> newSettings) : ISettingsChangedEvent
{
/// <summary>
/// 获取重置后的所有设置
/// </summary>
public IReadOnlyCollection<ISettingsSection> NewSettings { get; } = newSettings.ToList();
/// <summary>
/// 获取设置类型,固定返回 ISettingsSection
/// </summary>
public Type SettingsType => typeof(ISettingsSection);
/// <summary>
/// 获取设置实例,批量事件中返回 null
/// </summary>
public ISettingsSection Settings => null!;
/// <summary>
/// 获取重置时间
/// </summary>
public DateTime ChangedAt { get; } = DateTime.UtcNow;
}

View File

@ -0,0 +1,52 @@
using GFramework.Game.Abstractions.setting;
namespace GFramework.Game.setting.events;
/// <summary>
/// 表示设置重置事件
/// </summary>
/// <typeparam name="T">设置节类型</typeparam>
public class SettingsResetEvent<T> : ISettingsChangedEvent
where T : ISettingsSection
{
/// <summary>
/// 构造函数
/// </summary>
/// <param name="oldSettings">重置前的设置</param>
/// <param name="newSettings">重置后的新设置</param>
public SettingsResetEvent(T oldSettings, T newSettings)
{
OldSettings = oldSettings;
NewSettings = newSettings;
}
/// <summary>
/// 获取重置前的设置
/// </summary>
public T OldSettings { get; }
/// <summary>
/// 获取重置后的新设置
/// </summary>
public T NewSettings { get; }
/// <summary>
/// 获取类型化的设置实例(返回新设置)
/// </summary>
public T TypedSettings => NewSettings;
/// <summary>
/// 获取设置类型
/// </summary>
public Type SettingsType => typeof(T);
/// <summary>
/// 获取设置实例
/// </summary>
public ISettingsSection Settings => NewSettings;
/// <summary>
/// 获取重置时间
/// </summary>
public DateTime ChangedAt { get; } = DateTime.UtcNow;
}