ChunkGenerationTask.java
net.minecraft.server.level.ChunkGenerationTask
信息
- 全限定名:net.minecraft.server.level.ChunkGenerationTask
- 类型:public class
- 包:net.minecraft.server.level
- 源码路径:src/main/java/net/minecraft/server/level/ChunkGenerationTask.java
- 起始行号:L16
- 职责:
TODO
字段/常量
-
chunkMap- 类型:
GeneratingChunkMap - 修饰符:
private final - 源码定位:
L17 - 说明:
TODO
- 类型:
-
pos- 类型:
ChunkPos - 修饰符:
private final - 源码定位:
L18 - 说明:
TODO
- 类型:
-
scheduledStatus- 类型:
ChunkStatus - 修饰符:
private - 源码定位:
L19 - 说明:
TODO
- 类型:
-
targetStatus- 类型:
ChunkStatus - 修饰符:
public final - 源码定位:
L20 - 说明:
TODO
- 类型:
-
markedForCancellation- 类型:
boolean - 修饰符:
private volatile - 源码定位:
L21 - 说明:
TODO
- 类型:
-
scheduledLayer- 类型:
List<CompletableFuture<ChunkResult<ChunkAccess>>> - 修饰符:
private final - 源码定位:
L22 - 说明:
TODO
- 类型:
-
cache- 类型:
StaticCache2D<GenerationChunkHolder> - 修饰符:
private final - 源码定位:
L23 - 说明:
TODO
- 类型:
-
needsGeneration- 类型:
boolean - 修饰符:
private - 源码定位:
L24 - 说明:
TODO
- 类型:
内部类/嵌套类型
- 无
构造器
private ChunkGenerationTask(GeneratingChunkMap chunkMap, ChunkStatus targetStatus, ChunkPos pos, StaticCache2D<GenerationChunkHolder> cache) @ L26
- 构造器名:ChunkGenerationTask
- 源码定位:L26
- 修饰符:private
参数:
- chunkMap: GeneratingChunkMap
- targetStatus: ChunkStatus
- pos: ChunkPos
- cache: StaticCache2D
说明:
TODO
方法
下面的方法块按源码顺序生成。
public static ChunkGenerationTask create(GeneratingChunkMap chunkMap, ChunkStatus targetStatus, ChunkPos pos) @ L33
- 方法名:create
- 源码定位:L33
- 返回类型:ChunkGenerationTask
- 修饰符:public static
参数:
- chunkMap: GeneratingChunkMap
- targetStatus: ChunkStatus
- pos: ChunkPos
说明:
TODO
public CompletableFuture<?> runUntilWait() @ L41
- 方法名:runUntilWait
- 源码定位:L41
- 返回类型:CompletableFuture<?>
- 修饰符:public
参数:
- 无
说明:
TODO
private void scheduleNextLayer() @ L57
- 方法名:scheduleNextLayer
- 源码定位:L57
- 返回类型:void
- 修饰符:private
参数:
- 无
说明:
TODO
public void markForCancellation() @ L72
- 方法名:markForCancellation
- 源码定位:L72
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
private void releaseClaim() @ L76
- 方法名:releaseClaim
- 源码定位:L76
- 返回类型:void
- 修饰符:private
参数:
- 无
说明:
TODO
private boolean canLoadWithoutGeneration() @ L82
- 方法名:canLoadWithoutGeneration
- 源码定位:L82
- 返回类型:boolean
- 修饰符:private
参数:
- 无
说明:
TODO
public GenerationChunkHolder getCenter() @ L109
- 方法名:getCenter
- 源码定位:L109
- 返回类型:GenerationChunkHolder
- 修饰符:public
参数:
- 无
说明:
TODO
private void scheduleLayer(ChunkStatus status, boolean needsGeneration) @ L113
- 方法名:scheduleLayer
- 源码定位:L113
- 返回类型:void
- 修饰符:private
参数:
- status: ChunkStatus
- needsGeneration: boolean
说明:
TODO
private int getRadiusForLayer(ChunkStatus status, boolean needsGeneration) @ L129
- 方法名:getRadiusForLayer
- 源码定位:L129
- 返回类型:int
- 修饰符:private
参数:
- status: ChunkStatus
- needsGeneration: boolean
说明:
TODO
private boolean scheduleChunkInLayer(ChunkStatus status, boolean needsGeneration, GenerationChunkHolder chunkHolder) @ L134
- 方法名:scheduleChunkInLayer
- 源码定位:L134
- 返回类型:boolean
- 修饰符:private
参数:
- status: ChunkStatus
- needsGeneration: boolean
- chunkHolder: GenerationChunkHolder
说明:
TODO
private CompletableFuture<?> waitForScheduledLayer() @ L155
- 方法名:waitForScheduledLayer
- 源码定位:L155
- 返回类型:CompletableFuture<?>
- 修饰符:private
参数:
- 无
说明:
TODO
代码
public class ChunkGenerationTask {
private final GeneratingChunkMap chunkMap;
private final ChunkPos pos;
private @Nullable ChunkStatus scheduledStatus = null;
public final ChunkStatus targetStatus;
private volatile boolean markedForCancellation;
private final List<CompletableFuture<ChunkResult<ChunkAccess>>> scheduledLayer = new ArrayList<>();
private final StaticCache2D<GenerationChunkHolder> cache;
private boolean needsGeneration;
private ChunkGenerationTask(GeneratingChunkMap chunkMap, ChunkStatus targetStatus, ChunkPos pos, StaticCache2D<GenerationChunkHolder> cache) {
this.chunkMap = chunkMap;
this.targetStatus = targetStatus;
this.pos = pos;
this.cache = cache;
}
public static ChunkGenerationTask create(GeneratingChunkMap chunkMap, ChunkStatus targetStatus, ChunkPos pos) {
int worstCaseRadius = ChunkPyramid.GENERATION_PYRAMID.getStepTo(targetStatus).getAccumulatedRadiusOf(ChunkStatus.EMPTY);
StaticCache2D<GenerationChunkHolder> cache = StaticCache2D.create(
pos.x(), pos.z(), worstCaseRadius, (x, z) -> chunkMap.acquireGeneration(ChunkPos.pack(x, z))
);
return new ChunkGenerationTask(chunkMap, targetStatus, pos, cache);
}
public @Nullable CompletableFuture<?> runUntilWait() {
while (true) {
CompletableFuture<?> waitingFor = this.waitForScheduledLayer();
if (waitingFor != null) {
return waitingFor;
}
if (this.markedForCancellation || this.scheduledStatus == this.targetStatus) {
this.releaseClaim();
return null;
}
this.scheduleNextLayer();
}
}
private void scheduleNextLayer() {
ChunkStatus statusToSchedule;
if (this.scheduledStatus == null) {
statusToSchedule = ChunkStatus.EMPTY;
} else if (!this.needsGeneration && this.scheduledStatus == ChunkStatus.EMPTY && !this.canLoadWithoutGeneration()) {
this.needsGeneration = true;
statusToSchedule = ChunkStatus.EMPTY;
} else {
statusToSchedule = ChunkStatus.getStatusList().get(this.scheduledStatus.getIndex() + 1);
}
this.scheduleLayer(statusToSchedule, this.needsGeneration);
this.scheduledStatus = statusToSchedule;
}
public void markForCancellation() {
this.markedForCancellation = true;
}
private void releaseClaim() {
GenerationChunkHolder chunkHolder = this.cache.get(this.pos.x(), this.pos.z());
chunkHolder.removeTask(this);
this.cache.forEach(this.chunkMap::releaseGeneration);
}
private boolean canLoadWithoutGeneration() {
if (this.targetStatus == ChunkStatus.EMPTY) {
return true;
} else {
ChunkStatus highestGeneratedStatus = this.cache.get(this.pos.x(), this.pos.z()).getPersistedStatus();
if (highestGeneratedStatus != null && !highestGeneratedStatus.isBefore(this.targetStatus)) {
ChunkDependencies dependencies = ChunkPyramid.LOADING_PYRAMID.getStepTo(this.targetStatus).accumulatedDependencies();
int range = dependencies.getRadius();
for (int x = this.pos.x() - range; x <= this.pos.x() + range; x++) {
for (int z = this.pos.z() - range; z <= this.pos.z() + range; z++) {
int distance = this.pos.getChessboardDistance(x, z);
ChunkStatus requiredStatus = dependencies.get(distance);
ChunkStatus persistedStatus = this.cache.get(x, z).getPersistedStatus();
if (persistedStatus == null || persistedStatus.isBefore(requiredStatus)) {
return false;
}
}
}
return true;
} else {
return false;
}
}
}
public GenerationChunkHolder getCenter() {
return this.cache.get(this.pos.x(), this.pos.z());
}
private void scheduleLayer(ChunkStatus status, boolean needsGeneration) {
try (Zone zone = Profiler.get().zone("scheduleLayer")) {
zone.addText(status::getName);
int radius = this.getRadiusForLayer(status, needsGeneration);
for (int x = this.pos.x() - radius; x <= this.pos.x() + radius; x++) {
for (int z = this.pos.z() - radius; z <= this.pos.z() + radius; z++) {
GenerationChunkHolder chunkHolder = this.cache.get(x, z);
if (this.markedForCancellation || !this.scheduleChunkInLayer(status, needsGeneration, chunkHolder)) {
return;
}
}
}
}
}
private int getRadiusForLayer(ChunkStatus status, boolean needsGeneration) {
ChunkPyramid pyramid = needsGeneration ? ChunkPyramid.GENERATION_PYRAMID : ChunkPyramid.LOADING_PYRAMID;
return pyramid.getStepTo(this.targetStatus).getAccumulatedRadiusOf(status);
}
private boolean scheduleChunkInLayer(ChunkStatus status, boolean needsGeneration, GenerationChunkHolder chunkHolder) {
ChunkStatus persistedStatus = chunkHolder.getPersistedStatus();
boolean generate = persistedStatus != null && status.isAfter(persistedStatus);
ChunkPyramid pyramid = generate ? ChunkPyramid.GENERATION_PYRAMID : ChunkPyramid.LOADING_PYRAMID;
if (generate && !needsGeneration) {
throw new IllegalStateException("Can't load chunk, but didn't expect to need to generate");
} else {
CompletableFuture<ChunkResult<ChunkAccess>> future = chunkHolder.applyStep(pyramid.getStepTo(status), this.chunkMap, this.cache);
ChunkResult<ChunkAccess> now = future.getNow(null);
if (now == null) {
this.scheduledLayer.add(future);
return true;
} else if (now.isSuccess()) {
return true;
} else {
this.markForCancellation();
return false;
}
}
}
private @Nullable CompletableFuture<?> waitForScheduledLayer() {
while (!this.scheduledLayer.isEmpty()) {
CompletableFuture<ChunkResult<ChunkAccess>> lastFuture = this.scheduledLayer.getLast();
ChunkResult<ChunkAccess> resultNow = lastFuture.getNow(null);
if (resultNow == null) {
return lastFuture;
}
this.scheduledLayer.removeLast();
if (!resultNow.isSuccess()) {
this.markForCancellation();
}
}
return null;
}
}引用的其他类
-
- 引用位置:
字段
- 引用位置:
-
- 引用位置:
参数/字段
- 引用位置:
-
- 引用位置:
参数/字段/返回值
- 引用位置:
-
- 引用位置:
参数/字段/方法调用 - 关联成员:
StaticCache2D.create()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Profiler.get()
- 引用位置:
-
- 引用位置:
参数/字段/方法调用 - 关联成员:
ChunkPos.pack()
- 引用位置:
-
- 引用位置:
字段
- 引用位置:
-
- 引用位置:
参数/字段/方法调用 - 关联成员:
ChunkStatus.getStatusList()
- 引用位置: