mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-25 13:33:28 +08:00
refactor(setting): 重构设置重置功能实现
- 移除 SettingsResetEvent 中的旧设置属性,改为仅保存新设置 - 删除 SettingsPersistence 中的重置方法,统一通过命令模式处理 - 在 SettingsSystem 中添加 ResetAsync 方法并集成命令模式 - 为 AudioSettings 和 GraphicsSettings 添加 Reset 方法实现 - 扩展 ISettingsData 接口添加 Reset 方法定义 - 从接口中移除重置相关方法定义 - 在 ISettingsSystem 中添加重置相关的异步方法声明 - 为 AudioBusMapSettings 添加 Reset 方法实现 - 新增 ResetSettingsCommand 和 ResetSettingsInput 实现命令模式 - 添加 SettingsData 抽象基类提供默认的 Reset 实现 - [skip ci]
This commit is contained in:
parent
e7285b3426
commit
a45bf27c8b
@ -1,4 +1,4 @@
|
|||||||
namespace GFramework.Game.Abstractions.setting;
|
namespace GFramework.Game.Abstractions.setting;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 音频设置类,用于管理游戏中的音频配置
|
/// 音频设置类,用于管理游戏中的音频配置
|
||||||
@ -19,4 +19,14 @@ public class AudioSettings : ISettingsData
|
|||||||
/// 获取或设置音效音量,控制SFX的播放音量
|
/// 获取或设置音效音量,控制SFX的播放音量
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public float SfxVolume { get; set; } = 0.8f;
|
public float SfxVolume { get; set; } = 0.8f;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 重置音频设置为默认值
|
||||||
|
/// </summary>
|
||||||
|
public void Reset()
|
||||||
|
{
|
||||||
|
MasterVolume = 1.0f;
|
||||||
|
BgmVolume = 0.8f;
|
||||||
|
SfxVolume = 0.8f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -19,4 +19,14 @@ public class GraphicsSettings : ISettingsData
|
|||||||
/// 获取或设置屏幕分辨率高度
|
/// 获取或设置屏幕分辨率高度
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int ResolutionHeight { get; set; } = 1080;
|
public int ResolutionHeight { get; set; } = 1080;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 重置图形设置为默认值
|
||||||
|
/// </summary>
|
||||||
|
public void Reset()
|
||||||
|
{
|
||||||
|
Fullscreen = false;
|
||||||
|
ResolutionWidth = 1920;
|
||||||
|
ResolutionHeight = 1080;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -1,6 +1,12 @@
|
|||||||
namespace GFramework.Game.Abstractions.setting;
|
namespace GFramework.Game.Abstractions.setting;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 设置数据接口 - 纯数据,可自动创建
|
/// 设置数据接口 - 纯数据,可自动创建
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface ISettingsData : ISettingsSection;
|
public interface ISettingsData : ISettingsSection
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 重置设置为默认值
|
||||||
|
/// </summary>
|
||||||
|
void Reset();
|
||||||
|
}
|
||||||
@ -40,14 +40,4 @@ 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();
|
|
||||||
}
|
}
|
||||||
@ -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.system;
|
using GFramework.Core.Abstractions.system;
|
||||||
@ -28,5 +28,23 @@ public interface ISettingsSystem : ISystem
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 批量应用多个设置类型
|
/// 批量应用多个设置类型
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <param name="settingsTypes">设置配置类型集合</param>
|
||||||
Task Apply(IEnumerable<Type> settingsTypes);
|
Task Apply(IEnumerable<Type> settingsTypes);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 重置指定类型的设置
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="settingsType">设置类型</param>
|
||||||
|
Task ResetAsync(Type settingsType);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 重置指定类型的设置(泛型版本)
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">设置类型</typeparam>
|
||||||
|
Task ResetAsync<T>() where T : class, ISettingsData, new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 重置所有设置
|
||||||
|
/// </summary>
|
||||||
|
Task ResetAllAsync();
|
||||||
}
|
}
|
||||||
36
GFramework.Game.Abstractions/setting/SettingsData.cs
Normal file
36
GFramework.Game.Abstractions/setting/SettingsData.cs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace GFramework.Game.Abstractions.setting;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置数据抽象基类,提供默认的 Reset() 实现
|
||||||
|
/// </summary>
|
||||||
|
public abstract class SettingsData : ISettingsData
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 重置设置为默认值
|
||||||
|
/// 使用反射将所有属性重置为它们的默认值
|
||||||
|
/// </summary>
|
||||||
|
public virtual void Reset()
|
||||||
|
{
|
||||||
|
var properties = GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
|
||||||
|
foreach (var prop in properties)
|
||||||
|
{
|
||||||
|
if (!prop.CanWrite || !prop.CanRead) continue;
|
||||||
|
|
||||||
|
var defaultValue = GetDefaultValue(prop.PropertyType);
|
||||||
|
prop.SetValue(this, defaultValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取指定类型的默认值
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="type">要获取默认值的类型</param>
|
||||||
|
/// <returns>类型的默认值</returns>
|
||||||
|
private static object? GetDefaultValue(Type type)
|
||||||
|
{
|
||||||
|
return type.IsValueType ? Activator.CreateInstance(type) : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -118,50 +118,6 @@ public class SettingsPersistence : AbstractContextUtility, ISettingsPersistence
|
|||||||
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>()!;
|
||||||
|
|||||||
@ -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.commands;
|
||||||
using GFramework.Game.setting.events;
|
using GFramework.Game.setting.events;
|
||||||
|
|
||||||
namespace GFramework.Game.setting;
|
namespace GFramework.Game.setting;
|
||||||
@ -27,59 +28,27 @@ public class SettingsSystem : AbstractSystem, ISettingsSystem
|
|||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
public Task ResetAsync(Type settingsType)
|
||||||
/// 应用指定类型的设置配置
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">设置配置类型,必须是类且实现ISettingsSection接口</typeparam>
|
|
||||||
/// <returns>完成的任务</returns>
|
|
||||||
public Task Apply<T>() where T : class, ISettingsSection
|
|
||||||
=> Apply(typeof(T));
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 应用指定类型的设置配置
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="settingsType">设置配置类型</param>
|
|
||||||
/// <returns>完成的任务</returns>
|
|
||||||
public Task Apply(Type settingsType)
|
|
||||||
{
|
{
|
||||||
if (!_model.TryGet(settingsType, out var section))
|
return this.SendCommandAsync(new ResetSettingsCommand(new ResetSettingsInput
|
||||||
return Task.CompletedTask;
|
{
|
||||||
|
SettingsType = settingsType
|
||||||
TryApply(section);
|
}));
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
public Task ResetAsync<T>() where T : class, ISettingsData, new()
|
||||||
/// 应用指定类型集合的设置配置
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="settingsTypes">设置配置类型集合</param>
|
|
||||||
/// <returns>完成的任务</returns>
|
|
||||||
public Task Apply(IEnumerable<Type> settingsTypes)
|
|
||||||
{
|
{
|
||||||
// 去重后遍历设置类型,获取并应用对应的设置配置
|
return ResetAsync(typeof(T));
|
||||||
foreach (var type in settingsTypes.Distinct())
|
|
||||||
{
|
|
||||||
if (_model.TryGet(type, out var section))
|
|
||||||
{
|
|
||||||
TryApply(section);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Task.CompletedTask;
|
public Task ResetAllAsync()
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 初始化设置系统,获取设置模型实例
|
|
||||||
/// </summary>
|
|
||||||
protected override void OnInit()
|
|
||||||
{
|
{
|
||||||
_model = this.GetModel<ISettingsModel>()!;
|
return this.SendCommandAsync(new ResetSettingsCommand(new ResetSettingsInput
|
||||||
|
{
|
||||||
|
SettingsType = null
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 尝试应用可应用的设置配置
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="section">设置配置对象</param>
|
|
||||||
private void TryApply(ISettingsSection section)
|
private void TryApply(ISettingsSection section)
|
||||||
{
|
{
|
||||||
if (section is IApplyAbleSettings applyable)
|
if (section is IApplyAbleSettings applyable)
|
||||||
|
|||||||
54
GFramework.Game/setting/commands/ResetSettingsCommand.cs
Normal file
54
GFramework.Game/setting/commands/ResetSettingsCommand.cs
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
using GFramework.Core.command;
|
||||||
|
using GFramework.Game.Abstractions.setting;
|
||||||
|
using GFramework.Game.setting.events;
|
||||||
|
|
||||||
|
namespace GFramework.Game.setting.commands;
|
||||||
|
|
||||||
|
public sealed class ResetSettingsCommand : AbstractAsyncCommand<ResetSettingsInput>
|
||||||
|
{
|
||||||
|
private ISettingsModel _model = null!;
|
||||||
|
private ISettingsPersistence _persistence = null!;
|
||||||
|
|
||||||
|
protected override void OnContextReady()
|
||||||
|
{
|
||||||
|
base.OnContextReady();
|
||||||
|
_model = this.GetModel<ISettingsModel>()!;
|
||||||
|
_persistence = this.GetUtility<ISettingsPersistence>()!;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override async Task OnExecuteAsync(ResetSettingsInput input)
|
||||||
|
{
|
||||||
|
if (input.SettingsType == null)
|
||||||
|
await ResetAll();
|
||||||
|
else
|
||||||
|
await ResetSingle(input.SettingsType);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task ResetSingle(Type settingsType)
|
||||||
|
{
|
||||||
|
if (!_model.TryGet(settingsType, out var section))
|
||||||
|
throw new InvalidOperationException($"Settings {settingsType.Name} not found");
|
||||||
|
|
||||||
|
if (section is not ISettingsData settingsData)
|
||||||
|
throw new InvalidOperationException($"Settings {settingsType.Name} is not ISettingsData");
|
||||||
|
|
||||||
|
settingsData.Reset();
|
||||||
|
await _persistence.SaveAsync(settingsData);
|
||||||
|
this.SendEvent(new SettingsResetEvent<ISettingsSection>(settingsData));
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task ResetAll()
|
||||||
|
{
|
||||||
|
var allSettings = _model.All()
|
||||||
|
.OfType<ISettingsData>()
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
foreach (var settings in allSettings)
|
||||||
|
{
|
||||||
|
settings.Reset();
|
||||||
|
await _persistence.SaveAsync(settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.SendEvent(new SettingsResetAllEvent(allSettings));
|
||||||
|
}
|
||||||
|
}
|
||||||
8
GFramework.Game/setting/commands/ResetSettingsInput.cs
Normal file
8
GFramework.Game/setting/commands/ResetSettingsInput.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
using GFramework.Core.Abstractions.command;
|
||||||
|
|
||||||
|
namespace GFramework.Game.setting.commands;
|
||||||
|
|
||||||
|
public sealed class ResetSettingsInput : ICommandInput
|
||||||
|
{
|
||||||
|
public Type? SettingsType { get; init; }
|
||||||
|
}
|
||||||
@ -6,29 +6,13 @@ namespace GFramework.Game.setting.events;
|
|||||||
/// 表示设置重置事件
|
/// 表示设置重置事件
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">设置节类型</typeparam>
|
/// <typeparam name="T">设置节类型</typeparam>
|
||||||
public class SettingsResetEvent<T> : ISettingsChangedEvent
|
public class SettingsResetEvent<T>(T newSettings) : ISettingsChangedEvent
|
||||||
where T : ISettingsSection
|
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>
|
||||||
/// 获取重置后的新设置
|
/// 获取重置后的新设置
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public T NewSettings { get; }
|
public T NewSettings { get; } = newSettings;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取类型化的设置实例(返回新设置)
|
/// 获取类型化的设置实例(返回新设置)
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
using GFramework.Game.Abstractions.setting;
|
using GFramework.Game.Abstractions.setting;
|
||||||
|
|
||||||
namespace GFramework.Godot.setting;
|
namespace GFramework.Godot.setting;
|
||||||
|
|
||||||
@ -25,4 +25,14 @@ public class AudioBusMapSettings : ISettingsData
|
|||||||
/// 默认值为"SFX"
|
/// 默认值为"SFX"
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Sfx { get; set; } = "SFX";
|
public string Sfx { get; set; } = "SFX";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 重置音频总线映射设置为默认值
|
||||||
|
/// </summary>
|
||||||
|
public void Reset()
|
||||||
|
{
|
||||||
|
Master = "Master";
|
||||||
|
Bgm = "BGM";
|
||||||
|
Sfx = "SFX";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user