ThreadedLevelLightEngine.java

net.minecraft.server.level.ThreadedLevelLightEngine

信息

  • 全限定名:net.minecraft.server.level.ThreadedLevelLightEngine
  • 类型:public class
  • 包:net.minecraft.server.level
  • 源码路径:src/main/java/net/minecraft/server/level/ThreadedLevelLightEngine.java
  • 起始行号:L26
  • 继承:LevelLightEngine
  • 实现:AutoCloseable
  • 职责:

    TODO

字段/常量

  • DEFAULT_BATCH_SIZE

    • 类型: int
    • 修饰符: public static final
    • 源码定位: L27
    • 说明:

      TODO

  • LOGGER

    • 类型: Logger
    • 修饰符: private static final
    • 源码定位: L28
    • 说明:

      TODO

  • consecutiveExecutor

    • 类型: ConsecutiveExecutor
    • 修饰符: private final
    • 源码定位: L29
    • 说明:

      TODO

  • lightTasks

    • 类型: ObjectList<Pair<ThreadedLevelLightEngine.TaskType,Runnable>>
    • 修饰符: private final
    • 源码定位: L30
    • 说明:

      TODO

  • chunkMap

    • 类型: ChunkMap
    • 修饰符: private final
    • 源码定位: L31
    • 说明:

      TODO

  • taskDispatcher

    • 类型: ChunkTaskDispatcher
    • 修饰符: private final
    • 源码定位: L32
    • 说明:

      TODO

  • taskPerBatch

    • 类型: int
    • 修饰符: private final
    • 源码定位: L33
    • 说明:

      TODO

  • scheduled

    • 类型: AtomicBoolean
    • 修饰符: private final
    • 源码定位: L34
    • 说明:

      TODO

内部类/嵌套类型

  • net.minecraft.server.level.ThreadedLevelLightEngine.TaskType
    • 类型: enum
    • 修饰符: private static
    • 源码定位: L216
    • 说明:

      TODO

构造器

public ThreadedLevelLightEngine(LightChunkGetter lightChunkGetter, ChunkMap chunkMap, boolean hasSkyLight, ConsecutiveExecutor consecutiveExecutor, ChunkTaskDispatcher taskDispatcher) @ L36

  • 构造器名:ThreadedLevelLightEngine
  • 源码定位:L36
  • 修饰符:public

参数:

  • lightChunkGetter: LightChunkGetter
  • chunkMap: ChunkMap
  • hasSkyLight: boolean
  • consecutiveExecutor: ConsecutiveExecutor
  • taskDispatcher: ChunkTaskDispatcher

说明:

TODO

方法

下面的方法块按源码顺序生成。

public void close() @ L45

  • 方法名:close
  • 源码定位:L45
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

public int runLightUpdates() @ L49

  • 方法名:runLightUpdates
  • 源码定位:L49
  • 返回类型:int
  • 修饰符:public

参数:

说明:

TODO

public void checkBlock(BlockPos pos) @ L54

  • 方法名:checkBlock
  • 源码定位:L54
  • 返回类型:void
  • 修饰符:public

参数:

  • pos: BlockPos

说明:

TODO

protected void updateChunkStatus(ChunkPos pos) @ L65

  • 方法名:updateChunkStatus
  • 源码定位:L65
  • 返回类型:void
  • 修饰符:protected

参数:

  • pos: ChunkPos

说明:

TODO

public void updateSectionStatus(SectionPos pos, boolean sectionEmpty) @ L81

  • 方法名:updateSectionStatus
  • 源码定位:L81
  • 返回类型:void
  • 修饰符:public

参数:

  • pos: SectionPos
  • sectionEmpty: boolean

说明:

TODO

public void propagateLightSources(ChunkPos pos) @ L92

  • 方法名:propagateLightSources
  • 源码定位:L92
  • 返回类型:void
  • 修饰符:public

参数:

  • pos: ChunkPos

说明:

TODO

