GeWuYou a79f02c987 docs(api): 添加 Core API 参考文档与事件系统接口文档
- 新增 Core API 参考文档,涵盖架构与模块、数据模型与系统、命令与查询等核心组件
- 添加事件系统接口详细文档,包括 IEvent、IEventBus、IUnRegister 等接口说明
- 提供完整的 API 使用示例路径、最佳实践与性能建议
- 包含架构图、依赖关系图与故障排查指南
- 添加测试用例参考与扩展方法说明
- [skip ci]
2026-01-21 23:45:10 +08:00

19 KiB
Raw Blame History

设置系统

**本文引用的文件** - [SettingsSystem.cs](file://GFramework.Game/setting/SettingsSystem.cs) - [SettingsModel.cs](file://GFramework.Game/setting/SettingsModel.cs) - [SettingsPersistence.cs](file://GFramework.Game/setting/SettingsPersistence.cs) - [README.md](file://GFramework.Game/setting/README.md) - [ISettingsSystem.cs](file://GFramework.Game.Abstractions/setting/ISettingsSystem.cs) - [ISettingsModel.cs](file://GFramework.Game.Abstractions/setting/ISettingsModel.cs) - [ISettingsPersistence.cs](file://GFramework.Game.Abstractions/setting/ISettingsPersistence.cs) - [ISettingsSection.cs](file://GFramework.Game.Abstractions/setting/ISettingsSection.cs) - [SettingsChangedEvent.cs](file://GFramework.Game/setting/events/SettingsChangedEvent.cs) - [SettingsSavedEvent.cs](file://GFramework.Game/setting/events/SettingsSavedEvent.cs) - [SettingsAllLoadedEvent.cs](file://GFramework.Game/setting/events/SettingsAllLoadedEvent.cs) - [SettingsBatchChangedEvent.cs](file://GFramework.Game/setting/events/SettingsBatchChangedEvent.cs) - [AudioSettings.cs](file://GFramework.Game.Abstractions/setting/AudioSettings.cs) - [GraphicsSettings.cs](file://GFramework.Game.Abstractions/setting/GraphicsSettings.cs) - [GodotAudioSettings.cs](file://GFramework.Godot/setting/GodotAudioSettings.cs) - [GodotGraphicsSettings.cs](file://GFramework.Godot/setting/GodotGraphicsSettings.cs)

目录

  1. 简介
  2. 项目结构
  3. 核心组件
  4. 架构总览
  5. 详细组件分析
  6. 依赖关系分析
  7. 性能考量
  8. 故障排查指南
  9. 结论
  10. 附录

简介

本文件为 GFramework 设置系统Settings System的权威功能文档覆盖配置管理机制、数据模型、持久化策略、事件系统、接口设计与最佳实践。重点围绕以下目标展开

  • 设置项注册与生命周期管理
  • 验证规则与默认值处理策略
  • SettingsModel 数据模型的结构化存储与访问模式
  • SettingsPersistence 的序列化、存储位置与加载机制
  • 设置事件系统(如 SettingsChangedEvent、SettingsSavedEvent 等)的触发时机与处理流程
  • ISettingsSystem、ISettingsModel、ISettingsPersistence 等接口的设计理念与使用方法
  • 实际使用示例、配置选项、API 参考与数据一致性保障策略

项目结构

设置系统位于 GFramework.Game 与 GFramework.Game.Abstractions 中,并在 GFramework.Godot 提供具体平台实现(如 Godot 音频/图形设置)。核心文件分布如下:

  • 设置系统与模型SettingsSystem.cs、SettingsModel.cs
  • 持久化SettingsPersistence.cs
  • 事件SettingsChangedEvent.cs、SettingsSavedEvent.cs、SettingsAllLoadedEvent.cs、SettingsBatchChangedEvent.cs
  • 抽象接口ISettingsSystem.cs、ISettingsModel.cs、ISettingsPersistence.cs、ISettingsSection.cs
  • 示例设置数据AudioSettings.cs、GraphicsSettings.cs
  • 平台应用器GodotAudioSettings.cs、GodotGraphicsSettings.cs
graph TB
subgraph "抽象层"
IModel["ISettingsModel"]
ISystem["ISettingsSystem"]
IPersistence["ISettingsPersistence"]
ISection["ISettingsSection"]
end
subgraph "实现层"
Model["SettingsModel"]
System["SettingsSystem"]
Persist["SettingsPersistence"]
end
subgraph "平台实现"
Audio["GodotAudioSettings"]
Graphics["GodotGraphicsSettings"]
end
IModel --> Model
ISystem --> System
IPersistence --> Persist
ISection --> Audio
ISection --> Graphics
Model --> ISection
System --> Model
Persist --> IPersistence

图表来源

章节来源

核心组件

  • SettingsModel集中管理“设置节”ISettingsSection提供类型安全的获取、注册与聚合查询能力内部维护两类映射数据设置ISettingsData与可应用设置IApplyAbleSettings
  • SettingsSystem负责应用设置ApplyAll/Apply/Apply(IEnumerable)),自动识别 IApplyAbleSettings 并触发应用前后事件。
  • SettingsPersistence负责设置数据的异步加载、保存、存在性检查与批量操作统一键命名策略Settings_{TypeName}),并与事件系统联动。

