自动事件总线
基本信息
| 属性 | 值 |
|---|---|
| 类 | com.gtnewhorizon.gtnhlib.eventbus.AutoEventBus |
| 注解 | com.gtnewhorizon.gtnhlib.eventbus.EventBusSubscriber |
| 阶段枚举 | com.gtnewhorizon.gtnhlib.eventbus.Phase |
| 包路径 | src/main/java/com/gtnewhorizon/gtnhlib/eventbus/(6 个类) |
| 执行入口 | AutoEventBus.executePhase(Phase) |
功能
给类加 @EventBusSubscriber 即可让其中的 @SubscribeEvent 方法自动注册到 Forge 事件总线,无需手动 MinecraftForge.EVENT_BUS.register(...)。README 的表述(README.md Events 节):
Mark a class
@EventBusSubscriberto auto-register its@SubscribeEventmethods. Choose the side and load phase in the annotation. No manual registration needed.
GTNHLib 自身在 CommonProxy 的 4 个生命周期方法中按阶段驱动(CommonProxy.java:64-107):
| 调用点 | 阶段 |
|---|---|
CommonProxy.construct() |
Phase.CONSTRUCT |
CommonProxy.preInit() |
Phase.PRE |
CommonProxy.init() |
Phase.INIT |
@EventBusSubscriber
eventbus/EventBusSubscriber.java:18,@Retention(RUNTIME)、@Target(TYPE):
| 成员 | 默认值 | 说明 |
|---|---|---|
side() |
{ Side.CLIENT, Side.SERVER } |
订阅侧,两端都订阅 |
phase() |
Phase.INIT |
等价于 FML LoaderState,在哪个加载阶段注册 |
重要约束(EventBusSubscriber.java:16 注释):
All methods annotated with
@SubscribeEventare expected to be static.
条件方法
嵌套注解 @EventBusSubscriber.Condition(:38)可标在一个 boolean 方法上,作为整类的注册条件。契约(EventBusSubscriber.java:32-36 注释):
- 方法必须是
static、返回boolean、无参数 - 一个类至多一个条件方法
条件求值失败时的行为(eventbus/AutoEventBus.java:196-199)——记录 error 并保守地不注册:
} catch (Throwable e) {
LOGGER.error("Failed to invoke condition {} for class {}", condition, clazz, e);
return false;
}
即条件方法抛异常会导致该类静默不被注册(仅有日志),这是排查"事件不触发"时的首要检查点。
Phase
eventbus/Phase.java 定义 3 个阶段值,与 FML 生命周期事件一一对应:
| 枚举值 | 对应 FML 事件 | 触发点 |
|---|---|---|
CONSTRUCT |
FMLConstructionEvent |
CommonProxy.construct()(:65) |
PRE |
FMLPreInitializationEvent |
CommonProxy.preInit()(:69) |
INIT |
FMLInitializationEvent |
CommonProxy.init()(:107) |
每个枚举值自带一个 boolean hasExecuted 标志与 Object2ObjectMap<ModContainer, ObjectSet<String>> modClassesForPhase(Lombok @Getter(AccessLevel.PACKAGE)),用于保证每阶段只执行一次并记录已注册类。
注意 Phase 与 mixin 的 EARLY/LATE 是两套互不相干的阶段划分,见 Mixin 引导流程。
数值
| 数值名 | 值 |
|---|---|
eventbus 包类数 |
6(AutoEventBus、EventBusSubscriber、EventBusUtil、MethodInfo、Phase、StaticASMEventHandler) |
@EventBusSubscriber 成员数 |
2(side、phase)+ 1 个嵌套注解 Condition |
Phase 枚举值数 |
3(CONSTRUCT、PRE、INIT) |
executePhase 调用点 |
3(CommonProxy 的 construct / preInit / init) |
AutoEventBus 中 catch (Throwable) |
1 处(条件求值,:196) |
交互
典型用法:
@EventBusSubscriber(side = Side.CLIENT, phase = Phase.INIT)
public class MyHandler {
@Condition
public static boolean isEnabled() { return ...; }
@SubscribeEvent
public static void onEvent(SomeEvent e) { ...; }
}
CommonProxy 自身就标了 @EventBusSubscriber(CommonProxy.java:61),其 onPlayerLogin 静态方法在玩家加入时把服务端视距发给客户端(CommonProxy.java:197-202)。