public void setLightEnabled(ChunkPos pos, boolean enable) @ L99

  • 方法名:setLightEnabled
  • 源码定位:L99
  • 返回类型:void
  • 修饰符:public

参数:

  • pos: ChunkPos
  • enable: boolean

说明:

TODO

public void queueSectionData(LightLayer layer, SectionPos pos, DataLayer data) @ L109

  • 方法名:queueSectionData
  • 源码定位:L109
  • 返回类型:void
  • 修饰符:public

参数:

  • layer: LightLayer
  • pos: SectionPos
  • data: DataLayer

说明:

TODO

private void addTask(int chunkX, int chunkZ, ThreadedLevelLightEngine.TaskType type, Runnable runnable) @ L120

  • 方法名:addTask
  • 源码定位:L120
  • 返回类型:void
  • 修饰符:private

参数:

  • chunkX: int
  • chunkZ: int
  • type: ThreadedLevelLightEngine.TaskType
  • runnable: Runnable

说明:

TODO

private void addTask(int chunkX, int chunkZ, IntSupplier level, ThreadedLevelLightEngine.TaskType type, Runnable runnable) @ L124

  • 方法名:addTask
  • 源码定位:L124
  • 返回类型:void
  • 修饰符:private

参数:

  • chunkX: int
  • chunkZ: int
  • level: IntSupplier
  • type: ThreadedLevelLightEngine.TaskType
  • runnable: Runnable

说明:

TODO

public void retainData(ChunkPos pos, boolean retain) @ L133

  • 方法名:retainData
  • 源码定位:L133
  • 返回类型:void
  • 修饰符:public

参数:

  • pos: ChunkPos
  • retain: boolean

说明:

TODO

public CompletableFuture<ChunkAccess> initializeLight(ChunkAccess chunk, boolean lighted) @ L140

  • 方法名:initializeLight
  • 源码定位:L140
  • 返回类型:CompletableFuture
  • 修饰符:public

参数:

  • chunk: ChunkAccess
  • lighted: boolean

说明:

TODO

public CompletableFuture<ChunkAccess> lightChunk(ChunkAccess centerChunk, boolean lighted) @ L160

  • 方法名:lightChunk
  • 源码定位:L160
  • 返回类型:CompletableFuture
  • 修饰符:public

参数:

  • centerChunk: ChunkAccess
  • lighted: boolean

说明:

TODO

public void tryScheduleUpdate() @ L178

  • 方法名:tryScheduleUpdate
  • 源码定位:L178
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

private void runUpdate() @ L187

  • 方法名:runUpdate
  • 源码定位:L187
  • 返回类型:void
  • 修饰符:private

参数:

说明:

TODO

public CompletableFuture<?> waitForPendingTasks(int chunkX, int chunkZ) @ L212

  • 方法名:waitForPendingTasks
  • 源码定位:L212
  • 返回类型:CompletableFuture<?>
  • 修饰符:public

参数:

  • chunkX: int
  • chunkZ: int

说明:

TODO

代码

public class ThreadedLevelLightEngine extends LevelLightEngine implements AutoCloseable {
    public static final int DEFAULT_BATCH_SIZE = 1000;
    private static final Logger LOGGER = LogUtils.getLogger();
    private final ConsecutiveExecutor consecutiveExecutor;
    private final ObjectList<Pair<ThreadedLevelLightEngine.TaskType, Runnable>> lightTasks = new ObjectArrayList<>();
    private final ChunkMap chunkMap;
    private final ChunkTaskDispatcher taskDispatcher;
    private final int taskPerBatch = 1000;
    private final AtomicBoolean scheduled = new AtomicBoolean();
 
    public ThreadedLevelLightEngine(
        LightChunkGetter lightChunkGetter, ChunkMap chunkMap, boolean hasSkyLight, ConsecutiveExecutor consecutiveExecutor, ChunkTaskDispatcher taskDispatcher
    ) {
        super(lightChunkGetter, true, hasSkyLight);
        this.chunkMap = chunkMap;
        this.taskDispatcher = taskDispatcher;
        this.consecutiveExecutor = consecutiveExecutor;
    }
 
