Dynamic Emission Snapshots

基本信息

com.mitchej123.supernova.light.DynamicEmissionSnapshots(public final class)—— 在主线程采样 TileEntity 的彩色发光,工作线程只读已发布的数值, 永不接触 TileEntity。

源码类注释: Samples tile-entity emission on the main thread; workers read published values, never tile entities.

这与 Engine Internals 里 SafeBlockAccess.getTileEntity() 无条件返回 null 是配套设计 —— 引擎从不主动读 TileEntity。

两级存储

外层 ConcurrentHashMap<Long, Sources>(按 CoordinateUtils.getChunkKey(x>>4, z>>4)), 每个 Sources 内含:

字段 类型 作用
chunk Chunk 所属区块
tracked Int2ObjectOpenHashMap<TrackedSource> 本地坐标键 → 追踪源
values ConcurrentHashMap<Integer, Integer> 本地坐标键 → 已发布发光值

TrackedSource 持有 tile、position(ChunkPosition)与 key。

本地坐标键

static int localKey(x, y, z) { return (y << 8) | ((z & 15) << 4) | (x & 15); }

与 Light Queue 的 queueBlockChange 用的 (x & 15) | ((z & 15) << 4) | (y << 8) 是同一布局。

追踪条件

track(...) 只有同时满足以下条件才登记:

  1. !tile.isInvalid()
  2. 0 <= y <= 255
  3. x >> 4 == chunk.xPosition 且 z >> 4 == chunk.zPosition
  4. LightColorRegistry.isPositional(block) —— 非位置相关方块会主动注销

isTileEmitter 的判定是 block.hasTileEntity(meta) && isPositional(block)。

采样失败(RuntimeException)时返回 -1(跳过),并用 Set<Class<?>> sampleFailuresLogged 按方块类去重打一条 warn, 避免每 tick 刷屏。

每 tick 的失效清理

tick() 遍历所有 Sources,剔除两类条目:

条件 动作
tile.isInvalid() 或 chunkTileEntityMap.get(position) != tile 移除追踪 + 移除数值
!LightColorRegistry.isPositional(block)(方块被换掉) 同上

数值变化时 values.put(...) 并把键收进 IntArrayList changed, 循环结束后对每个变化键调 manager.queueBlockChange(...) 触发重照。 若某区块 tracked 变空,则从 chunks 里移除该 Sources(用双参 remove(key, value) 防误删)。

采样降级

track(...) 中若 emission < 0(采样失败), 用 values.putIfAbsent(key, LightColorRegistry.getPackedEmissionNoWorld(block, meta)) 兜底 —— 即退化为无世界上下文的静态发射值。

生命周期入口

方法 触发
registerChunk(Chunk) 区块加载,遍历 chunkTileEntityMap
unregisterChunk(cx, cz) 区块卸载
refreshPosition(x, y, z) TileEntity 增删后、方块变更任务入队前
tileEntityChanged(x, y, z) 比对 before/after,变化才 queueBlockChange
get(x, y, z) 工作线程读;null 表示无快照,走普通方块发光
setManager(WorldLightManager) 注入回引用

相关条目

源码

  • src/main/java/com/mitchej123/supernova/light/DynamicEmissionSnapshots.java