章节来源

架构总览

设置系统采用“模型-系统-持久化”的分层设计,结合事件驱动与接口抽象,实现高内聚低耦合的配置管理。

classDiagram
class ISettingsSection {
<<interface>>
}
class ISettingsModel {
<<interface>>
+GetData<T>()
+TryGet(type, out section)
+GetApplicator<T>()
+All()
+RegisterApplicator<T>(applicator)
}
class ISettingsSystem {
<<interface>>
+ApplyAll()
+Apply(type)
+Apply<T>()
+Apply(types)
}
class ISettingsPersistence {
<<interface>>
+LoadAsync<T>()
+SaveAsync<T>(section)
+ExistsAsync<T>()
+DeleteAsync<T>()
+SaveAllAsync(allData)
+LoadAllAsync(knownTypes)
}
class SettingsModel {
-Dictionary<Type, ISettingsData> _dataSettings
-Dictionary<Type, IApplyAbleSettings> _applicators
+GetData<T>()
+TryGet(type, out section)
+GetApplicator<T>()
+All()
+RegisterApplicator<T>(applicator)
}
class SettingsSystem {
-ISettingsModel _model
+ApplyAll()
+Apply(type)
+Apply<T>()
+Apply(types)
-TryApply(section)
}
class SettingsPersistence {
-IStorage _storage
+LoadAsync<T>()
+SaveAsync<T>(section)
+ExistsAsync<T>()
+DeleteAsync<T>()
+SaveAllAsync(allData)
+LoadAllAsync(knownTypes)
-GetKey<T>()
}
ISettingsModel <|.. SettingsModel
ISettingsSystem <|.. SettingsSystem
ISettingsPersistence <|.. SettingsPersistence
SettingsSystem --> ISettingsModel : "依赖"
SettingsModel --> ISettingsSection : "管理"
SettingsPersistence --> ISettingsPersistence : "实现"

图表来源

详细组件分析

SettingsModel 数据模型

  • 职责与特性
    • 统一管理 ISettingsSection 的数据设置与可应用设置。
    • 通过 GetData() 自动创建并缓存 ISettingsData 实例,确保类型安全与单例语义。
    • 通过 RegisterApplicator() 手动注册 IApplyAbleSettings便于后续由 SettingsSystem 应用。
    • TryGet/All 提供查询与聚合访问,支持上层系统按需筛选。
  • 复杂度与性能
    • GetData() 基于字典查找与创建,平均 O(1),首次创建包含对象构造成本。
    • TryGet/All 为 O(n) 聚合n 为已注册数量),建议在高频路径避免频繁 All()。
  • 默认值与验证
    • 默认值由 ISettingsData.Reset() 或构造函数设定;建议在 GetData() 返回后立即进行校验与规范化。
    • 验证可在应用前Apply 前或保存前SaveAsync 前)执行,结合事件流进行拦截与回滚。

章节来源

