GFramework/docs/zh-CN/source-generators/priority-generator.md
gewuyou 289f12f309 docs(batch-boot): 收口旧入口对比文案
- 更新 Core、Game、Godot 与 source-generators 多个页面的 reader-facing 契约说明

- 将旧文档和旧入口对比句式改成直接陈述当前默认入口、约束与推荐做法

- 补充 documentation full coverage active topic 的 RP-047 跟踪与验证记录
2026-04-28 07:37:20 +08:00

5.5 KiB
Raw Blame History

title, description
title description
Priority 生成器 说明 [Priority] 当前会生成什么、何时生效、应配合哪些优先级 API 使用,以及动态优先级的边界。

Priority 生成器

[Priority] 的职责很简单:为目标类型自动生成 IPrioritized.Priority

它本身不是调度器,也不会自动改变系统、服务或处理器的执行顺序。只有调用方使用了“按优先级排序”的检索入口,生成出来的 Priority 才会真正影响顺序。

当前包关系

  • 特性来源:GFramework.Core.SourceGenerators.Abstractions
  • 生成器实现:GFramework.Core.SourceGenerators
  • 运行时契约:GFramework.Core.Abstractions.Bases.IPrioritized
  • 预定义常量:GFramework.Core.Abstractions.Bases.PriorityGroup

最小用法

using GFramework.Core.Abstractions.Bases;
using GFramework.Core.SourceGenerators.Abstractions.Bases;

[Priority(PriorityGroup.High)]
public partial class SaveSystem : AbstractSystem
{
    protected override void OnInit()
    {
    }
}

当前生成器会补出:

public int Priority => PriorityGroup.High;

优先级值越小,优先级越高。

当前真正会读取优先级的入口

IIocContainer

如果你直接在容器层取集合,使用:

var handlers = container.GetAllByPriority<IMyHandler>();

IArchitectureContext

当前推荐按组件类别使用这些 API

  • GetServicesByPriority<TService>()
  • GetSystemsByPriority<TSystem>()
  • GetModelsByPriority<TModel>()
  • GetUtilitiesByPriority<TUtility>()

IContextAware 扩展方法

如果你已经在 [ContextAware] 类型或 ContextAwareBase 派生类型里,直接用:

  • this.GetServicesByPriority<TService>()
  • this.GetSystemsByPriority<TSystem>()
  • this.GetModelsByPriority<TModel>()
  • this.GetUtilitiesByPriority<TUtility>()

当前公开扩展方法就是按角色拆分的这些 API而不是泛化的 this.GetAllByPriority<T>()

最小接入示例

系统排序

using GFramework.Core.Abstractions.Bases;
using GFramework.Core.Abstractions.Systems;
using GFramework.Core.Extensions;
using GFramework.Core.SourceGenerators.Abstractions.Bases;
using GFramework.Core.SourceGenerators.Abstractions.Rule;

[Priority(PriorityGroup.Critical)]
public partial class InputSystem : AbstractSystem
{
    protected override void OnInit()
    {
    }
}

[ContextAware]
public partial class SystemBootstrapper : IController
{
    public void Start()
    {
        var systems = this.GetSystemsByPriority<ISystem>();

        foreach (var system in systems)
        {
            system.Initialize();
        }
    }
}

服务排序

[Priority(PriorityGroup.High)]
public partial class PremiumSaveMigration : ISaveMigration
{
}

[Priority(PriorityGroup.Low)]
public partial class MetricsSaveMigration : ISaveMigration
{
}

var migrations = architecture.Context.GetServicesByPriority<ISaveMigration>();

PriorityGroup 的角色

当前仓库提供了这些预定义常量:

  • PriorityGroup.Critical
  • PriorityGroup.High
  • PriorityGroup.Normal
  • PriorityGroup.Low
  • PriorityGroup.Deferred

文档不应该把这些值解释成硬编码的生命周期阶段。它们只是团队共享的排序语义常量,具体“高优先级意味着先做什么”仍然取决于 调用方对排序结果的使用方式。

如果项目有更细粒度的排序约定,也可以直接传 int,或在项目层自定义自己的优先级常量。

何时使用 [Priority]

适合以下场景:

  • 类型顺序在编译期就能确定
  • 你不想手写 IPrioritized
  • 同一类型的所有实例都应共享同一个优先级

常见例子:

  • 初始化顺序明确的系统
  • 顺序敏感的服务实现
  • 有先后要求的处理器或迁移器

何时不要使用 [Priority]

以下场景应改为手写 IPrioritized

  • 优先级要依赖运行时配置
  • 优先级要根据环境、开关或状态动态变化
  • 你已经手动实现了 IPrioritized

例如:

public sealed class DynamicPrioritySystem : IPrioritized
{
    private readonly bool _enabled;

    public DynamicPrioritySystem(bool enabled)
    {
        _enabled = enabled;
    }

    public int Priority => _enabled ? PriorityGroup.High : PriorityGroup.Deferred;
}

当前诊断与约束

[Priority] 当前有几条直接约束:

  • GF_Priority_001
    • 只能标在 class
  • GF_Priority_002
    • 目标类型已经手写实现 IPrioritized
  • GF_Priority_003
    • 类型必须是 partial
  • GF_Priority_004
    • 特性值缺失或无效
  • GF_Priority_005
    • 不支持嵌套类

对文档而言,最关键的结论是:

  • partial 是强约束
  • 顶层类是强约束
  • 手写实现与生成实现只能二选一

与旧写法的边界

下面这些旧写法或旧表述已经不再适合作为默认指导:

  • IContextAware 类型里统一写 this.GetAllByPriority<T>()
  • 继续用 system.Init() 作为系统初始化示例
  • [Priority] 写成“标了就会自动改变执行顺序”

当前更准确的理解是:

  • [Priority] 只生成 Priority
  • 排序效果依赖容器、上下文或扩展方法是否走了 priority-aware API
  • IContextAware 路径更推荐按组件类别使用 GetSystemsByPriority / GetServicesByPriority 等入口

推荐阅读

  1. ContextAware 生成器
  2. ContextGet 生成器
  3. Core 模块总览
  4. 源码生成器总览