    @Override
    public void close() {
    }
 
    @Override
    public int runLightUpdates() {
        throw (UnsupportedOperationException)Util.pauseInIde(new UnsupportedOperationException("Ran automatically on a different thread!"));
    }
 
    @Override
    public void checkBlock(BlockPos pos) {
        BlockPos immutable = pos.immutable();
        this.addTask(
            SectionPos.blockToSectionCoord(pos.getX()),
            SectionPos.blockToSectionCoord(pos.getZ()),
            ThreadedLevelLightEngine.TaskType.PRE_UPDATE,
            Util.name(() -> super.checkBlock(immutable), () -> "checkBlock " + immutable)
        );
    }
 
    protected void updateChunkStatus(ChunkPos pos) {
        this.addTask(pos.x(), pos.z(), () -> 0, ThreadedLevelLightEngine.TaskType.PRE_UPDATE, Util.name(() -> {
            super.retainData(pos, false);
            super.setLightEnabled(pos, false);
 
            for (int sectionY = this.getMinLightSection(); sectionY < this.getMaxLightSection(); sectionY++) {
                super.queueSectionData(LightLayer.BLOCK, SectionPos.of(pos, sectionY), null);
                super.queueSectionData(LightLayer.SKY, SectionPos.of(pos, sectionY), null);
            }
 
            for (int sectionY = this.levelHeightAccessor.getMinSectionY(); sectionY <= this.levelHeightAccessor.getMaxSectionY(); sectionY++) {
                super.updateSectionStatus(SectionPos.of(pos, sectionY), true);
            }
        }, () -> "updateChunkStatus " + pos + " true"));
    }
 
    @Override
    public void updateSectionStatus(SectionPos pos, boolean sectionEmpty) {
        this.addTask(
            pos.x(),
            pos.z(),
            () -> 0,
            ThreadedLevelLightEngine.TaskType.PRE_UPDATE,
            Util.name(() -> super.updateSectionStatus(pos, sectionEmpty), () -> "updateSectionStatus " + pos + " " + sectionEmpty)
        );
    }
 
    @Override
    public void propagateLightSources(ChunkPos pos) {
        this.addTask(
            pos.x(), pos.z(), ThreadedLevelLightEngine.TaskType.PRE_UPDATE, Util.name(() -> super.propagateLightSources(pos), () -> "propagateLight " + pos)
        );
    }
 
    @Override
    public void setLightEnabled(ChunkPos pos, boolean enable) {
        this.addTask(
            pos.x(),
            pos.z(),
            ThreadedLevelLightEngine.TaskType.PRE_UPDATE,
            Util.name(() -> super.setLightEnabled(pos, enable), () -> "enableLight " + pos + " " + enable)
        );
    }
 
    @Override
    public void queueSectionData(LightLayer layer, SectionPos pos, @Nullable DataLayer data) {
        this.addTask(
            pos.x(),
            pos.z(),
            () -> 0,
            ThreadedLevelLightEngine.TaskType.PRE_UPDATE,
            Util.name(() -> super.queueSectionData(layer, pos, data), () -> "queueData " + pos)
        );
    }
 
    private void addTask(int chunkX, int chunkZ, ThreadedLevelLightEngine.TaskType type, Runnable runnable) {
        this.addTask(chunkX, chunkZ, this.chunkMap.getChunkQueueLevel(ChunkPos.pack(chunkX, chunkZ)), type, runnable);
    }
 
    private void addTask(int chunkX, int chunkZ, IntSupplier level, ThreadedLevelLightEngine.TaskType type, Runnable runnable) {
        this.taskDispatcher.submit(() -> {
            this.lightTasks.add(Pair.of(type, runnable));
            if (this.lightTasks.size() >= 1000) {
                this.runUpdate();
            }
        }, ChunkPos.pack(chunkX, chunkZ), level);
    }
 