SettingsSystem 应用系统

  • 职责与特性
    • 提供 ApplyAll/Apply/Apply(IEnumerable) 三种应用入口,自动去重与过滤非 IApplyAbleSettings。
    • 在应用前发送 SettingsApplyingEvent应用成功/失败分别发送 SettingsAppliedEvent含异常信息
  • 错误处理
    • 应用异常会通过事件上报并重新抛出,便于上层捕获与恢复。
  • 性能建议
    • 批量修改后一次性应用,减少事件风暴与重复应用开销。
sequenceDiagram
participant Caller as "调用方"
participant System as "SettingsSystem"
participant Model as "ISettingsModel"
participant Section as "IApplyAbleSettings"
participant Bus as "事件总线"
Caller->>System : "Apply<T>()"
System->>Model : "TryGet(type, out section)"
alt 找到 IApplyAbleSettings
System->>Bus : "发送 SettingsApplyingEvent"
System->>Section : "Apply()"
alt 成功
System->>Bus : "发送 SettingsAppliedEvent(true)"
else 失败
System->>Bus : "发送 SettingsAppliedEvent(false, ex)"
System-->>Caller : "抛出异常"
end
else 未找到
System-->>Caller : "忽略并返回"
end

图表来源

章节来源

SettingsPersistence 持久化策略

  • 存储键命名
    • 统一键格式Settings_{TypeName},避免冲突并便于调试。
  • 加载与保存
    • LoadAsync():若存在则读取,否则创建新实例;均触发 SettingsLoadedEvent。
    • SaveAsync():写入存储并触发 SettingsSavedEvent。
    • SaveAllAsync(IEnumerable):批量写入并触发 SettingsBatchSavedEvent。
    • LoadAllAsync(IEnumerable):按类型集合批量读取,触发 SettingsAllLoadedEvent。
  • 与事件系统联动
    • 读取、保存、删除、批量保存与全部加载均伴随事件,便于订阅者同步状态。
  • 与存储后端解耦
    • 通过 IStorage 抽象对接任意存储实现(文件、内存、加密存储等)。
flowchart TD
Start(["开始"]) --> Key["生成键名<br/>Settings_{TypeName}"]
Key --> Exists{"键存在?"}
Exists --> |是| Read["读取数据"]
Exists --> |否| New["创建新实例"]
Read --> Loaded["触发 SettingsLoadedEvent"]
New --> Loaded
Loaded --> Save{"保存?"}
Save --> |是| Write["写入存储"]
Write --> Saved["触发 SettingsSavedEvent"]
Save --> |否| End(["结束"])
Saved --> End

图表来源

章节来源

设置事件系统

  • 事件类型与触发时机
    • SettingsChangedEvent泛型设置变更事件携带变更时间与类型信息。
    • SettingsSavedEvent设置保存事件用于记录保存动作与时间戳。
    • SettingsAllLoadedEvent全部设置加载完成事件聚合所有已加载设置。
    • SettingsBatchChangedEvent批量设置变更事件用于批处理场景。
  • 事件用途
    • 订阅者可基于事件进行 UI 刷新、日志记录、统计上报或二次应用(如跨平台同步)。
  • 时序示意
sequenceDiagram
participant P as "SettingsPersistence"
participant M as "SettingsModel"
participant S as "SettingsSystem"
participant E as "事件总线"
P->>P : "LoadAsync<T>()"
alt 键存在
P->>M : "返回已存储实例"
P->>E : "触发 SettingsLoadedEvent<T>"
else 键不存在
P->>M : "创建新实例"
P->>E : "触发 SettingsLoadedEvent<T>"
end
P->>P : "SaveAsync<T>(section)"
P->>E : "触发 SettingsSavedEvent<T>"
S->>S : "Apply<T>()"
S->>E : "触发 SettingsApplyingEvent"
S->>E : "触发 SettingsAppliedEvent(成功/失败)"

图表来源

章节来源

接口设计与使用方法

  • ISettingsSection设置节标识接口承载具体配置项。
  • ISettingsModel提供类型安全的设置获取、注册与聚合查询。
  • ISettingsSystem提供设置应用的统一入口支持单个/批量/全部应用。
  • ISettingsPersistence提供异步加载/保存/删除/存在性检查与批量操作。
  • 使用要点
    • 先通过 ISettingsModel.GetData() 获取或创建设置实例,再进行赋值与校验。
    • 对需要应用到平台/引擎的设置,实现 IApplyAbleSettings 并通过 RegisterApplicator() 注册。
    • 使用 SettingsPersistence 进行持久化,注意键名唯一性与序列化兼容性。
    • 通过事件总线订阅相关事件,实现 UI/日志/同步等横切关注点。

