diff --git a/GFramework.Game.Abstractions/setting/AudioSettings.cs b/GFramework.Game.Abstractions/setting/AudioSettings.cs
index a0e2e2d..1f0d6af 100644
--- a/GFramework.Game.Abstractions/setting/AudioSettings.cs
+++ b/GFramework.Game.Abstractions/setting/AudioSettings.cs
@@ -1,4 +1,4 @@
-namespace GFramework.Game.Abstractions.setting;
+namespace GFramework.Game.Abstractions.setting;
///
/// 音频设置类,用于管理游戏中的音频配置
@@ -19,4 +19,14 @@ public class AudioSettings : ISettingsData
/// 获取或设置音效音量,控制SFX的播放音量
///
public float SfxVolume { get; set; } = 0.8f;
+
+ ///
+ /// 重置音频设置为默认值
+ ///
+ public void Reset()
+ {
+ MasterVolume = 1.0f;
+ BgmVolume = 0.8f;
+ SfxVolume = 0.8f;
+ }
}
\ No newline at end of file
diff --git a/GFramework.Game.Abstractions/setting/GraphicsSettings.cs b/GFramework.Game.Abstractions/setting/GraphicsSettings.cs
index e27cab8..cfd7b86 100644
--- a/GFramework.Game.Abstractions/setting/GraphicsSettings.cs
+++ b/GFramework.Game.Abstractions/setting/GraphicsSettings.cs
@@ -19,4 +19,14 @@ public class GraphicsSettings : ISettingsData
/// 获取或设置屏幕分辨率高度
///
public int ResolutionHeight { get; set; } = 1080;
+
+ ///
+ /// 重置图形设置为默认值
+ ///
+ public void Reset()
+ {
+ Fullscreen = false;
+ ResolutionWidth = 1920;
+ ResolutionHeight = 1080;
+ }
}
\ No newline at end of file
diff --git a/GFramework.Game.Abstractions/setting/ISettingsData.cs b/GFramework.Game.Abstractions/setting/ISettingsData.cs
index 4894bdd..dfa1a41 100644
--- a/GFramework.Game.Abstractions/setting/ISettingsData.cs
+++ b/GFramework.Game.Abstractions/setting/ISettingsData.cs
@@ -1,6 +1,12 @@
-namespace GFramework.Game.Abstractions.setting;
+namespace GFramework.Game.Abstractions.setting;
///
/// 设置数据接口 - 纯数据,可自动创建
///
-public interface ISettingsData : ISettingsSection;
\ No newline at end of file
+public interface ISettingsData : ISettingsSection
+{
+ ///
+ /// 重置设置为默认值
+ ///
+ void Reset();
+}
\ No newline at end of file
diff --git a/GFramework.Game.Abstractions/setting/ISettingsPersistence.cs b/GFramework.Game.Abstractions/setting/ISettingsPersistence.cs
index 9e3074b..569620d 100644
--- a/GFramework.Game.Abstractions/setting/ISettingsPersistence.cs
+++ b/GFramework.Game.Abstractions/setting/ISettingsPersistence.cs
@@ -40,14 +40,4 @@ public interface ISettingsPersistence : IContextUtility
/// 加载所有已知类型的设置数据
///
Task> LoadAllAsync(IEnumerable knownTypes);
-
- ///
- /// 重置指定类型的设置数据为默认值
- ///
- Task ResetAsync() where T : class, ISettingsData, new();
-
- ///
- /// 重置所有设置数据为默认值
- ///
- Task ResetAllAsync();
}
\ No newline at end of file
diff --git a/GFramework.Game.Abstractions/setting/ISettingsSystem.cs b/GFramework.Game.Abstractions/setting/ISettingsSystem.cs
index 9912c84..2afb5b3 100644
--- a/GFramework.Game.Abstractions/setting/ISettingsSystem.cs
+++ b/GFramework.Game.Abstractions/setting/ISettingsSystem.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using GFramework.Core.Abstractions.system;
@@ -28,5 +28,23 @@ public interface ISettingsSystem : ISystem
///
/// 批量应用多个设置类型
///
+ /// 设置配置类型集合
Task Apply(IEnumerable settingsTypes);
+
+ ///
+ /// 重置指定类型的设置
+ ///
+ /// 设置类型
+ Task ResetAsync(Type settingsType);
+
+ ///
+ /// 重置指定类型的设置(泛型版本)
+ ///
+ /// 设置类型
+ Task ResetAsync() where T : class, ISettingsData, new();
+
+ ///
+ /// 重置所有设置
+ ///
+ Task ResetAllAsync();
}
\ No newline at end of file
diff --git a/GFramework.Game.Abstractions/setting/SettingsData.cs b/GFramework.Game.Abstractions/setting/SettingsData.cs
new file mode 100644
index 0000000..cc8d9ae
--- /dev/null
+++ b/GFramework.Game.Abstractions/setting/SettingsData.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Reflection;
+
+namespace GFramework.Game.Abstractions.setting;
+
+///
+/// 设置数据抽象基类,提供默认的 Reset() 实现
+///
+public abstract class SettingsData : ISettingsData
+{
+ ///
+ /// 重置设置为默认值
+ /// 使用反射将所有属性重置为它们的默认值
+ ///
+ 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);
+ }
+ }
+
+ ///
+ /// 获取指定类型的默认值
+ ///
+ /// 要获取默认值的类型
+ /// 类型的默认值
+ private static object? GetDefaultValue(Type type)
+ {
+ return type.IsValueType ? Activator.CreateInstance(type) : null;
+ }
+}
\ No newline at end of file
diff --git a/GFramework.Game/setting/SettingsPersistence.cs b/GFramework.Game/setting/SettingsPersistence.cs
index c26cea4..e777185 100644
--- a/GFramework.Game/setting/SettingsPersistence.cs
+++ b/GFramework.Game/setting/SettingsPersistence.cs
@@ -118,50 +118,6 @@ public class SettingsPersistence : AbstractContextUtility, ISettingsPersistence
return result;
}
- public async Task ResetAsync() where T : class, ISettingsData, new()
- {
- var type = typeof(T);
- var key = GetKey(type);
-
- T oldSettings;
- if (await _storage.ExistsAsync(key))
- {
- oldSettings = await _storage.ReadAsync(key);
- }
- else
- {
- oldSettings = new T();
- }
-
- var newSettings = new T();
- await _storage.WriteAsync(key, newSettings);
-
- this.SendEvent(new SettingsResetEvent(oldSettings, newSettings));
- return newSettings;
- }
-
- public async Task ResetAllAsync()
- {
- var knownTypes = new List();
-
- var audioSettings = await LoadAllAsync(knownTypes);
- var allNewSettings = new List();
-
- 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()!;
diff --git a/GFramework.Game/setting/SettingsSystem.cs b/GFramework.Game/setting/SettingsSystem.cs
index 70ba895..7f37ea7 100644
--- a/GFramework.Game/setting/SettingsSystem.cs
+++ b/GFramework.Game/setting/SettingsSystem.cs
@@ -1,6 +1,7 @@
using GFramework.Core.extensions;
using GFramework.Core.system;
using GFramework.Game.Abstractions.setting;
+using GFramework.Game.setting.commands;
using GFramework.Game.setting.events;
namespace GFramework.Game.setting;
@@ -27,59 +28,27 @@ public class SettingsSystem : AbstractSystem, ISettingsSystem
return Task.CompletedTask;
}
- ///
- /// 应用指定类型的设置配置
- ///
- /// 设置配置类型,必须是类且实现ISettingsSection接口
- /// 完成的任务
- public Task Apply() where T : class, ISettingsSection
- => Apply(typeof(T));
-
- ///
- /// 应用指定类型的设置配置
- ///
- /// 设置配置类型
- /// 完成的任务
- public Task Apply(Type settingsType)
+ public Task ResetAsync(Type settingsType)
{
- if (!_model.TryGet(settingsType, out var section))
- return Task.CompletedTask;
-
- TryApply(section);
- return Task.CompletedTask;
- }
-
- ///
- /// 应用指定类型集合的设置配置
- ///
- /// 设置配置类型集合
- /// 完成的任务
- public Task Apply(IEnumerable settingsTypes)
- {
- // 去重后遍历设置类型,获取并应用对应的设置配置
- foreach (var type in settingsTypes.Distinct())
+ return this.SendCommandAsync(new ResetSettingsCommand(new ResetSettingsInput
{
- if (_model.TryGet(type, out var section))
- {
- TryApply(section);
- }
- }
-
- return Task.CompletedTask;
+ SettingsType = settingsType
+ }));
}
- ///
- /// 初始化设置系统,获取设置模型实例
- ///
- protected override void OnInit()
+ public Task ResetAsync() where T : class, ISettingsData, new()
{
- _model = this.GetModel()!;
+ return ResetAsync(typeof(T));
+ }
+
+ public Task ResetAllAsync()
+ {
+ return this.SendCommandAsync(new ResetSettingsCommand(new ResetSettingsInput
+ {
+ SettingsType = null
+ }));
}
- ///
- /// 尝试应用可应用的设置配置
- ///
- /// 设置配置对象
private void TryApply(ISettingsSection section)
{
if (section is IApplyAbleSettings applyable)
diff --git a/GFramework.Game/setting/commands/ResetSettingsCommand.cs b/GFramework.Game/setting/commands/ResetSettingsCommand.cs
new file mode 100644
index 0000000..fa1c835
--- /dev/null
+++ b/GFramework.Game/setting/commands/ResetSettingsCommand.cs
@@ -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
+{
+ private ISettingsModel _model = null!;
+ private ISettingsPersistence _persistence = null!;
+
+ protected override void OnContextReady()
+ {
+ base.OnContextReady();
+ _model = this.GetModel()!;
+ _persistence = this.GetUtility()!;
+ }
+
+ 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(settingsData));
+ }
+
+ private async Task ResetAll()
+ {
+ var allSettings = _model.All()
+ .OfType()
+ .ToList();
+
+ foreach (var settings in allSettings)
+ {
+ settings.Reset();
+ await _persistence.SaveAsync(settings);
+ }
+
+ this.SendEvent(new SettingsResetAllEvent(allSettings));
+ }
+}
\ No newline at end of file
diff --git a/GFramework.Game/setting/commands/ResetSettingsInput.cs b/GFramework.Game/setting/commands/ResetSettingsInput.cs
new file mode 100644
index 0000000..7200737
--- /dev/null
+++ b/GFramework.Game/setting/commands/ResetSettingsInput.cs
@@ -0,0 +1,8 @@
+using GFramework.Core.Abstractions.command;
+
+namespace GFramework.Game.setting.commands;
+
+public sealed class ResetSettingsInput : ICommandInput
+{
+ public Type? SettingsType { get; init; }
+}
\ No newline at end of file
diff --git a/GFramework.Game/setting/events/SettingsResetEvent.cs b/GFramework.Game/setting/events/SettingsResetEvent.cs
index ae4e40b..be6755c 100644
--- a/GFramework.Game/setting/events/SettingsResetEvent.cs
+++ b/GFramework.Game/setting/events/SettingsResetEvent.cs
@@ -6,29 +6,13 @@ namespace GFramework.Game.setting.events;
/// 表示设置重置事件
///
/// 设置节类型
-public class SettingsResetEvent : ISettingsChangedEvent
+public class SettingsResetEvent(T newSettings) : ISettingsChangedEvent
where T : ISettingsSection
{
- ///
- /// 构造函数
- ///
- /// 重置前的设置
- /// 重置后的新设置
- public SettingsResetEvent(T oldSettings, T newSettings)
- {
- OldSettings = oldSettings;
- NewSettings = newSettings;
- }
-
- ///
- /// 获取重置前的设置
- ///
- public T OldSettings { get; }
-
///
/// 获取重置后的新设置
///
- public T NewSettings { get; }
+ public T NewSettings { get; } = newSettings;
///
/// 获取类型化的设置实例(返回新设置)
diff --git a/GFramework.Godot/setting/AudioBusMapSettings.cs b/GFramework.Godot/setting/AudioBusMapSettings.cs
index a8c8d55..883325b 100644
--- a/GFramework.Godot/setting/AudioBusMapSettings.cs
+++ b/GFramework.Godot/setting/AudioBusMapSettings.cs
@@ -1,4 +1,4 @@
-using GFramework.Game.Abstractions.setting;
+using GFramework.Game.Abstractions.setting;
namespace GFramework.Godot.setting;
@@ -25,4 +25,14 @@ public class AudioBusMapSettings : ISettingsData
/// 默认值为"SFX"
///
public string Sfx { get; set; } = "SFX";
+
+ ///
+ /// 重置音频总线映射设置为默认值
+ ///
+ public void Reset()
+ {
+ Master = "Master";
+ Bgm = "BGM";
+ Sfx = "SFX";
+ }
}
\ No newline at end of file