GFramework/docs/zh-CN/source-generators/auto-register-exported-collections-generator.md
GeWuYou e691c9c855 docs(api): 添加 GFramework API 参考文档和源代码生成器文档
- 新增 API 参考文档,包含核心命名空间、常用 API、游戏模块 API、Godot 集成 API
- 详细介绍架构、模型、系统、命令、查询等核心类型及其用法示例
- 添加本地化系统 API 文档,包含管理器、字符串、配置等相关接口
- 新增源代码生成器完整文档,涵盖 Log、Config Schema、ContextAware 等生成器
- 详细说明各生成器的使用方法、配置选项和诊断信息
- 提供完整的 Godot 专用生成器文档,包括 GetNode、BindNodeSignal、AutoUiPage 等
- 添加使用示例和最佳实践指南,展示完整的游戏控制器和枚举状态管理示例
2026-04-13 19:16:28 +08:00

5.5 KiB

AutoRegisterExportedCollections 生成器

为 Godot 导出集合生成批量注册方法,收敛启动入口里的重复 foreach + Registry(...) 样板。

概述

在游戏启动入口中,常见的一类样板是:

  • 在 Inspector 中导出一批配置、资源映射或预制体条目
  • 从某个 Registry 成员拿到注册器
  • 遍历集合逐项调用 Register(...) / Registry(...)

AutoRegisterExportedCollections 会把这类样板收敛成声明式配置。

它特别适合 GameEntryPoint、资源根节点、配置引导节点这类“导出即注册”的场景。

基础使用

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>
{
}

[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()
    {
        __RegisterExportedCollections_Generated();
    }
}

生成的代码

// <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 注册方法名,例如 RegisterRegistry

推荐优先使用 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 导出字段和外部依赖通常还未准备完毕。

相关文档