diff --git a/docs/zh-CN/api-reference/index.md b/docs/zh-CN/api-reference/index.md index 18b3ec3c..b491cc5a 100644 --- a/docs/zh-CN/api-reference/index.md +++ b/docs/zh-CN/api-reference/index.md @@ -440,11 +440,28 @@ Godot 引擎集成模块。 #### 支持的生成器 -| 生成器 | 说明 | -|--------------------|---------| -| `LoggingGenerator` | 日志生成器 | -| `EnumGenerator` | 枚举扩展生成器 | -| `RuleGenerator` | 规则生成器 | +| 生成器 | 说明 | +|--------------------------------------------|-------------| +| `LoggingGenerator` | 日志生成器 | +| `EnumGenerator` | 枚举扩展生成器 | +| `RuleGenerator` | 规则生成器 | +| `AutoRegisterModuleGenerator` | 架构模块注册生成器 | +| `AutoUiPageGenerator` | UI 页面行为生成器 | +| `AutoSceneGenerator` | 场景行为生成器 | +| `AutoRegisterExportedCollectionsGenerator` | 导出集合批量注册生成器 | + +#### 常用 Attribute + +| Attribute | 说明 | 文档 | +|--------------------------------------------|-----------------------------------|-------------------------------------------------------------------------------------------------------------| +| `AutoRegisterModuleAttribute` | 为模块类生成 `Install(IArchitecture)` | [AutoRegisterModule 生成器](../source-generators/auto-register-module-generator.md) | +| `RegisterModelAttribute` | 声明模块内自动注册的 `IModel` 类型 | [AutoRegisterModule 生成器](../source-generators/auto-register-module-generator.md) | +| `RegisterSystemAttribute` | 声明模块内自动注册的 `ISystem` 类型 | [AutoRegisterModule 生成器](../source-generators/auto-register-module-generator.md) | +| `RegisterUtilityAttribute` | 声明模块内自动注册的 `IUtility` 类型 | [AutoRegisterModule 生成器](../source-generators/auto-register-module-generator.md) | +| `AutoUiPageAttribute` | 为 `CanvasItem` 页面节点生成 `GetPage()` | [AutoUiPage 生成器](../source-generators/auto-ui-page-generator.md) | +| `AutoSceneAttribute` | 为场景根节点生成 `GetScene()` | [AutoScene 生成器](../source-generators/auto-scene-generator.md) | +| `AutoRegisterExportedCollectionsAttribute` | 为宿主类开启导出集合批量注册生成 | [AutoRegisterExportedCollections 生成器](../source-generators/auto-register-exported-collections-generator.md) | +| `RegisterExportedCollectionAttribute` | 指定集合与注册器成员的映射关系 | [AutoRegisterExportedCollections 生成器](../source-generators/auto-register-exported-collections-generator.md) | ## 常见用法示例 diff --git a/docs/zh-CN/source-generators/auto-register-exported-collections-generator.md b/docs/zh-CN/source-generators/auto-register-exported-collections-generator.md new file mode 100644 index 00000000..2d73f531 --- /dev/null +++ b/docs/zh-CN/source-generators/auto-register-exported-collections-generator.md @@ -0,0 +1,174 @@ +# AutoRegisterExportedCollections 生成器 + +> 为 Godot 导出集合生成批量注册方法,收敛启动入口里的重复 `foreach + Registry(...)` 样板。 + +## 概述 + +在游戏启动入口中,常见的一类样板是: + +- 在 Inspector 中导出一批配置、资源映射或预制体条目 +- 从某个 Registry 成员拿到注册器 +- 遍历集合逐项调用 `Register(...)` / `Registry(...)` + +`AutoRegisterExportedCollections` 会把这类样板收敛成声明式配置。 + +它特别适合 `GameEntryPoint`、资源根节点、配置引导节点这类“导出即注册”的场景。 + +## 基础使用 + +```csharp +using System.Collections.Generic; +using GFramework.Godot.SourceGenerators.Abstractions; +using Godot; + +public interface IKeyValue +{ +} + +public interface IRegistry +{ + void Registry(IKeyValue mapping); +} + +public interface IAssetRegistry : IRegistry +{ +} + +public sealed class TextureConfig : Resource, IKeyValue +{ +} + +public sealed class TextureRegistry : IAssetRegistry +{ + public void Registry(IKeyValue mapping) + { + } +} + +[AutoRegisterExportedCollections] +public partial class GameEntryPoint : Node +{ + private IAssetRegistry? _textureRegistry; + + [Export] + [RegisterExportedCollection(nameof(_textureRegistry), nameof(IRegistry.Registry))] + private Godot.Collections.Array? _textureConfigs; + + public override void _Ready() + { + _textureRegistry ??= new TextureRegistry(); + __RegisterExportedCollections_Generated(); + } +} +``` + +为了让示例具备完整的调用路径,这里在 `_Ready()` 里先初始化了 `_textureRegistry`。 +实际项目里,这个字段通常来自架构容器、服务定位或外部注入;关键点是调用 `__RegisterExportedCollections_Generated()` +之前,注册器成员必须已经可用,否则生成代码会按设计静默跳过注册。 + +## 生成的代码 + +```csharp +// +#nullable enable + +partial class GameEntryPoint +{ + private void __RegisterExportedCollections_Generated() + { + if (this._textureConfigs is not null && this._textureRegistry is not null) + { + foreach (var __generatedItem in this._textureConfigs) + { + this._textureRegistry.Registry(__generatedItem); + } + } + } +} +``` + +## 参数说明 + +### `[AutoRegisterExportedCollections]` + +类级标记,声明该类型允许生成 `__RegisterExportedCollections_Generated()`。 + +### `[RegisterExportedCollection(registryMemberName, registerMethodName)]` + +| 参数 | 类型 | 说明 | +|----------------------|----------|----------------------------------| +| `registryMemberName` | `string` | 当前类型上用于执行注册的字段或属性名 | +| `registerMethodName` | `string` | 注册方法名,例如 `Register` 或 `Registry` | + +推荐优先使用 `nameof(...)` 表达式,而不是手写字符串。 + +## 支持的匹配规则 + +生成器会在编译期验证: + +- 集合成员必须是实例字段,或可读的实例属性 +- 集合类型必须可枚举 +- 集合元素类型必须能在编译期推导 +- 注册器成员必须是实例字段,或可读的实例属性 +- 注册方法必须是单参数实例方法,且参数类型能接收集合元素类型 + +当前版本还支持从以下位置解析注册方法: + +- 注册器具体类型本身 +- 注册器基类 +- 注册器实现的接口 +- 继承链上的接口 + +这意味着像 `IAssetRegistry` 继承 `IRegistry` 的项目结构也能正常生成,不必再把注册器字段改成具体实现类型。 + +## 适用场景 + +推荐用于: + +- `GameEntryPoint` 中的资源注册 +- 场景启动时的配置条目注册 +- Inspector 预配置的纹理、音频、Prefab、场景映射批量接入 + +不推荐用于: + +- 注册前需要复杂过滤、去重、排序、条件判断的集合 +- 需要记录失败项、错误聚合或回滚逻辑的批量导入 +- 每个元素注册时都依赖额外上下文或副作用控制的流程 + +## 使用约束 + +- 目标类型必须是 `partial class` +- 不支持嵌套类 +- 生成器不会自动调用 `__RegisterExportedCollections_Generated()` +- 非泛型 `IEnumerable` 之类无法推导元素类型的集合不受支持 +- 注册方法必须对宿主类型可访问 + +## 诊断信息 + +| 诊断 ID | 含义 | +|-----------------------|-------------------------------------------------------------| +| `GF_Common_Class_001` | 目标类型不是 `partial`,生成被跳过 | +| `GF_Common_Class_002` | 宿主类型已声明 `__RegisterExportedCollections_Generated()`,与生成代码冲突 | +| `GF_AutoExport_001` | `AutoRegisterExportedCollections` 不支持嵌套类 | +| `GF_AutoExport_002` | 指定的注册器成员不存在 | +| `GF_AutoExport_003` | 注册器成员上找不到兼容的注册方法 | +| `GF_AutoExport_004` | 被标记的成员不是可枚举集合 | +| `GF_AutoExport_005` | 无法推导集合元素类型 | +| `GF_AutoExport_006` | 集合成员不是实例可读成员 | +| `GF_AutoExport_007` | 注册器成员不是实例可读成员 | +| `GF_AutoExport_008` | `RegisterExportedCollectionAttribute` 参数无效 | + +## 调用时机建议 + +推荐在以下时机之一调用生成方法: + +- `_Ready()` 中,且在注册器字段已经准备好之后 +- 启动入口的显式 `Initialize()` 或 `Bootstrap()` 方法中 +- 测试中的装配阶段 + +不要在构造函数中调用,因为此时 Godot 导出字段和外部依赖通常还未准备完毕。 + +## 相关文档 + +- [源码生成器总览](./index) +- [游戏内容配置系统](/zh-CN/game/config-system) diff --git a/docs/zh-CN/source-generators/auto-register-module-generator.md b/docs/zh-CN/source-generators/auto-register-module-generator.md new file mode 100644 index 00000000..241e6ed2 --- /dev/null +++ b/docs/zh-CN/source-generators/auto-register-module-generator.md @@ -0,0 +1,153 @@ +# AutoRegisterModule 生成器 + +> 为架构模块生成固定顺序的组件注册代码,收敛 `Install(IArchitecture)` 样板。 + +## 概述 + +`AutoRegisterModule` 面向 GFramework 的模块安装场景。 +当一个模块类只需要按固定顺序注册若干 `Model`、`System`、`Utility` 时,开发者不必再手写重复的 `Install(IArchitecture)` 方法。 + +生成器会扫描类上的: + +- `[AutoRegisterModule]` +- `[RegisterModel(typeof(...))]` +- `[RegisterSystem(typeof(...))]` +- `[RegisterUtility(typeof(...))]` + +然后在编译期生成统一的安装方法。 + +### 核心收益 + +- 把模块注册入口收敛到声明式 Attribute +- 避免漏注册、顺序漂移和重复样板 +- 保持零运行时反射开销 + +## 基础使用 + +```csharp +using GFramework.Core.Abstractions.Architectures; +using GFramework.Core.Abstractions.Model; +using GFramework.Core.Abstractions.Systems; +using GFramework.Core.Abstractions.Utility; +using GFramework.SourceGenerators.Abstractions.Architectures; + +public sealed class RunStateModel : IModel +{ +} + +public sealed class BuildSystem : ISystem +{ +} + +public sealed class GridPathUtility : IUtility +{ +} + +[AutoRegisterModule] +[RegisterModel(typeof(RunStateModel))] +[RegisterSystem(typeof(BuildSystem))] +[RegisterUtility(typeof(GridPathUtility))] +public partial class GameplayModule +{ +} +``` + +## 生成的代码 + +编译器会生成与下述结构等价的代码: + +```csharp +// +#nullable enable + +partial class GameplayModule +{ + public void Install(global::GFramework.Core.Abstractions.Architectures.IArchitecture architecture) + { + architecture.RegisterModel(new global::RunStateModel()); + architecture.RegisterSystem(new global::BuildSystem()); + architecture.RegisterUtility(new global::GridPathUtility()); + } +} +``` + +## 参数说明 + +### `[AutoRegisterModule]` + +类级标记,用于声明该类型允许生成 `Install(IArchitecture)`。 + +### `[RegisterModel(typeof(TModel))]` + +| 参数 | 类型 | 说明 | +|-------------|--------|--------------------| +| `modelType` | `Type` | 要注册的 `IModel` 实现类型 | + +### `[RegisterSystem(typeof(TSystem))]` + +| 参数 | 类型 | 说明 | +|--------------|--------|---------------------| +| `systemType` | `Type` | 要注册的 `ISystem` 实现类型 | + +### `[RegisterUtility(typeof(TUtility))]` + +| 参数 | 类型 | 说明 | +|---------------|--------|----------------------| +| `utilityType` | `Type` | 要注册的 `IUtility` 实现类型 | + +## 顺序规则 + +生成器会按 Attribute 的稳定声明顺序输出注册语句。 + +- 同一个 `partial` 声明内:按源码书写顺序生成 +- 多个 `partial` 文件之间:按语法树稳定顺序合并 + +这意味着模块安装顺序是可预期的,适合游戏启动时需要确定初始化顺序的场景。 + +## 适用场景 + +推荐用于: + +- 游戏主架构中的固定模块安装 +- 菜单模块、战斗模块、局内模块等声明式注册 +- 仅依赖无参构造即可完成初始化的组件 + +不推荐用于: + +- 需要运行时参数、配置对象或工厂参与构造的组件 +- 注册前必须执行复杂前置逻辑的模块 +- 注册逻辑本身存在分支、条件或环境判断的模块 + +## 使用约束 + +- 目标类型必须是 `partial class` +- 不支持嵌套类 +- 目标类型上不能自己再声明 `Install(IArchitecture)` +- 注册类型必须是具体类型,不能是抽象类或接口 +- 注册类型必须实现对应接口: + - `RegisterModel` 对应 `IModel` + - `RegisterSystem` 对应 `ISystem` + - `RegisterUtility` 对应 `IUtility` +- 注册类型必须存在可访问的无参构造函数 + +## 诊断信息 + +| 诊断 ID | 含义 | +|-----------------------|------------------------------------------| +| `GF_Common_Class_001` | 目标类型不是 `partial`,生成被跳过 | +| `GF_AutoModule_001` | `AutoRegisterModule` 不支持嵌套类 | +| `GF_AutoModule_002` | 注册特性没有提供有效的具体类型参数 | +| `GF_AutoModule_003` | 注册类型没有实现要求的接口 | +| `GF_AutoModule_004` | 注册类型缺少可访问的无参构造 | +| `GF_AutoModule_005` | 宿主类型已声明 `Install(IArchitecture)`,与生成代码冲突 | + +## 注意事项 + +- 生成器只负责生成安装方法,不会自动调用它;模块仍需由你的架构启动逻辑显式执行。 +- 如果某个组件需要通过 Service、配置表或 Godot 导出字段来完成构造,优先保留手写注册代码。 +- 当注册逻辑已经包含较强的业务语义时,不要为了消灭几行代码而强行改成声明式生成。 + +## 相关文档 + +- [源码生成器总览](./index) +- [Context Get 注入生成器](./context-get-generator) diff --git a/docs/zh-CN/source-generators/auto-scene-generator.md b/docs/zh-CN/source-generators/auto-scene-generator.md new file mode 100644 index 00000000..1a2ff881 --- /dev/null +++ b/docs/zh-CN/source-generators/auto-scene-generator.md @@ -0,0 +1,119 @@ +# AutoScene 生成器 + +> 为场景根节点生成 `GetScene()` 样板,统一场景键声明与行为包装。 + +## 概述 + +`AutoScene` 面向 GFramework 的场景路由与场景行为包装场景。 +对于一个可切换、可识别的场景根节点,开发者通常需要重复声明: + +- 场景 Key +- 场景行为缓存字段 +- `GetScene()` 包装方法 + +`AutoScene` 会在编译期生成这些固定样板。 + +## 基础使用 + +```csharp +using GFramework.Godot.SourceGenerators.Abstractions; +using GFramework.Game.Abstractions.Enums; +using Godot; + +[AutoScene(nameof(SceneKey.Gameplay))] +public partial class GameplayRoot : Node2D +{ + public override void _Ready() + { + _ = GetScene(); + } +} +``` + +## 生成的代码 + +```csharp +// +#nullable enable + +partial class GameplayRoot +{ + private global::GFramework.Game.Abstractions.Scene.ISceneBehavior? __autoSceneBehavior_Generated; + + public static string SceneKeyStr => "Gameplay"; + + public global::GFramework.Game.Abstractions.Scene.ISceneBehavior GetScene() + { + return __autoSceneBehavior_Generated + ??= global::GFramework.Godot.Scene.SceneBehaviorFactory.Create(this, SceneKeyStr); + } +} +``` + +## 参数说明 + +`[AutoScene]` 只接收一个字符串参数: + +| 参数 | 类型 | 说明 | +|-------|----------|------------------------| +| `key` | `string` | 场景 Key,例如 `"Gameplay"` | + +推荐使用 `nameof(SceneKey.Gameplay)` 而不是裸字符串。 + +## 适用场景 + +推荐用于: + +- 主玩法根场景 +- 主菜单根场景 +- 局内关卡根节点 +- 使用 GFramework 场景路由管理的切换目标 + +不推荐用于: + +- 普通子节点或容器节点 +- 只会被父节点内部消费、没有独立场景语义的脚本 +- 行为创建需要额外动态参数的场景包装 + +## 使用约束 + +- 目标类型必须是 `partial class` +- 不支持嵌套类 +- 目标类型必须继承 `Godot.Node` +- 不要自行声明 `GetScene()` +- 不要自行声明同名保留成员,例如 `SceneKeyStr` + +## 生命周期边界 + +`AutoScene` 不会自动改写或生成: + +- `_Ready()` +- `_EnterTree()` +- `_ExitTree()` +- 场景切换调用链 + +它只负责提供稳定的场景行为访问入口。何时调用 `GetScene()`,仍由你的节点生命周期和场景系统决定。 + +## 诊断信息 + +| 诊断 ID | 含义 | +|-----------------------|-------------------------------------| +| `GF_Common_Class_001` | 目标类型不是 `partial`,生成被跳过 | +| `GF_Common_Class_002` | 宿主类型已声明 `GetScene()` 或保留成员名,和生成代码冲突 | +| `GF_AutoBehavior_001` | `AutoScene` 不支持嵌套类 | +| `GF_AutoBehavior_002` | 目标类型没有继承 `Godot.Node` | +| `GF_AutoBehavior_004` | `AutoSceneAttribute` 参数数量或类型不符合要求 | + +如果你自己声明了 `SceneKeyStr`、`__autoSceneBehavior_Generated` 或 `GetScene()`,编译阶段还会出现成员冲突错误或对应的冲突诊断。 + +## 与页面生成器的区别 + +- `AutoUiPage` 生成的是 `IUiPageBehavior` 与 `UiLayer` +- `AutoScene` 生成的是 `ISceneBehavior` 与场景 Key + +一个类型通常只应承担一种路由语义。不要把纯页面节点和纯场景根节点混为一体。 + +## 相关文档 + +- [源码生成器总览](./index) +- [AutoUiPage 生成器](./auto-ui-page-generator) diff --git a/docs/zh-CN/source-generators/auto-ui-page-generator.md b/docs/zh-CN/source-generators/auto-ui-page-generator.md new file mode 100644 index 00000000..b455eab8 --- /dev/null +++ b/docs/zh-CN/source-generators/auto-ui-page-generator.md @@ -0,0 +1,153 @@ +# AutoUiPage 生成器 + +> 为 Godot UI 页面生成 `GetPage()` 样板,统一页面键与层级声明。 + +## 概述 + +`AutoUiPage` 面向 GFramework 的 UI 路由场景。 +当一个 Godot `CanvasItem` 节点本质上就是一个页面时,开发者通常要重复声明: + +- 页面 Key +- 页面所在 `UiLayer` +- `IUiPageBehavior` 缓存字段 +- `GetPage()` 工厂包装 + +`AutoUiPage` 会把这部分样板迁移到编译期生成。 + +## 基础使用 + +```csharp +using GFramework.Godot.SourceGenerators.Abstractions; +using GFramework.Game.Abstractions.Enums; +using Godot; + +[AutoUiPage(nameof(UiKey.MainMenu), nameof(UiLayer.Page))] +public partial class MainMenu : Control +{ + public override void _Ready() + { + _ = GetPage(); + } +} +``` + +上面的 `nameof(UiKey.MainMenu)` 会生成字符串常量 `UiKeyStr`,`nameof(UiLayer.Page)` 则会在生成代码中解析为对应的枚举成员 +`UiLayer.Page`,并传入页面行为工厂。 + +## 生成的代码 + +```csharp +// +#nullable enable + +partial class MainMenu +{ + private global::GFramework.Game.Abstractions.UI.IUiPageBehavior? __autoUiPageBehavior_Generated; + + public static string UiKeyStr => "MainMenu"; + + public global::GFramework.Game.Abstractions.UI.IUiPageBehavior GetPage() + { + return __autoUiPageBehavior_Generated + ??= global::GFramework.Godot.UI.UiPageBehaviorFactory.Create( + this, + UiKeyStr, + global::GFramework.Game.Abstractions.Enums.UiLayer.Page); + } +} +``` + +## 参数说明 + +`[AutoUiPage]` 需要两个字符串参数: + +| 参数 | 类型 | 说明 | +|-------------|----------|-----------------------------| +| `key` | `string` | 页面 Key,例如 `"MainMenu"` | +| `layerName` | `string` | `UiLayer` 枚举成员名,例如 `"Page"` | + +推荐写法: + +```csharp +[AutoUiPage(nameof(UiKey.Inventory), nameof(UiLayer.Overlay))] +``` + +这样可以避免硬编码字符串拼写错误。 + +## 适用场景 + +推荐用于: + +- 主菜单、设置页、背包页、弹窗根节点 +- Godot 场景中已经明确是“一个页面”的 `Control` / `CanvasLayer` / `Panel` +- 只需要标准页面行为包装,而不需要自定义复杂工厂逻辑的页面 + +不推荐用于: + +- 临时子控件、列表项、纯视觉碎片节点 +- 页面行为创建前必须注入额外上下文参数的节点 +- 还未接入 GFramework UI 路由体系的老页面 + +## 使用约束 + +- 目标类型必须是 `partial class` +- 不支持嵌套类 +- 目标类型必须继承 `Godot.CanvasItem` +- `layerName` 必须对应 `GFramework.Game.Abstractions.Enums.UiLayer` 上的有效成员名 +- 不要自行声明同名 `GetPage()` 方法 + +## 生命周期边界 + +`AutoUiPage` 只生成页面行为样板,不会自动织入 Godot 生命周期。 + +它不会替你生成或调用: + +- `_Ready()` +- `_ExitTree()` +- 页面打开关闭回调 +- 节点注入或上下文注入 + +如果页面同时使用了 `[GetNode]`、`[BindNodeSignal]`、`[GetAll]` 等特性,仍然需要在你自己的生命周期方法中显式调用对应的生成方法。 + +## 诊断信息 + +| 诊断 ID | 含义 | +|-----------------------|------------------------------------| +| `GF_Common_Class_001` | 目标类型不是 `partial`,生成被跳过 | +| `GF_Common_Class_002` | 宿主类型已声明 `GetPage()`,与生成代码冲突 | +| `GF_AutoBehavior_001` | `AutoUiPage` 不支持嵌套类 | +| `GF_AutoBehavior_002` | 目标类型没有继承 `Godot.CanvasItem` | +| `GF_AutoBehavior_003` | 提供的 `UiLayer` 名称无效 | +| `GF_AutoBehavior_004` | `AutoUiPageAttribute` 参数数量或类型不符合要求 | + +## 组合示例 + +```csharp +using GFramework.Godot.SourceGenerators.Abstractions; +using GFramework.Game.Abstractions.Enums; +using GFramework.SourceGenerators.Abstractions.Rule; +using Godot; + +[ContextAware] +[GetAll] +[AutoUiPage(nameof(UiKey.PauseMenu), nameof(UiLayer.Modal))] +public partial class PauseMenu : Control +{ + [GetNode] + private Button _resumeButton = null!; + + public override void _Ready() + { + __InjectGetNodes_Generated(); + __InjectContextBindings_Generated(); + + _ = GetPage(); + } +} +``` + +## 相关文档 + +- [源码生成器总览](./index) +- [GetNode 生成器](./get-node-generator) +- [BindNodeSignal 生成器](./bind-node-signal-generator) diff --git a/docs/zh-CN/source-generators/index.md b/docs/zh-CN/source-generators/index.md index 148de911..60aada08 100644 --- a/docs/zh-CN/source-generators/index.md +++ b/docs/zh-CN/source-generators/index.md @@ -15,8 +15,12 @@ GFramework.SourceGenerators 是 GFramework 框架的源代码生成器包,通 - [GenerateEnumExtensions 属性生成器](#generateenumextensions-属性生成器) - [Priority 属性生成器](#priority-属性生成器) - [Context Get 注入生成器](#context-get-注入生成器) +- [AutoRegisterModule 生成器](#autoregistermodule-生成器) - [GetNode 生成器 (Godot)](#getnode-生成器) - [BindNodeSignal 生成器 (Godot)](#bindnodesignal-生成器) +- [AutoUiPage 生成器 (Godot)](#autouipage-生成器) +- [AutoScene 生成器 (Godot)](#autoscene-生成器) +- [AutoRegisterExportedCollections 生成器 (Godot)](#autoregisterexportedcollections-生成器) - [诊断信息](#诊断信息) - [性能优势](#性能优势) - [使用示例](#使用示例) @@ -44,11 +48,15 @@ GFramework.SourceGenerators 利用 Roslyn 源代码生成器技术,在编译 - **[GenerateEnumExtensions] 属性**:自动生成枚举扩展方法 - **[Priority] 属性**:自动实现 IPrioritized 接口,为类添加优先级标记 - **Context Get 注入特性**:自动注入架构组件(GetModel/GetSystem/GetUtility/GetService/GetAll) +- **[AutoRegisterModule] 属性**:为模块类自动生成固定顺序的 `Install(IArchitecture)` 注册代码 ### Godot 专用生成器 - **[GetNode] 属性 (Godot)**:自动获取 Godot 节点引用,支持多种查找模式 - **[BindNodeSignal] 属性 (Godot)**:自动生成 Godot 节点信号绑定与解绑逻辑 +- **[AutoUiPage] 属性 (Godot)**:自动生成 UI 页面行为包装与页面 Key +- **[AutoScene] 属性 (Godot)**:自动生成场景行为包装与场景 Key +- **[AutoRegisterExportedCollections] 属性 (Godot)**:自动生成导出集合的批量注册方法 ### 🔧 高级特性 @@ -462,6 +470,32 @@ public partial class PlayerHud : Control **完整文档**:[GetNode 生成器](./get-node-generator) +## AutoRegisterModule 生成器 + +AutoRegisterModule 生成器面向 GFramework 模块安装场景,为类上的注册声明自动生成 `Install(IArchitecture)`。 + +### 主要功能 + +- **声明式模块注册**:用 Attribute 声明 `Model` / `System` / `Utility` +- **稳定顺序输出**:按 Attribute 书写顺序生成注册代码 +- **零反射开销**:编译期生成 `new T()` 与 `architecture.RegisterXxx(...)` + +### 基础示例 + +```csharp +using GFramework.SourceGenerators.Abstractions.Architectures; + +[AutoRegisterModule] +[RegisterModel(typeof(RunStateModel))] +[RegisterSystem(typeof(BuildSystem))] +[RegisterUtility(typeof(AudioUtility))] +public partial class GameplayModule +{ +} +``` + +**完整文档**:[AutoRegisterModule 生成器](./auto-register-module-generator) + ## BindNodeSignal 生成器 BindNodeSignal 生成器为标记了 `[BindNodeSignal]` 特性的方法自动生成节点事件绑定和解绑代码。 @@ -503,6 +537,82 @@ public partial class MainMenu : Control **完整文档**:[BindNodeSignal 生成器](./bind-node-signal-generator) +## AutoUiPage 生成器 + +AutoUiPage 生成器为 Godot 页面节点自动生成 `UiKeyStr`、缓存的 `IUiPageBehavior` 和 `GetPage()`。 + +### 主要功能 + +- **页面键统一声明**:用一个 Attribute 同时声明页面 Key 与 `UiLayer` +- **行为缓存**:延迟创建并缓存 `IUiPageBehavior` +- **减少页面样板**:不再手写重复的页面工厂包装 + +### 基础示例 + +```csharp +using GFramework.Godot.SourceGenerators.Abstractions; +using GFramework.Game.Abstractions.Enums; +using Godot; + +[AutoUiPage(nameof(UiKey.MainMenu), nameof(UiLayer.Page))] +public partial class MainMenu : Control +{ +} +``` + +**完整文档**:[AutoUiPage 生成器](./auto-ui-page-generator) + +## AutoScene 生成器 + +AutoScene 生成器为场景根节点自动生成 `SceneKeyStr`、缓存的 `ISceneBehavior` 和 `GetScene()`。 + +### 主要功能 + +- **场景键统一声明**:避免散落的场景 key 字符串 +- **行为缓存**:延迟创建并复用场景行为对象 +- **路由接入更直接**:场景节点可直接暴露标准场景行为入口 + +### 基础示例 + +```csharp +using GFramework.Godot.SourceGenerators.Abstractions; +using GFramework.Game.Abstractions.Enums; +using Godot; + +[AutoScene(nameof(SceneKey.Gameplay))] +public partial class GameplayRoot : Node2D +{ +} +``` + +**完整文档**:[AutoScene 生成器](./auto-scene-generator) + +## AutoRegisterExportedCollections 生成器 + +AutoRegisterExportedCollections 生成器为 Godot 导出集合自动生成批量注册方法,适合启动入口和资源映射注册。 + +### 主要功能 + +- **批量注册样板收敛**:统一 `foreach + registry.Register(item)` 模式 +- **编译期校验**:验证集合、注册器成员和方法签名 +- **支持接口注册器**:兼容从基类和继承接口解析注册方法 + +### 基础示例 + +```csharp +using GFramework.Godot.SourceGenerators.Abstractions; +using Godot; + +[AutoRegisterExportedCollections] +public partial class GameEntryPoint : Node +{ + [RegisterExportedCollection(nameof(_textureRegistry), "Registry")] + private Godot.Collections.Array? _textureConfigs; +} +``` + +**完整文档**:[AutoRegisterExportedCollections 生成器](./auto-register-exported-collections-generator) + ## 诊断信息 GFramework.SourceGenerators 提供详细的编译时诊断信息,帮助开发者快速定位和解决问题。