Light Queue
基本信息
com.mitchej123.supernova.light.LightQueue(public final class)——
按区块组织的插入序任务队列,单生产者 / 单消费者:
主线程投喂,该 lane 的工作线程消费。
| 字段 | 类型 | 作用 |
|---|---|---|
tasksByChunk |
Long2ObjectLinkedOpenHashMap<ChunkTasks> |
权威表,保持插入序 |
inFlight |
ChunkTasks |
已出队但未完成的那唯一一个任务 |
workAvailable |
Semaphore(0) |
唤醒工作线程 |
blockChangeKeys |
LongArrayFIFOQueue |
方块变更键 |
initialLightKeys |
LongArrayFIFOQueue |
初始光照键 |
inFlight 之所以能只有一个:源码注释说明队列单消费者,
且一个任务在下一个出队前必定已完成。
两条独立的键队列
blockChangeKeys 与 initialLightKeys 分离,使
removeFirstBlockChangeTask() 能跳过纯初始光照任务 ——
源码注释:player block placement/breaking outranks chunk loading。
hasInitialLightTask() 则反过来让到达的初始光照抢占边缘检查阶段。
两条键队列只 push 不 remove(
false -> true翻转时入队)。 因此键可能指向已消失或已不合格的任务,读取方需自行跳过。
世代与重试:isSuperseded
isSuperseded(key, generation, edgePass) 判定某世代是否已被更新世代取代。
比较符号刻意不同:
| 通道 | 比较 | 效果 |
|---|---|---|
edgePass = false(传播) |
existing.lightGeneration > generation |
严格大于才取代,溢出重试可替换自己这一代 |
edgePass = true(边缘) |
existing.lightGeneration >= generation |
大于等于即取代,边缘检查不会插到传播前面 |
lightGeneration == 0L 视为「无世代」,一律不取代。
任务入队入口
| 方法 | 作用 |
|---|---|
queueBlockChange(x,y,z) |
记录位置键 (x&15) | ((z&15)<<4) | (y<<8) 到 IntOpenHashSet |
queueSectionChange(cx, sectionY, cz, empty) |
写 Boolean[WorldUtil.getTotalSections()] 空区表 |
queueChunkLight(...) |
首次排入初始光照 |
requeueChunkLight(..., previousAttempts) |
BFS 队列溢出后重试同一世代,attempts = max(attempts, previous+1) |
queueInitialLightEdges(...) |
所有 lane 传播完成后的边缘对账 |
queueEdgeCheckAllSections(cx,cz) |
把全部 section 塞进 queuedEdgeChecks |
queueChunkLight / requeueChunkLight 显式重置 edgePass = false 与
attempts = 0(或 previousAttempts+1),
因为 getOrCreate 跨世代返回同一个 task 对象,重试预算必须显式重置。
完成与查询
| 方法 | 说明 |
|---|---|
completeTask(task) |
由工作线程 finally 调用,抛异常也不会搁浅区块 |
pendingWorkFuture(long key) |
返回 SettableFuture<Void>,不在队列则 null |
hasPendingWork(cx, cz) |
在表里或正是 inFlight |
removeChunk(cx, cz) |
移除并 onComplete.set(null) |
waitForWork() / wakeUp() |
Semaphore.acquire() 后 drainPermits() |
chunksQueued 统计在 getOrCreate 新建 task 时自增
(stats 可为 null,见 Light Stats)。
相关条目
- Chunk Tasks — 队列里装的任务对象
- World Light Manager — lane 线程
- Light Stats
- Extended World —
supernova$hasChunkPendingLight的数据源
源码
src/main/java/com/mitchej123/supernova/light/LightQueue.java