From 7da35c00b268aa81234c9b65f782bd8ea6da42dd Mon Sep 17 00:00:00 2001 From: GeWuYou <95328647+GeWuYou@users.noreply.github.com> Date: Mon, 6 Apr 2026 07:53:46 +0800 Subject: [PATCH] =?UTF-8?q?feat(config):=20=E6=B7=BB=E5=8A=A0=E5=9F=BA?= =?UTF-8?q?=E4=BA=8E=E6=96=87=E4=BB=B6=E7=9B=AE=E5=BD=95=E7=9A=84YAML?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E5=8A=A0=E8=BD=BD=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 实现YamlConfigLoader类,支持从文件目录加载YAML配置 - 提供RegisterTable方法注册配置表定义,支持schema校验 - 添加LoadAsync异步加载功能,支持批量加载配置表 - 实现EnableHotReload方法,支持开发期配置热重载 - 添加跨表引用校验功能,确保配置依赖关系正确性 - 支持YAML文件和YML文件格式,自动识别文件扩展名 - 提供配置表主键提取器和比较器自定义功能 - 实现文件变更监听和防抖机制,避免频繁重载 - 支持配置目录和schema文件路径的灵活配置 - 提供详细的加载异常信息和诊断支持 --- .../Config/YamlConfigLoaderTests.cs | 20 +++++++++++ GFramework.Game/Config/YamlConfigLoader.cs | 13 ++++++++ .../Config/SchemaConfigGeneratorTests.cs | 33 +++++++++++-------- 3 files changed, 52 insertions(+), 14 deletions(-) diff --git a/GFramework.Game.Tests/Config/YamlConfigLoaderTests.cs b/GFramework.Game.Tests/Config/YamlConfigLoaderTests.cs index f2045ad3..86f01098 100644 --- a/GFramework.Game.Tests/Config/YamlConfigLoaderTests.cs +++ b/GFramework.Game.Tests/Config/YamlConfigLoaderTests.cs @@ -1133,6 +1133,26 @@ public class YamlConfigLoaderTests } } + /// + /// 验证热重载会在启动前拒绝负的防抖延迟,避免后台延迟任务才暴露参数错误。 + /// + [Test] + public void EnableHotReload_Should_Throw_When_Debounce_Delay_Is_Negative() + { + var loader = new YamlConfigLoader(_rootPath); + var registry = new ConfigRegistry(); + + var exception = Assert.Throws(() => + loader.EnableHotReload( + registry, + new YamlConfigHotReloadOptions + { + DebounceDelay = TimeSpan.FromMilliseconds(-1) + })); + + Assert.That(exception!.ParamName, Is.EqualTo("options")); + } + /// /// 验证热重载失败时会保留旧表状态,并通过失败回调暴露诊断信息。 /// diff --git a/GFramework.Game/Config/YamlConfigLoader.cs b/GFramework.Game/Config/YamlConfigLoader.cs index 491505fd..012caa32 100644 --- a/GFramework.Game/Config/YamlConfigLoader.cs +++ b/GFramework.Game/Config/YamlConfigLoader.cs @@ -97,6 +97,9 @@ public sealed class YamlConfigLoader : IConfigLoader /// 防抖延迟;为空时默认使用 200 毫秒。 /// 用于停止热重载监听的注销句柄。 /// 为空时抛出。 + /// + /// 当显式提供的 小于 时抛出。 + /// public IUnRegister EnableHotReload( IConfigRegistry registry, Action? onTableReloaded = null, @@ -122,12 +125,22 @@ public sealed class YamlConfigLoader : IConfigLoader /// 热重载配置选项;为空时使用默认选项。 /// 用于停止热重载监听的注销句柄。 /// 为空时抛出。 + /// + /// 当 小于 + /// 时抛出。 + /// public IUnRegister EnableHotReload( IConfigRegistry registry, YamlConfigHotReloadOptions? options) { ArgumentNullException.ThrowIfNull(registry); options ??= new YamlConfigHotReloadOptions(); + if (options.DebounceDelay < TimeSpan.Zero) + { + throw new ArgumentOutOfRangeException( + nameof(options), + "DebounceDelay must be greater than or equal to zero."); + } return new HotReloadSession( _rootPath, diff --git a/GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.cs b/GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.cs index 9c777f4c..07b3b81c 100644 --- a/GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.cs +++ b/GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.cs @@ -95,8 +95,13 @@ public class SchemaConfigGeneratorTests /// /// 验证 schema 字段名无法映射为合法 C# 标识符时会直接给出诊断,而不是生成不可编译代码。 /// - [Test] - public void Run_Should_Report_Diagnostic_When_Schema_Key_Maps_To_Invalid_CSharp_Identifier() + /// 会映射为非法 C# 标识符的 schema key。 + /// 当前命名规范化逻辑生成出的非法标识符。 + [TestCase("drop$item", "Drop$item")] + [TestCase("1-phase", "1Phase")] + public void Run_Should_Report_Diagnostic_When_Schema_Key_Maps_To_Invalid_CSharp_Identifier( + string schemaKey, + string generatedIdentifier) { const string source = """ namespace TestApp @@ -107,16 +112,16 @@ public class SchemaConfigGeneratorTests } """; - const string schema = """ - { - "type": "object", - "required": ["id", "drop$item"], - "properties": { - "id": { "type": "integer" }, - "drop$item": { "type": "string" } - } - } - """; + var schema = $$""" + { + "type": "object", + "required": ["id", "{{schemaKey}}"], + "properties": { + "id": { "type": "integer" }, + "{{schemaKey}}": { "type": "string" } + } + } + """; var result = SchemaGeneratorTestDriver.Run( source, @@ -128,8 +133,8 @@ public class SchemaConfigGeneratorTests { Assert.That(diagnostic.Id, Is.EqualTo("GF_ConfigSchema_006")); Assert.That(diagnostic.Severity, Is.EqualTo(DiagnosticSeverity.Error)); - Assert.That(diagnostic.GetMessage(), Does.Contain("drop$item")); - Assert.That(diagnostic.GetMessage(), Does.Contain("Drop$item")); + Assert.That(diagnostic.GetMessage(), Does.Contain(schemaKey)); + Assert.That(diagnostic.GetMessage(), Does.Contain(generatedIdentifier)); }); }