diff --git a/GFramework.Game.Tests/Config/GeneratedConfigConsumerIntegrationTests.cs b/GFramework.Game.Tests/Config/GeneratedConfigConsumerIntegrationTests.cs index a419c260..d9aee6da 100644 --- a/GFramework.Game.Tests/Config/GeneratedConfigConsumerIntegrationTests.cs +++ b/GFramework.Game.Tests/Config/GeneratedConfigConsumerIntegrationTests.cs @@ -91,9 +91,16 @@ public class GeneratedConfigConsumerIntegrationTests Assert.Multiple(() => { + Assert.That(MonsterConfigBindings.ConfigDomain, Is.EqualTo("monster")); Assert.That(MonsterConfigBindings.TableName, Is.EqualTo("monster")); Assert.That(MonsterConfigBindings.ConfigRelativePath, Is.EqualTo("monster")); Assert.That(MonsterConfigBindings.SchemaRelativePath, Is.EqualTo("schemas/monster.schema.json")); + Assert.That(MonsterConfigBindings.Metadata.ConfigDomain, Is.EqualTo(MonsterConfigBindings.ConfigDomain)); + Assert.That(MonsterConfigBindings.Metadata.TableName, Is.EqualTo(MonsterConfigBindings.TableName)); + Assert.That(MonsterConfigBindings.Metadata.ConfigRelativePath, + Is.EqualTo(MonsterConfigBindings.ConfigRelativePath)); + Assert.That(MonsterConfigBindings.Metadata.SchemaRelativePath, + Is.EqualTo(MonsterConfigBindings.SchemaRelativePath)); Assert.That(table.Count, Is.EqualTo(2)); Assert.That(table.Get(1).Name, Is.EqualTo("Slime")); Assert.That(table.Get(2).Hp, Is.EqualTo(30)); diff --git a/GFramework.SourceGenerators.Tests/Config/snapshots/SchemaConfigGenerator/MonsterConfigBindings.g.txt b/GFramework.SourceGenerators.Tests/Config/snapshots/SchemaConfigGenerator/MonsterConfigBindings.g.txt index a2954ce7..36c4dbcc 100644 --- a/GFramework.SourceGenerators.Tests/Config/snapshots/SchemaConfigGenerator/MonsterConfigBindings.g.txt +++ b/GFramework.SourceGenerators.Tests/Config/snapshots/SchemaConfigGenerator/MonsterConfigBindings.g.txt @@ -9,20 +9,51 @@ namespace GFramework.Game.Config.Generated; /// public static class MonsterConfigBindings { + /// + /// Groups the schema-derived metadata constants so consumer code can reuse one stable entry point. + /// + public static class Metadata + { + /// + /// Gets the logical config domain derived from the schema base name. The current runtime convention keeps this value aligned with the generated table name. + /// + public const string ConfigDomain = "monster"; + + /// + /// Gets the runtime registration name of the generated config table. + /// + public const string TableName = "monster"; + + /// + /// Gets the config directory path expected by the generated registration helper. + /// + public const string ConfigRelativePath = "monster"; + + /// + /// Gets the schema file path expected by the generated registration helper. + /// + public const string SchemaRelativePath = "schemas/monster.schema.json"; + } + + /// + /// Gets the logical config domain derived from the schema base name. The current runtime convention keeps this value aligned with the generated table name. + /// + public const string ConfigDomain = Metadata.ConfigDomain; + /// /// Gets the runtime registration name of the generated config table. /// - public const string TableName = "monster"; + public const string TableName = Metadata.TableName; /// /// Gets the config directory path expected by the generated registration helper. /// - public const string ConfigRelativePath = "monster"; + public const string ConfigRelativePath = Metadata.ConfigRelativePath; /// /// Gets the schema file path expected by the generated registration helper. /// - public const string SchemaRelativePath = "schemas/monster.schema.json"; + public const string SchemaRelativePath = Metadata.SchemaRelativePath; /// /// Registers the generated config table using the schema-derived runtime conventions. @@ -40,9 +71,9 @@ public static class MonsterConfigBindings } return loader.RegisterTable( - TableName, - ConfigRelativePath, - SchemaRelativePath, + Metadata.TableName, + Metadata.ConfigRelativePath, + Metadata.SchemaRelativePath, static config => config.Id, comparer); } @@ -60,7 +91,7 @@ public static class MonsterConfigBindings throw new global::System.ArgumentNullException(nameof(registry)); } - return new MonsterTable(registry.GetTable(TableName)); + return new MonsterTable(registry.GetTable(Metadata.TableName)); } /// @@ -77,7 +108,7 @@ public static class MonsterConfigBindings throw new global::System.ArgumentNullException(nameof(registry)); } - if (registry.TryGetTable(TableName, out var innerTable) && innerTable is not null) + if (registry.TryGetTable(Metadata.TableName, out var innerTable) && innerTable is not null) { table = new MonsterTable(innerTable); return true; diff --git a/GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs b/GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs index c0e5560d..96956f8b 100644 --- a/GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs +++ b/GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs @@ -650,22 +650,58 @@ public sealed class SchemaConfigGenerator : IIncrementalGenerator builder.AppendLine($"public static class {bindingsClassName}"); builder.AppendLine("{"); builder.AppendLine(" /// "); + builder.AppendLine( + " /// Groups the schema-derived metadata constants so consumer code can reuse one stable entry point."); + builder.AppendLine(" /// "); + builder.AppendLine(" public static class Metadata"); + builder.AppendLine(" {"); + builder.AppendLine(" /// "); + builder.AppendLine( + " /// Gets the logical config domain derived from the schema base name. The current runtime convention keeps this value aligned with the generated table name."); + builder.AppendLine(" /// "); + builder.AppendLine( + $" public const string ConfigDomain = {SymbolDisplay.FormatLiteral(schema.TableRegistrationName, true)};"); + builder.AppendLine(); + builder.AppendLine(" /// "); + builder.AppendLine(" /// Gets the runtime registration name of the generated config table."); + builder.AppendLine(" /// "); + builder.AppendLine( + $" public const string TableName = {SymbolDisplay.FormatLiteral(schema.TableRegistrationName, true)};"); + builder.AppendLine(); + builder.AppendLine(" /// "); + builder.AppendLine( + " /// Gets the config directory path expected by the generated registration helper."); + builder.AppendLine(" /// "); + builder.AppendLine( + $" public const string ConfigRelativePath = {SymbolDisplay.FormatLiteral(schema.ConfigRelativePath, true)};"); + builder.AppendLine(); + builder.AppendLine(" /// "); + builder.AppendLine(" /// Gets the schema file path expected by the generated registration helper."); + builder.AppendLine(" /// "); + builder.AppendLine( + $" public const string SchemaRelativePath = {SymbolDisplay.FormatLiteral(schema.SchemaRelativePath, true)};"); + builder.AppendLine(" }"); + builder.AppendLine(); + builder.AppendLine(" /// "); + builder.AppendLine( + " /// Gets the logical config domain derived from the schema base name. The current runtime convention keeps this value aligned with the generated table name."); + builder.AppendLine(" /// "); + builder.AppendLine(" public const string ConfigDomain = Metadata.ConfigDomain;"); + builder.AppendLine(); + builder.AppendLine(" /// "); builder.AppendLine(" /// Gets the runtime registration name of the generated config table."); builder.AppendLine(" /// "); - builder.AppendLine( - $" public const string TableName = {SymbolDisplay.FormatLiteral(schema.TableRegistrationName, true)};"); + builder.AppendLine(" public const string TableName = Metadata.TableName;"); builder.AppendLine(); builder.AppendLine(" /// "); builder.AppendLine(" /// Gets the config directory path expected by the generated registration helper."); builder.AppendLine(" /// "); - builder.AppendLine( - $" public const string ConfigRelativePath = {SymbolDisplay.FormatLiteral(schema.ConfigRelativePath, true)};"); + builder.AppendLine(" public const string ConfigRelativePath = Metadata.ConfigRelativePath;"); builder.AppendLine(); builder.AppendLine(" /// "); builder.AppendLine(" /// Gets the schema file path expected by the generated registration helper."); builder.AppendLine(" /// "); - builder.AppendLine( - $" public const string SchemaRelativePath = {SymbolDisplay.FormatLiteral(schema.SchemaRelativePath, true)};"); + builder.AppendLine(" public const string SchemaRelativePath = Metadata.SchemaRelativePath;"); builder.AppendLine(); builder.AppendLine(" /// "); builder.AppendLine( @@ -688,9 +724,9 @@ public sealed class SchemaConfigGenerator : IIncrementalGenerator builder.AppendLine(); builder.AppendLine( $" return loader.RegisterTable<{schema.KeyClrType}, {schema.ClassName}>("); - builder.AppendLine(" TableName,"); - builder.AppendLine(" ConfigRelativePath,"); - builder.AppendLine(" SchemaRelativePath,"); + builder.AppendLine(" Metadata.TableName,"); + builder.AppendLine(" Metadata.ConfigRelativePath,"); + builder.AppendLine(" Metadata.SchemaRelativePath,"); builder.AppendLine($" static config => config.{schema.KeyPropertyName},"); builder.AppendLine(" comparer);"); builder.AppendLine(" }"); @@ -711,7 +747,7 @@ public sealed class SchemaConfigGenerator : IIncrementalGenerator builder.AppendLine(" }"); builder.AppendLine(); builder.AppendLine( - $" return new {schema.TableName}(registry.GetTable<{schema.KeyClrType}, {schema.ClassName}>(TableName));"); + $" return new {schema.TableName}(registry.GetTable<{schema.KeyClrType}, {schema.ClassName}>(Metadata.TableName));"); builder.AppendLine(" }"); builder.AppendLine(); builder.AppendLine(" /// "); @@ -733,7 +769,7 @@ public sealed class SchemaConfigGenerator : IIncrementalGenerator builder.AppendLine(" }"); builder.AppendLine(); builder.AppendLine( - $" if (registry.TryGetTable<{schema.KeyClrType}, {schema.ClassName}>(TableName, out var innerTable) && innerTable is not null)"); + $" if (registry.TryGetTable<{schema.KeyClrType}, {schema.ClassName}>(Metadata.TableName, out var innerTable) && innerTable is not null)"); builder.AppendLine(" {"); builder.AppendLine($" table = new {schema.TableName}(innerTable);"); builder.AppendLine(" return true;"); diff --git a/docs/zh-CN/game/config-system.md b/docs/zh-CN/game/config-system.md index 03331442..163cbca4 100644 --- a/docs/zh-CN/game/config-system.md +++ b/docs/zh-CN/game/config-system.md @@ -103,11 +103,21 @@ var slime = monsterTable.Get(1); 这组辅助会把以下约定固化到生成代码里: +- 配置域常量,例如 `MonsterConfigBindings.ConfigDomain` - 表注册名,例如 `monster` - 配置目录相对路径,例如 `monster` - schema 相对路径,例如 `schemas/monster.schema.json` - 主键提取逻辑,例如 `config => config.Id` +如果你希望把这些约定作为一个统一入口传递或复用,也可以优先读取 `MonsterConfigBindings.Metadata` 下的常量: + +```csharp +var domain = MonsterConfigBindings.Metadata.ConfigDomain; +var tableName = MonsterConfigBindings.Metadata.TableName; +var configPath = MonsterConfigBindings.Metadata.ConfigRelativePath; +var schemaPath = MonsterConfigBindings.Metadata.SchemaRelativePath; +``` + 如果你需要自定义目录、表名或 key selector,仍然可以直接调用 `YamlConfigLoader.RegisterTable(...)` 原始重载。 ## 运行时校验行为