Forge 事件钩子
本 mod 不声明任何自定义事件,也不向任何总线 post 事件。它只做两件事:把自己注册到两个总线上,然后接收 FML / Forge 的生命周期事件。
基本信息
| 属性 | 值 |
|---|---|
| 类型 | 事件订阅 |
| 用到的总线 | Guava LoadController.masterChannel(FML 母总线)、MinecraftForge.EVENT_BUS(Forge 总线) |
总线注册位置
| 注册者 | 总线 | 代码位置 |
|---|---|---|
MCLib 实例自身 |
FML 母总线 | MCLib 构造函数,反射拿到 LoadController.masterChannel 后 register(this) |
UpdateCheckLib 实例(静态块) |
FML 母总线 和 MinecraftForge.EVENT_BUS |
UpdateCheckLib 的 static { } 块 |
SloppyDepLoader.DepLoadInst |
FML 母总线 | DepLoadInst 构造函数 |
SloppyDepLoader.DepLoadInst |
MinecraftForge.EVENT_BUS |
onInit(FMLInitializationEvent) 中注册,onGui 处理完主菜单后 unregister(this) |
UpdateCheckLib 与 DepLoadInst 的静态初始化时机很关键:两者都在 FML 进入 pre-init 之前就把自己挂上了母总线,靠 MCLib.onPreInit 里的 TaskQueue.consume 顺序来保证依赖满足。
订阅的事件清单
| 事件 | 注解 | 处理方法 | 处理者 | 总线 |
|---|---|---|---|---|
FMLPreInitializationEvent |
@Subscribe(Guava) |
MCLib.onPreInit |
MCLib |
FML 母总线 |
FMLInitializationEvent |
@Subscribe(Guava) |
DepLoadInst.onInit |
SloppyDepLoader.DepLoadInst |
FML 母总线 |
FMLPreInitializationEvent |
@Subscribe(Guava) |
UpdateCheckLib.preInit |
UpdateCheckLib |
FML 母总线(方法体为空) |
FMLPostInitializationEvent |
@Subscribe(Guava) |
UpdateCheckLib.postInit |
UpdateCheckLib |
FML 母总线 |
GuiOpenEvent |
@SubscribeEvent + @SideOnly(CLIENT) |
DepLoadInst.onGui |
SloppyDepLoader.DepLoadInst |
MinecraftForge.EVENT_BUS |
GuiScreenEvent.InitGuiEvent.Post |
@SubscribeEvent + @SideOnly(CLIENT) |
UpdateCheckLib.onGui |
UpdateCheckLib |
MinecraftForge.EVENT_BUS |
各事件的触发时机与行为
| 事件 | 触发时机 | 行为 |
|---|---|---|
FMLPreInitializationEvent |
pre-init 阶段 | 若本副本最新,跑 SloppyDepLoader 的 preInit() 下载可选依赖;然后消费该状态的任务队列(触发 AssetDirector 预初始化) |
FMLInitializationEvent |
init 阶段 | 仅为把 DepLoadInst 挂上 Forge 总线;注释写明"必须等到 pre-init 正式开始才能在 mod 事件总线上注册对象" |
FMLPostInitializationEvent |
post-init 阶段 | UpdateCheckLib 等所有 CompletableFuture 完成,统计 updateCount,写 updates.html,客户端再更新按钮上的数字。API 文档要求提交任务不晚于 post-init 开始 |
GuiOpenEvent |
客户端打开任意 GUI | 仅当 event.gui instanceof GuiMainMenu 且下载全部完成时,若有新增依赖则把 GUI 换成 GuiRestartNotification 提示重启,随后从总线上注销自己 |
GuiScreenEvent.InitGuiEvent.Post |
客户端任意 GUI 初始化完成后 | 仅当 event.gui instanceof GuiMainMenu 时,按 配置文件 的坐标在主菜单插入 GuiButtonUpdates;进入其他界面时把 updatesButton 置 null |
取消性
上面六个事件在源码中都没有被 @Cancelable 取消——其中 GuiOpenEvent 本身可取消(event.gui 可被替换),SloppyDepLoader 就是通过替换 event.gui 而不是调用 setCanceled(true) 来实现重启动提示的;其余五个 FML 生命周期事件不可取消。
本 mod 没有声明的事件
源码里 grep -rn "extends Event" 无结果,@Cancelable 注解无结果,EVENT_BUS.post / bus.post 无结果。若某个 mod 文档声称 MCLib 提供了自己的事件总线 API,那是错的。
相关条目
- MCLib 核心与任务队列 - 总线的反射获取与订阅注册
- GUI 注入 - 两个客户端事件里被注入的按钮与对话框