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<TKey, TValue>
{
}
public interface IRegistry<TKey, TValue>
{
void Registry(IKeyValue<TKey, TValue> mapping);
}
public interface IAssetRegistry<TValue> : IRegistry<string, TValue>
{
}
public sealed class TextureConfig : Resource, IKeyValue<string, Texture2D>
{
}
public sealed class TextureRegistry : IAssetRegistry<Texture2D>
{
public void Registry(IKeyValue<string, Texture2D> mapping)
{
}
}
[AutoRegisterExportedCollections]
public partial class GameEntryPoint : Node
{
private IAssetRegistry<Texture2D>? _textureRegistry;
[Export]
[RegisterExportedCollection(nameof(_textureRegistry), nameof(IRegistry<string, Texture2D>.Registry))]
private Godot.Collections.Array<TextureConfig>? _textureConfigs;
public override void _Ready()
{
_textureRegistry ??= new TextureRegistry();
__RegisterExportedCollections_Generated();
}
}为了让示例具备完整的调用路径,这里在 _Ready() 里先初始化了 _textureRegistry。 实际项目里,这个字段通常来自架构容器、服务定位或外部注入;关键点是调用 __RegisterExportedCollections_Generated() 之前,注册器成员必须已经可用,否则生成代码会按设计静默跳过注册。
生成的代码
csharp
// <auto-generated />
#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<T> 继承 IRegistry<TKey, TValue> 的项目结构也能正常生成,不必再把注册器字段改成具体实现类型。
适用场景
推荐用于:
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 导出字段和外部依赖通常还未准备完毕。