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.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using GFramework.Core.Abstractions.utility; using GFramework.Core.Abstractions.utility;
@ -40,4 +40,14 @@ public interface ISettingsPersistence : IContextUtility
/// 加载所有已知类型的设置数据 /// 加载所有已知类型的设置数据
/// </summary> /// </summary>
Task<IDictionary<Type, ISettingsData>> LoadAllAsync(IEnumerable<Type> knownTypes); 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.extensions;
using GFramework.Core.utility; using GFramework.Core.utility;
using GFramework.Game.Abstractions.setting; using GFramework.Game.Abstractions.setting;
using GFramework.Game.setting.events;
namespace GFramework.Game.setting; namespace GFramework.Game.setting;
@ -23,10 +24,14 @@ public class SettingsPersistence : AbstractContextUtility, ISettingsPersistence
if (await _storage.ExistsAsync(key)) 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> /// <summary>
@ -38,6 +43,7 @@ public class SettingsPersistence : AbstractContextUtility, ISettingsPersistence
{ {
var key = GetKey<T>(); var key = GetKey<T>();
await _storage.WriteAsync(key, section); await _storage.WriteAsync(key, section);
this.SendEvent(new SettingsSavedEvent<T>(section));
} }
/// <summary> /// <summary>
@ -59,6 +65,7 @@ public class SettingsPersistence : AbstractContextUtility, ISettingsPersistence
{ {
var key = GetKey<T>(); var key = GetKey<T>();
_storage.Delete(key); _storage.Delete(key);
this.SendEvent(new SettingsDeletedEvent(typeof(T)));
await Task.CompletedTask; await Task.CompletedTask;
} }
@ -68,12 +75,15 @@ public class SettingsPersistence : AbstractContextUtility, ISettingsPersistence
/// <param name="allData">包含所有设置数据的可枚举集合</param> /// <param name="allData">包含所有设置数据的可枚举集合</param>
public async Task SaveAllAsync(IEnumerable<ISettingsData> allData) 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 type = data.GetType();
var key = GetKey(type); var key = GetKey(type);
await _storage.WriteAsync(key, data); await _storage.WriteAsync(key, data);
} }
this.SendEvent(new SettingsBatchSavedEvent(dataList));
} }
/// <summary> /// <summary>
@ -84,6 +94,7 @@ public class SettingsPersistence : AbstractContextUtility, ISettingsPersistence
public async Task<IDictionary<Type, ISettingsData>> LoadAllAsync(IEnumerable<Type> knownTypes) public async Task<IDictionary<Type, ISettingsData>> LoadAllAsync(IEnumerable<Type> knownTypes)
{ {
var result = new Dictionary<Type, ISettingsData>(); var result = new Dictionary<Type, ISettingsData>();
var allSettings = new List<ISettingsSection>();
foreach (var type in knownTypes) foreach (var type in knownTypes)
{ {
@ -100,11 +111,57 @@ public class SettingsPersistence : AbstractContextUtility, ISettingsPersistence
var loaded = (ISettingsData)((dynamic)task).Result; var loaded = (ISettingsData)((dynamic)task).Result;
result[type] = loaded; result[type] = loaded;
allSettings.Add(loaded);
} }
this.SendEvent(new SettingsAllLoadedEvent(allSettings));
return result; 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() protected override void OnInit()
{ {
_storage = this.GetUtility<IStorage>()!; _storage = this.GetUtility<IStorage>()!;

View File

@ -1,6 +1,7 @@
using GFramework.Core.extensions; using GFramework.Core.extensions;
using GFramework.Core.system; using GFramework.Core.system;
using GFramework.Game.Abstractions.setting; using GFramework.Game.Abstractions.setting;
using GFramework.Game.setting.events;
namespace GFramework.Game.setting; namespace GFramework.Game.setting;
@ -79,11 +80,22 @@ public class SettingsSystem : AbstractSystem, ISettingsSystem
/// 尝试应用可应用的设置配置 /// 尝试应用可应用的设置配置
/// </summary> /// </summary>
/// <param name="section">设置配置对象</param> /// <param name="section">设置配置对象</param>
private static void TryApply(ISettingsSection section) private void TryApply(ISettingsSection section)
{ {
if (section is IApplyAbleSettings applyable) 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;
}