    @Override
    public void retainData(ChunkPos pos, boolean retain) {
        this.addTask(
            pos.x(), pos.z(), () -> 0, ThreadedLevelLightEngine.TaskType.PRE_UPDATE, Util.name(() -> super.retainData(pos, retain), () -> "retainData " + pos)
        );
    }
 
    public CompletableFuture<ChunkAccess> initializeLight(ChunkAccess chunk, boolean lighted) {
        ChunkPos pos = chunk.getPos();
        this.addTask(pos.x(), pos.z(), ThreadedLevelLightEngine.TaskType.PRE_UPDATE, Util.name(() -> {
            LevelChunkSection[] sections = chunk.getSections();
 
            for (int sectionIndex = 0; sectionIndex < chunk.getSectionsCount(); sectionIndex++) {
                LevelChunkSection section = sections[sectionIndex];
                if (!section.hasOnlyAir()) {
                    int sectionY = this.levelHeightAccessor.getSectionYFromSectionIndex(sectionIndex);
                    super.updateSectionStatus(SectionPos.of(pos, sectionY), false);
                }
            }
        }, () -> "initializeLight: " + pos));
        return CompletableFuture.supplyAsync(() -> {
            super.setLightEnabled(pos, lighted);
            super.retainData(pos, false);
            return chunk;
        }, r -> this.addTask(pos.x(), pos.z(), ThreadedLevelLightEngine.TaskType.POST_UPDATE, r));
    }
 
    public CompletableFuture<ChunkAccess> lightChunk(ChunkAccess centerChunk, boolean lighted) {
        ChunkPos pos = centerChunk.getPos();
        centerChunk.setLightCorrect(false);
        this.addTask(pos.x(), pos.z(), ThreadedLevelLightEngine.TaskType.PRE_UPDATE, Util.name(() -> {
            if (!lighted) {
                super.propagateLightSources(pos);
            }
 
            if (SharedConstants.DEBUG_VERBOSE_SERVER_EVENTS) {
                LOGGER.debug("LIT {}", pos);
            }
        }, () -> "lightChunk " + pos + " " + lighted));
        return CompletableFuture.supplyAsync(() -> {
            centerChunk.setLightCorrect(true);
            return centerChunk;
        }, r -> this.addTask(pos.x(), pos.z(), ThreadedLevelLightEngine.TaskType.POST_UPDATE, r));
    }
 
    public void tryScheduleUpdate() {
        if ((!this.lightTasks.isEmpty() || super.hasLightWork()) && this.scheduled.compareAndSet(false, true)) {
            this.consecutiveExecutor.schedule(() -> {
                this.runUpdate();
                this.scheduled.set(false);
            });
        }
    }
 
    private void runUpdate() {
        int totalSize = Math.min(this.lightTasks.size(), 1000);
        ObjectListIterator<Pair<ThreadedLevelLightEngine.TaskType, Runnable>> iterator = this.lightTasks.iterator();
 
        int count;
        for (count = 0; iterator.hasNext() && count < totalSize; count++) {
            Pair<ThreadedLevelLightEngine.TaskType, Runnable> task = iterator.next();
            if (task.getFirst() == ThreadedLevelLightEngine.TaskType.PRE_UPDATE) {
                task.getSecond().run();
            }
        }
 
        iterator.back(count);
        super.runLightUpdates();
 
        for (int var5 = 0; iterator.hasNext() && var5 < totalSize; var5++) {
            Pair<ThreadedLevelLightEngine.TaskType, Runnable> task = iterator.next();
            if (task.getFirst() == ThreadedLevelLightEngine.TaskType.POST_UPDATE) {
                task.getSecond().run();
            }
 
            iterator.remove();
        }
    }
 
    public CompletableFuture<?> waitForPendingTasks(int chunkX, int chunkZ) {
        return CompletableFuture.runAsync(() -> {}, r -> this.addTask(chunkX, chunkZ, ThreadedLevelLightEngine.TaskType.POST_UPDATE, r));
    }
 
    private static enum TaskType {
        PRE_UPDATE,
        POST_UPDATE;
    }
}

引用的其他类