feat(setting): 添加设置重置功能并重构Godot设置类

- 在SettingsModel中添加Reset<T>()和ResetAll()方法
- 在SettingsSystem中添加异步Reset<T>()和ResetAll()方法
- 扩展ISettingsModel和ISettingsSystem接口以支持重置操作
- 重构GodotAudioSettings、GodotGraphicsSettings和GodotLocalizationSettings类
- 将直接依赖设置对象改为依赖ISettingsModel接口
- 实现IResettable接口以支持设置重置功能
- [release ci]
This commit is contained in:
GeWuYou 2026-01-29 21:51:25 +08:00
parent 7e4d93aa2b
commit 0c0ddaab7f
7 changed files with 116 additions and 46 deletions

View File

@ -63,4 +63,15 @@ public interface ISettingsModel : IModel
/// <param name="settingTypes">要初始化的设置类型数组</param> /// <param name="settingTypes">要初始化的设置类型数组</param>
/// <returns>异步操作任务</returns> /// <returns>异步操作任务</returns>
Task InitializeAsync(params Type[] settingTypes); Task InitializeAsync(params Type[] settingTypes);
/// <summary>
/// 重置指定类型的设置
/// </summary>
/// <typeparam name="T">要重置的设置类型必须实现IResettable接口并具有无参构造函数</typeparam>
void Reset<T>() where T : class, IResettable, new();
/// <summary>
/// 重置所有设置
/// </summary>
void ResetAll();
} }

View File

@ -25,4 +25,17 @@ public interface ISettingsSystem : ISystem
/// </summary> /// </summary>
/// <returns>表示异步操作的任务</returns> /// <returns>表示异步操作的任务</returns>
Task SaveAll(); Task SaveAll();
/// <summary>
/// 重置指定类型的设置
/// </summary>
/// <typeparam name="T">设置类型必须继承自class并实现IPersistentApplyAbleSettings接口</typeparam>
/// <returns>表示异步操作的任务</returns>
Task Reset<T>() where T : class, IPersistentApplyAbleSettings, new();
/// <summary>
/// 重置所有设置
/// </summary>
/// <returns>表示异步操作的任务</returns>
Task ResetAll();
} }

View File

@ -125,6 +125,58 @@ public class SettingsModel<TRepository>(IDataRepository? repository)
return this; return this;
} }
// -----------------------------
// Load / Init
// -----------------------------
/// <summary>
/// 异步初始化设置模型,加载指定类型的设置数据
/// </summary>
/// <param name="settingTypes">要初始化的设置类型数组</param>
public async Task InitializeAsync(params Type[] settingTypes)
{
foreach (var type in settingTypes)
{
if (!typeof(IResettable).IsAssignableFrom(type) ||
!typeof(IData).IsAssignableFrom(type))
continue;
try
{
var loaded = (ISettingsSection)await Repository.LoadAsync(type);
var migrated = MigrateIfNeeded(loaded);
_dataSettings[type] = (IResettable)migrated;
_migrationCache.TryRemove(type, out _);
}
catch (Exception ex)
{
Log.Error($"Failed to load settings for {type.Name}", ex);
}
}
}
/// <summary>
/// 重置指定类型的可重置对象
/// </summary>
/// <typeparam name="T">要重置的对象类型必须是class类型实现IResettable接口并具有无参构造函数</typeparam>
public void Reset<T>() where T : class, IResettable, new()
{
var data = GetData<T>();
data.Reset();
}
/// <summary>
/// 重置所有存储的数据设置对象
/// </summary>
public void ResetAll()
{
foreach (var data in _dataSettings.Values)
{
data.Reset();
}
}
/// <summary> /// <summary>
/// 如果需要的话,对设置节进行版本迁移 /// 如果需要的话,对设置节进行版本迁移
/// </summary> /// </summary>
@ -157,37 +209,6 @@ public class SettingsModel<TRepository>(IDataRepository? repository)
} }
// -----------------------------
// Load / Init
// -----------------------------
/// <summary>
/// 异步初始化设置模型,加载指定类型的设置数据
/// </summary>
/// <param name="settingTypes">要初始化的设置类型数组</param>
public async Task InitializeAsync(params Type[] settingTypes)
{
foreach (var type in settingTypes)
{
if (!typeof(IResettable).IsAssignableFrom(type) ||
!typeof(IData).IsAssignableFrom(type))
continue;
try
{
var loaded = (ISettingsSection)await Repository.LoadAsync(type);
var migrated = MigrateIfNeeded(loaded);
_dataSettings[type] = (IResettable)migrated;
_migrationCache.TryRemove(type, out _);
}
catch (Exception ex)
{
Log.Error($"Failed to load settings for {type.Name}", ex);
}
}
}
/// <summary> /// <summary>
/// 初始化方法,用于获取设置持久化服务 /// 初始化方法,用于获取设置持久化服务
/// </summary> /// </summary>

View File

@ -58,6 +58,27 @@ public class SettingsSystem<TRepository>(IDataRepository? repository)
} }
} }
/// <summary>
/// 重置所有设置并应用更改
/// </summary>
/// <returns>异步任务</returns>
public async Task ResetAll()
{
_model.ResetAll();
await ApplyAll();
}
/// <summary>
/// 重置指定类型的设置并应用更改
/// </summary>
/// <typeparam name="T">设置类型必须实现IPersistentApplyAbleSettings接口且具有无参构造函数</typeparam>
/// <returns>异步任务</returns>
public async Task Reset<T>() where T : class, IPersistentApplyAbleSettings, new()
{
_model.Reset<T>();
await Apply<T>();
}
/// <summary> /// <summary>
/// 初始化设置系统,获取设置模型实例 /// 初始化设置系统,获取设置模型实例