章节来源

平台应用器示例Godot

  • GodotAudioSettings将 AudioSettings 映射到 Godot 音频总线支持主音量、BGM、SFX 分别设置。
  • GodotGraphicsSettings根据 GraphicsSettings 控制窗口模式、分辨率与全屏状态。
  • 设计要点
    • 应用器仅负责“如何应用”,不负责数据存储;数据由 ISettingsData 与 SettingsPersistence 管理。
    • 应用器应具备幂等性与边界检查(如音量范围、分辨率有效性)。

章节来源

依赖关系分析

  • 组件耦合
    • SettingsSystem 依赖 ISettingsModelSettingsModel 依赖 ISettingsSectionSettingsPersistence 依赖 IStorage。
    • 事件系统通过 SendEvent 与事件总线解耦,降低模块间直接依赖。
  • 外部依赖
    • IStorage 由上下文注入,允许替换为文件存储、内存存储或其他实现。
  • 循环依赖
    • 未发现循环依赖各方向依赖清晰System -> Model -> SectionPersistence -> Storage
graph LR
System["SettingsSystem"] --> Model["ISettingsModel"]
Model --> Section["ISettingsSection"]
Persist["SettingsPersistence"] --> Storage["IStorage"]
System --> Events["事件总线"]
Persist --> Events

图表来源

章节来源

性能考量

  • 批处理优于频繁小变更
    • 修改多处设置后统一调用 ApplyAll/Apply(types) 应用,减少事件风暴与平台调用次数。
  • 缓存与懒创建
    • SettingsModel 对 ISettingsData 使用字典缓存避免重复构造GetData() 为 O(1) 查找。
  • I/O 优化
    • SettingsPersistence 的 SaveAllAsync 与 LoadAllAsync 适合批量场景;单次 SaveAsync/LoadAsync 适合增量更新。
  • 事件风暴
    • 批量保存/加载时使用 SettingsBatchSavedEvent/SettingsAllLoadedEvent订阅者可选择批量刷新以提升 UI 性能。

故障排查指南

  • 应用失败
    • 现象SettingsAppliedEvent(false, ex)。
    • 排查:检查 IApplyAbleSettings.Apply() 内部异常来源(平台 API 参数、权限、资源状态)。
  • 未生效
    • 现象:设置已保存但未应用。
    • 排查:确认设置实现了 IApplyAbleSettings 并通过 RegisterApplicator() 注册;调用 ApplyAll/Apply()。
  • 无法加载
    • 现象LoadAsync() 返回默认值而非期望值。
    • 排查确认键名一致Settings_{TypeName})、序列化兼容、存储后端可用。
  • 事件未触发
    • 现象:订阅者未收到事件。
    • 排查确认事件总线可用、SendEvent 调用路径正确、订阅者生命周期匹配。

章节来源

结论

设置系统通过清晰的接口分层与事件驱动,提供了类型安全、可扩展、可测试的配置管理方案。配合平台应用器与持久化抽象,既满足默认值与验证需求,又兼顾性能与一致性。建议在实际工程中遵循“批量修改、延迟应用、事件聚合”的最佳实践,并通过 Reset() 与边界检查确保默认值与数据合法性。

附录

配置选项与约定

  • 键命名Settings_{TypeName}
  • 默认值:由 ISettingsData.Reset() 或构造函数提供
  • 序列化:由 IStorage 实现决定,建议保持向后兼容

API 参考(摘要)

  • ISettingsModel
    • GetData():获取或创建 ISettingsData 实例
    • RegisterApplicator():注册 IApplyAbleSettings
    • TryGet/All查询与聚合
  • ISettingsSystem
    • ApplyAll/Apply(Type)/Apply()(IEnumerable)
  • ISettingsPersistence
    • LoadAsync(), SaveAsync(), ExistsAsync(), DeleteAsync()
    • SaveAllAsync(IEnumerable), LoadAllAsync(IEnumerable)

章节来源