虚拟子世界注册表
基本信息
| 属性 | 值 |
|---|---|
| 类 | com.gtnewhorizon.gtnhlib.api.world.WorldContextRegistry |
| 源码 | src/main/java/com/gtnewhorizon/gtnhlib/api/world/WorldContextRegistry.java |
| 形态 | final 类 + 私有构造,纯静态注册表 |
| 目标场景 | LittleBlocks、MetaWorlds 等把虚拟子世界渲染进父世界的 mod |
| 作用面 | 双方(客户端专用代码隔离在私有内部类) |
功能
为"虚拟子世界"建立地址与父世界的双向映射,使子世界的信息能在客户端与服务端之间传递。类注释(WorldContextRegistry.java:9-14):
Registry for mods Like LittleBlocks or MetaWorlds that add virtual subworlds that need to be rendered into another parent world.
地址由三元组构成 —— 父维度 id + 命名空间 + 子世界 id。命名空间的存在是因为每个 mod 维护自己的子 id 空间。
数值
| 数值名 | 值 |
|---|---|
| 公共常量 | 3(ROOT_SUB_ID = 0、UNKNOWN_SUB_ID = -1、ROOT_NAMESPACE = "") |
WorldAddress 字段 |
3(全部 public final) |
Handler 接口方法 |
4(全部 default) |
| 静态注册方法 | 1(registerHandler) |
| 静态查询方法 | 6(addressOf、getHostWorld、getWorlds、getSubWorld、getClientWorld、getServerWorld) |
| 底层存储 | LinkedHashMap<String, Handler>,保持注册顺序 |
WorldAddress 构造器带双向一致性校验(:53-58):namespace 为 ROOT_NAMESPACE(空串)当且仅当 subId == ROOT_SUB_ID,否则抛 IllegalArgumentException;namespace 为 null 同样抛异常。
hashCode() 用 FNV-1a 逐步散列三个字段(:76-81),不是 Objects.hash。
交互
| 调用 | 行为 |
|---|---|
registerHandler(ns, handler) |
注册处理器。ns 为空、已注册或 null 均抛 IllegalArgumentException |
addressOf(world) |
遍历处理器找 getSubId(world) != UNKNOWN_SUB_ID 者;普通世界返回 root 地址 |
getHostWorld(world) |
返回父世界;普通世界返回自身 |
getWorlds(world) |
父世界排首位,随后追加各处理器的子世界 —— 无虚拟世界时返回单元素列表,调用方可无条件遍历 |
getSubWorld(host, addr) |
root 地址返回 host;否则按命名空间找处理器 |
getClientWorld(addr) |
客户端当前世界必须在 addr.hostDimensionId 维度,否则抛 RuntimeException |
getServerWorld(addr) |
经 DimensionManager.getWorld(dimId) 取得服务端世界 |
两处运行时不变式检查值得注意(:171-186),是刻意设计而非缺陷:
- 处理器声称拥有 subId 为
0的世界 → 抛RuntimeException(子世界 id 必须为正) - 处理器认领了子世界却答不出
getHostWorld→ 抛RuntimeException
Handler 的 4 个 default 方法全部有安全默认:getSubWorld/getHostWorld 返回 null,getSubId 返回 UNKNOWN_SUB_ID,getSubWorlds 返回 Collections.emptyList()。
客户端代码通过私有内部类 ClientWorldAccess 隔离(:257-263),避免在 common 侧类加载路径上触碰 net.minecraft.client.Minecraft。
相关条目
- 内存与哈希工具 -
WorldAddress.hashCode使用的 FNV-1a 实现