Signal Bus 网络

基本信息

属性 值
性质 非标准多方块 —— 无固定尺寸、无控制器、无框架判定
唯一使用者 Signal Bus(SignalBusLogic,成员)
主控类 SignalBusMasterLogic(MultiblockMasterBaseLogic)
框架文件数 7(lib/multiblock/,共 981 行)
成员接口 IMultiblockMember
成员方块 仅 TMechworks:signalBus
结构大小 无上限,按 6 面邻接图自由聚合
破坏顺序 任意顺序均可拆除,无「先控制器后成员」要求

与本 wiki 其它多方块的区别

本 mod 的多方块不是 3×3×3 / 5×5×5 这类固定体积结构,而是自组织邻接网络:

特征 GTNH 常见多方块 本网络的 Signal Bus
尺寸 固定 N×M×K 无固定尺寸
控制器 必须有且唯一 无控制器,任一成员可为主控
成型条件 遍历固定偏移校验 getNeighboringMembers() 动态返回邻居
拆除限制 多为「先控制器后成员」 任意顺序,onDetached 自动重算
跨区块 通常不支持 支持(MultiblockRegistry 按 chunk 预注册)

因此本条目不列「几×几×几、控制器在哪个、能否旋转拆除」 —— 这些字段对本结构不存在。

框架组件(7 个文件)

文件 行数 职责
MultiblockBaseLogic.java 348 成员基类:邻接发现、attachBlock / detachBlock、isCompatible 传播
MultiblockMasterBaseLogic.java 380 主控基类:信号聚合调度、doMultiblockTick、NBT 序列化
MultiblockRegistry.java 118 全局注册表:CopyOnWriteArraySet<MultiblockMasterBaseLogic> + 按 dimensionId/chunkCoord 的预加载表
IMultiblockMember.java 52 成员契约(onAttached / onDetached / onChunkLoad / getNeighboringMembers / getNewMultiblockMasterObject)
BlockMultiblock.java 17 供多方块成员方块继承的 Block 薄封装
MultiblockEventHandler.java 38 Forge 事件钩子(区块加载 / 卸载时通知注册表)
MultiblockServerTickHandler.java 28 仅服务端注册(TMechworks.preInit 中 if (event.getSide() == Side.SERVER))

lib/multiblock/BlockMultiblock.java(17 行)在本 mod 无任何子类 —— Signal Bus 直接继承 Block,未走这个薄封装。

聚合流程

  1. 放置 Signal Bus → SignalBusLogic.addPlacedSide(side) 置位该面
  2. SignalBusLogic.getNeighboringMembers() 枚举 6 面(跳过未 placedSides 的面),返回相邻的 ISignalBusConnectable
  3. MultiblockBaseLogic 逐个 isCompatible(other) 检查 → attachBlock 归入主控
  4. 邻接变化触发 onAttached / onDetached,全网重算
  5. SignalBusMasterLogic.doMultiblockTick() 聚合 localHighSignals(byte[16])→ getSignals()
  6. updateBusSignals(CoordTuple bus, byte[] signals) 分发给已注册的 Signal Terminal

跨区块加载

MultiblockRegistry 用两层表处理「成员先于主控加载」:

  • preInitMembers / preInitMasters:HashMap<dimensionId, HashMap<chunkCoord, List<IMultiblockMember>>>
  • loadedMembers:加载完成后转入
  • onChunkLoaded(world, chunkCoord):先处理主控再处理成员,逐个 onChunkLoad()

数值

数值 值
框架文件数 7(981 行)
成员方块种类 1(TMechworks:signalBus)
结构尺寸 无固定尺寸
控制器 无
主控实现 SignalBusMasterLogic(getNewMultiblockMasterObject() 每成员各建一个)
信号数组 byte[16](16 通道)
聚合缓存 cachedReceivedSignals byte[16] + cachedConnectableCount int
增量标志 southboundSignalsChanged / northboundSignalsChanged / forceCheck
Tick 端 仅服务端(MultiblockServerTickHandler)
跨区块 支持(按 chunk 预注册)
拆除限制 无

源码缺陷

  • BlockMultiblock 是死类(17 行,lib/multiblock/BlockMultiblock.java):全仓无任何类继承它。
  • MasterBaseLogic 380 行 > 成员基类 348 行,但 Signal Bus 的主控只用了 getSignals() / updateBusSignals() / getSignals() / endMerging() / NBT 五个方法 —— 框架本身比它唯一的用户更复杂,属过度设计。
  • MultiblockRegistry.masters 是静态 CopyOnWriteArraySet 且从不清理世界引用:tick(World) 遍历全部 master 比对 logic.worldObj == world,世界卸载时若 unregister 未被调用会泄漏 World 引用。MultiblockEventHandler(38 行)的钩子覆盖是否完整无法从字段判断。
  • loadedMembers 字段被声明但 onChunkLoaded 走的是 preInit* 表:本条目未确认 loadedMembers 的写入点,若为零则该字段是死字段。
  • 无跨维度网络:MultiblockRegistry 的所有表都以 world.provider.dimensionId 为第一层 key,天然隔离维度。Spool of Wire 的 targetDim 因此被限制在同维度(见其缺陷条目)。
  • 无控制器意味着「网络归属」语义模糊:getNewMultiblockMasterObject() 每个成员都建一个 master 对象,聚合时靠 MultiblockBaseLogic 选一个存活者。源码无「谁是 master」的可观测输出,玩家无法从游戏内判断网络状态。

相关条目