View File

@ -8,9 +8,9 @@ namespace GFramework.Godot.setting;
/// <summary> /// <summary>
/// Godot音频设置实现类用于应用音频配置到Godot音频系统 /// Godot音频设置实现类用于应用音频配置到Godot音频系统
/// </summary> /// </summary>
/// <param name="settings">音频设置对象,包含主音量、背景音乐音量和音效音量</param> /// <param name="model">设置模型对象,提供音频设置数据访问</param>
/// <param name="audioBusMap">音频总线映射对象,定义了不同音频类型的总线名称</param> /// <param name="audioBusMap">音频总线映射对象,定义了不同音频类型的总线名称</param>
public class GodotAudioSettings(AudioSettings settings, AudioBusMap audioBusMap) public class GodotAudioSettings(ISettingsModel model, AudioBusMap audioBusMap)
: IPersistentApplyAbleSettings : IPersistentApplyAbleSettings
{ {
/// <summary> /// <summary>
@ -19,16 +19,18 @@ public class GodotAudioSettings(AudioSettings settings, AudioBusMap audioBusMap)
/// <returns>表示异步操作的任务</returns> /// <returns>表示异步操作的任务</returns>
public Task Apply() public Task Apply()
{ {
var settings = model.GetData<AudioSettings>();
SetBus(audioBusMap.Master, settings.MasterVolume); SetBus(audioBusMap.Master, settings.MasterVolume);
SetBus(audioBusMap.Bgm, settings.BgmVolume); SetBus(audioBusMap.Bgm, settings.BgmVolume);
SetBus(audioBusMap.Sfx, settings.SfxVolume); SetBus(audioBusMap.Sfx, settings.SfxVolume);
return Task.CompletedTask; return Task.CompletedTask;
} }
public void Reset() /// <summary>
{ /// 重置音频设置为默认值
settings.Reset(); /// </summary>
} public void Reset() =>
model.GetData<AudioSettings>().Reset();
/// <summary> /// <summary>
/// 设置指定音频总线的音量 /// 设置指定音频总线的音量

View File

@ -7,8 +7,8 @@ namespace GFramework.Godot.setting;
/// <summary> /// <summary>
/// Godot图形设置应用器 /// Godot图形设置应用器
/// </summary> /// </summary>
/// <param name="settings">图形设置配置对象</param> /// <param name="model">设置模型接口</param>
public class GodotGraphicsSettings(GraphicsSettings settings) : IPersistentApplyAbleSettings public class GodotGraphicsSettings(ISettingsModel model) : IPersistentApplyAbleSettings
{ {
/// <summary> /// <summary>
/// 应用图形设置到Godot引擎 /// 应用图形设置到Godot引擎
@ -16,6 +16,7 @@ public class GodotGraphicsSettings(GraphicsSettings settings) : IPersistentApply
/// <returns>异步任务</returns> /// <returns>异步任务</returns>
public async Task Apply() public async Task Apply()
{ {
var settings = model.GetData<GraphicsSettings>();
// 创建分辨率向量 // 创建分辨率向量
var size = new Vector2I(settings.ResolutionWidth, settings.ResolutionHeight); var size = new Vector2I(settings.ResolutionWidth, settings.ResolutionHeight);
@ -42,8 +43,8 @@ public class GodotGraphicsSettings(GraphicsSettings settings) : IPersistentApply
await Task.CompletedTask; await Task.CompletedTask;
} }
public void Reset() /// <summary>
{ /// 重置图形设置
settings.Reset(); /// </summary>
} public void Reset() => model.GetData<GraphicsSettings>().Reset();
} }

View File

@ -21,9 +21,9 @@ namespace GFramework.Godot.setting;
/// <summary> /// <summary>
/// Godot本地化设置类负责应用本地化配置到Godot引擎 /// Godot本地化设置类负责应用本地化配置到Godot引擎
/// </summary> /// </summary>
/// <param name="settings">本地化设置对象</param> /// <param name="model">设置模型</param>
/// <param name="localizationMap">本地化映射表</param> /// <param name="localizationMap">本地化映射表</param>
public class GodotLocalizationSettings(LocalizationSettings settings, LocalizationMap localizationMap) public class GodotLocalizationSettings(ISettingsModel model, LocalizationMap localizationMap)
: IPersistentApplyAbleSettings : IPersistentApplyAbleSettings
{ {
/// <summary> /// <summary>
@ -32,6 +32,7 @@ public class GodotLocalizationSettings(LocalizationSettings settings, Localizati
/// <returns>完成的任务</returns> /// <returns>完成的任务</returns>
public Task Apply() public Task Apply()
{ {
var settings = model.GetData<LocalizationSettings>();
// 尝试从映射表获取 Godot locale // 尝试从映射表获取 Godot locale
var locale = localizationMap.LanguageMap.GetValueOrDefault(settings.Language, "en"); var locale = localizationMap.LanguageMap.GetValueOrDefault(settings.Language, "en");
// 默认值 // 默认值
@ -42,5 +43,5 @@ public class GodotLocalizationSettings(LocalizationSettings settings, Localizati
/// <summary> /// <summary>
/// 重置本地化设置 /// 重置本地化设置
/// </summary> /// </summary>
public void Reset() => settings.Reset(); public void Reset() => model.GetData<LocalizationSettings>().Reset();
} }