mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-25 21:34:28 +08:00
- 新增 Core API 参考文档,涵盖架构与模块、数据模型与系统、命令与查询等核心组件 - 添加事件系统接口详细文档,包括 IEvent、IEventBus、IUnRegister 等接口说明 - 提供完整的 API 使用示例路径、最佳实践与性能建议 - 包含架构图、依赖关系图与故障排查指南 - 添加测试用例参考与扩展方法说明 - [skip ci]
17 KiB
17 KiB
设置系统核心
**本文引用的文件** - [SettingsSystem.cs](file://GFramework.Game/setting/SettingsSystem.cs) - [ISettingsSystem.cs](file://GFramework.Game.Abstractions/setting/ISettingsSystem.cs) - [SettingsModel.cs](file://GFramework.Game/setting/SettingsModel.cs) - [ISettingsModel.cs](file://GFramework.Game.Abstractions/setting/ISettingsModel.cs) - [SettingsPersistence.cs](file://GFramework.Game/setting/SettingsPersistence.cs) - [ISettingsPersistence.cs](file://GFramework.Game.Abstractions/setting/ISettingsPersistence.cs) - [IApplyAbleSettings.cs](file://GFramework.Game.Abstractions/setting/IApplyAbleSettings.cs) - [ISettingsSection.cs](file://GFramework.Game.Abstractions/setting/ISettingsSection.cs) - [ISettingsData.cs](file://GFramework.Game.Abstractions/setting/ISettingsData.cs) - [SettingsApplyingEvent.cs](file://GFramework.Game/setting/events/SettingsApplyingEvent.cs) - [SettingsAppliedEvent.cs](file://GFramework.Game/setting/events/SettingsAppliedEvent.cs) - [SettingsAllLoadedEvent.cs](file://GFramework.Game/setting/events/SettingsAllLoadedEvent.cs) - [SettingsSavedEvent.cs](file://GFramework.Game/setting/events/SettingsSavedEvent.cs) - [SettingsLoadedEvent.cs](file://GFramework.Game/setting/events/SettingsLoadedEvent.cs) - [GodotAudioSettings.cs](file://GFramework.Godot/setting/GodotAudioSettings.cs) - [GodotGraphicsSettings.cs](file://GFramework.Godot/setting/GodotGraphicsSettings.cs) - [GraphicsSettings.cs](file://GFramework.Game.Abstractions/setting/GraphicsSettings.cs) - [AudioSettings.cs](file://GFramework.Game.Abstractions/setting/AudioSettings.cs) - [README.md(设置系统)](file://GFramework.Game/setting/README.md)目录
简介
本文件聚焦于GFramework设置系统的核心组件,围绕SettingsSystem类展开,深入解析其设置应用机制、批量应用策略与异常处理流程;同时阐明ISettingsSystem接口的设计理念与方法签名,并结合事件系统说明设置应用的生命周期管理与状态流转。文档还提供核心API参考、使用示例与最佳实践,帮助开发者在不同平台(如Godot)中正确集成与扩展设置系统。
项目结构
设置系统位于Game层,采用“模型-系统-事件”的分层设计:
- 模型层:SettingsModel负责设置节的注册、检索与聚合
- 系统层:SettingsSystem负责设置应用的调度与异常传播
- 事件层:围绕设置加载、保存、应用等生命周期发出事件
- 平台适配:Godot等平台通过IApplyAbleSettings实现具体应用逻辑
graph TB
subgraph "模型层"
SM["SettingsModel<br/>管理ISettingsSection集合"]
end
subgraph "系统层"
SS["SettingsSystem<br/>应用ISettingsSection"]
end
subgraph "事件层"
SEA["SettingsApplyingEvent"]
SEAE["SettingsAppliedEvent"]
SLE["SettingsLoadedEvent"]
SSE["SettingsSavedEvent"]
SALL["SettingsAllLoadedEvent"]
end
subgraph "平台适配"
GA["GodotAudioSettings"]
GG["GodotGraphicsSettings"]
end
SM --> SS
SS --> SEA
SS --> SEAE
SS -. 可能触发 .-> SLE
SS -. 可能触发 .-> SSE
SS -. 可能触发 .-> SALL
GA --> |"实现"| IAS["IApplyAbleSettings"]
GG --> |"实现"| IAS
SM --> GA
SM --> GG
图表来源
- SettingsModel.cs
- SettingsSystem.cs
- SettingsApplyingEvent.cs
- SettingsAppliedEvent.cs
- GodotAudioSettings.cs
- GodotGraphicsSettings.cs
章节来源
核心组件
- ISettingsSystem:定义设置应用的统一入口,支持ApplyAll、Apply(Type)、Apply()、Apply(IEnumerable)四种应用方式
- SettingsSystem:具体实现,负责遍历模型中的设置节,筛选可应用设置并触发事件与异常传播
- ISettingsModel:提供设置节的注册、检索与聚合能力
- IApplyAbleSettings:可应用设置接口,定义Apply方法
- 事件体系:SettingsApplyingEvent、SettingsAppliedEvent等,贯穿设置应用生命周期
章节来源
- ISettingsSystem.cs
- SettingsSystem.cs
- SettingsModel.cs
- IApplyAbleSettings.cs
- SettingsApplyingEvent.cs
- SettingsAppliedEvent.cs
架构总览
设置系统遵循“模型-系统-事件”分层,系统层不直接操作平台细节,而是通过可应用设置接口抽象进行应用;事件层提供可观测性与可观测性扩展点。
classDiagram
class ISettingsSystem {
+ApplyAll() Task
+Apply(Type) Task
+Apply<T>() Task
+Apply(IEnumerable~Type~) Task
}
class SettingsSystem {
-ISettingsModel _model
+ApplyAll() Task
+Apply(Type) Task
+Apply<T>() Task
+Apply(IEnumerable~Type~) Task
-TryApply(ISettingsSection) void
}
class ISettingsModel {
+GetData<T>() T
+RegisterApplicator<T>(T) ISettingsModel
+GetApplicator<T>() T?
+TryGet(Type, out ISettingsSection) bool
+All() IEnumerable~ISettingsSection~
}
class SettingsModel {
-Dictionary<Type, IApplyAbleSettings> _applicators
-Dictionary<Type, ISettingsData> _dataSettings
+GetData<T>() T
+RegisterApplicator<T>(T) ISettingsModel
+GetApplicator<T>() T?
+TryGet(Type, out ISettingsSection) bool
+All() IEnumerable~ISettingsSection~
}
class IApplyAbleSettings {
+Apply() Task
}
class ISettingsSection
class ISettingsData {
+Reset() void
}
ISettingsSystem <|.. SettingsSystem
ISettingsModel <|.. SettingsModel
ISettingsSection <|-- IApplyAbleSettings
ISettingsSection <|-- ISettingsData
SettingsSystem --> ISettingsModel : "依赖"
SettingsModel --> IApplyAbleSettings : "注册/检索"
SettingsModel --> ISettingsData : "注册/检索"
图表来源
- ISettingsSystem.cs
- SettingsSystem.cs
- SettingsModel.cs
- IApplyAbleSettings.cs
- ISettingsSection.cs
- ISettingsData.cs
详细组件分析
SettingsSystem 类分析
-
设计要点
- 继承自AbstractSystem,通过GetModel获取ISettingsModel
- 仅对实现IApplyAbleSettings的设置节执行应用,非可应用设置会被忽略
- 应用前发送“正在应用”事件,应用结果(成功/失败)发送“已应用”事件
- 异常捕获后仍抛出,保证上层可感知失败并进行恢复
-
方法详解
- ApplyAll:遍历模型中所有设置节,逐个调用TryApply
- Apply(Type):根据类型从模型获取设置节,若存在则调用TryApply
- Apply():泛型版本,委托给Apply(Type)
- Apply(IEnumerable):去重后批量应用,提升效率
-
生命周期与事件
- 应用开始:发送SettingsApplyingEvent
- 应用结束:发送SettingsAppliedEvent(成功或失败均会发送)
- 异常:捕获后发送失败事件并向上抛出
-
异常处理与恢复
- TryApply内部捕获异常,确保事件一致性
- 抛出异常使调用方可以决定回滚或记录日志
sequenceDiagram
participant Caller as "调用方"
participant Sys as "SettingsSystem"
participant Model as "ISettingsModel"
participant Sect as "ISettingsSection"
participant App as "IApplyAbleSettings"
participant Bus as "事件总线"
Caller->>Sys : 调用 ApplyAll()
Sys->>Model : All()
loop 遍历每个设置节
Sys->>Model : TryGet(type, out section)
alt 找到且可应用
Sys->>Bus : 发送 SettingsApplyingEvent
Sys->>App : Apply()
alt 成功
Sys->>Bus : 发送 SettingsAppliedEvent(true)
else 失败
Sys->>Bus : 发送 SettingsAppliedEvent(false, ex)
Sys-->>Caller : 抛出异常
end
else 未找到或不可应用
Sys-->>Sys : 忽略
end
end
Sys-->>Caller : 返回已完成任务
图表来源
章节来源
ISettingsSystem 接口设计
-
设计理念
- 统一设置应用入口,屏蔽具体实现差异
- 支持单类型、泛型、批量应用,满足不同场景需求
- 返回Task以契合异步应用模式
-
方法签名与语义
- ApplyAll:应用所有可应用设置
- Apply(Type):按类型应用设置
- Apply():泛型约束为class且实现ISettingsSection
- Apply(IEnumerable):批量应用,内部去重
-
使用场景
- 启动时一次性应用全部设置
- 运行时按需应用某类设置
- 批量应用多类设置,避免重复应用同一类型
章节来源
SettingsModel 与 ISettingsModel
-
能力概览
- GetData():按类型获取或创建数据设置实例
- RegisterApplicator():注册可应用设置实例
- GetApplicator():获取已注册的可应用设置
- TryGet(Type, out ISettingsSection):优先从数据设置查找,再从可应用设置查找
- All():合并两类设置节集合
-
复杂度与性能
- 字典查找近似O(1),All()合并两个集合,整体开销与设置数量线性相关
- 建议在高频应用场景中缓存常用类型
章节来源
IApplyAbleSettings 与 ISettingsData
- IApplyAbleSettings
- 定义Apply方法,返回Task,便于平台侧执行异步应用(如Godot图形/音频设置)
- ISettingsData
- 继承ISettingsSection,提供Reset方法,用于恢复默认值
章节来源
平台适配示例(Godot)
- GodotAudioSettings
- 通过AudioServer设置各总线音量,应用前校验总线存在性
- GodotGraphicsSettings
- 通过DisplayServer设置窗口模式、尺寸与位置,支持全屏与窗口化切换
章节来源
设置应用流程与事件触发时机
- 触发顺序
- SettingsApplyingEvent:在TryApply开始时发送
- SettingsAppliedEvent:无论成功或失败都会发送
- 状态管理
- 成功:Success=true,Error=null
- 失败:Success=false,Error=异常对象
- 与其他模块的关系
- SettingsSystem与ISettingsModel交互获取设置节
- SettingsSystem与事件总线交互发布应用事件
- SettingsSystem不直接依赖平台API,通过IApplyAbleSettings抽象实现
flowchart TD
Start(["进入 TryApply"]) --> Check["判断是否实现 IApplyAbleSettings"]
Check --> |否| Skip["忽略此设置节"]
Check --> |是| SendApplying["发送 SettingsApplyingEvent"]
SendApplying --> TryApply["调用 Apply()"]
TryApply --> Success{"是否抛出异常?"}
Success --> |否| SendOk["发送 SettingsAppliedEvent(true)"]
Success --> |是| SendFail["发送 SettingsAppliedEvent(false, ex)"]
SendOk --> Throw["继续执行不抛出"]
SendFail --> ReThrow["重新抛出异常"]
Skip --> End(["结束"])
Throw --> End
ReThrow --> End
图表来源
依赖关系分析
- 组件耦合
- SettingsSystem依赖ISettingsModel,低耦合高内聚
- SettingsModel内部维护两类字典,职责清晰
- 外部依赖
- 事件系统:通过SendEvent发布事件
- 平台API:由IApplyAbleSettings实现(如Godot)
- 循环依赖
- 未发现循环依赖,事件与系统解耦良好
graph LR
SS["SettingsSystem"] --> IM["ISettingsModel"]
IM --> SD["SettingsData"]
IM --> IA["IApplyAbleSettings"]
SS --> EV1["SettingsApplyingEvent"]
SS --> EV2["SettingsAppliedEvent"]
IA --> Plat["平台API如Godot"]
图表来源
章节来源
性能考量
- 批量应用优化
- Apply(IEnumerable)内部对类型集合去重,避免重复应用同一类型
- 查找与遍历
- SettingsModel的TryGet优先从数据设置字典查找,再从可应用设置字典查找,均为O(1)
- ApplyAll与Apply(IEnumerable)遍历集合,整体O(n)
- 异步应用
- IApplyAbleSettings.Apply返回Task,允许平台侧异步执行(如Godot设置),避免阻塞主线程
故障排查指南
- 症状:设置未生效
- 检查设置是否实现IApplyAbleSettings
- 确认已在ISettingsModel中注册(RegisterApplicator或GetData后注册)
- 症状:应用过程中抛出异常
- SettingsAppliedEvent.Success=false,Error包含异常对象
- 上层应捕获异常并进行回滚或降级处理
- 症状:事件未触发
- 确认SettingsSystem已正确初始化并获取ISettingsModel
- 确认事件订阅正常
章节来源
结论
SettingsSystem通过清晰的接口抽象与事件驱动,实现了设置应用的统一入口与可观测性。ISettingsSystem提供了灵活的应用策略(单类型、泛型、批量),配合TryApply的异常处理与事件传播,使得设置系统既易于扩展又便于维护。在平台适配方面,IApplyAbleSettings将平台细节封装在实现类中,保持核心系统的稳定与通用。
附录
核心API参考
- ISettingsSystem
- ApplyAll(): 应用所有可应用设置
- Apply(Type): 按类型应用设置
- Apply(): 泛型应用,约束T为class且实现ISettingsSection
- Apply(IEnumerable): 批量应用,内部去重
- ISettingsModel
- GetData(): 获取或创建数据设置实例
- RegisterApplicator(): 注册可应用设置实例
- GetApplicator(): 获取已注册的可应用设置
- TryGet(Type, out ISettingsSection): 尝试获取设置节
- All(): 获取所有设置节集合
- IApplyAbleSettings
- Apply(): 异步应用设置到平台系统
- ISettingsData
- Reset(): 重置为默认值
章节来源
使用示例与最佳实践
- 基本使用
- 获取ISettingsModel,使用GetData()获取或创建设置实例
- 通过RegisterApplicator()注册可应用设置
- 使用ISettingsSystem.ApplyAll()一次性应用所有设置
- 最佳实践
- 将平台相关设置封装为IApplyAbleSettings实现类,避免在系统层直接耦合平台API
- 对批量应用的类型集合进行去重,减少重复工作
- 在应用前订阅SettingsApplyingEvent,应用后订阅SettingsAppliedEvent,以便进行日志与监控
- 对可能失败的设置应用进行异常捕获与回滚策略设计
章节来源