diff --git a/core/src/main/java/com/seibel/distanthorizons/core/file/AbstractDataSourceHandler.java b/core/src/main/java/com/seibel/distanthorizons/core/file/AbstractDataSourceHandler.java index b87b809c5..8f2ec3440 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/file/AbstractDataSourceHandler.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/file/AbstractDataSourceHandler.java @@ -17,6 +17,7 @@ import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.nio.channels.ClosedChannelException; +import java.util.ArrayList; import java.util.Enumeration; import java.util.Timer; import java.util.TimerTask; @@ -187,8 +188,6 @@ public abstract class AbstractDataSourceHandler updateDataSourcesWithChunkDataAsync(ChunkSizedFullDataAccessor chunkDataView) { - DhSectionPos pos = chunkDataView.getSectionPos().convertNewToDetailLevel(DhSectionPos.SECTION_MINIMUM_DETAIL_LEVEL); - ThreadPoolExecutor executor = ThreadPools.getFileHandlerExecutor(); if (executor == null || executor.isTerminated()) { @@ -199,7 +198,15 @@ public abstract class AbstractDataSourceHandler this.updateDataSourcesRecursively(pos, chunkDataView), executor); + return CompletableFuture.runAsync(() -> + { + DhSectionPos bottomPos = chunkDataView.getSectionPos().convertNewToDetailLevel(DhSectionPos.SECTION_MINIMUM_DETAIL_LEVEL); + + bottomPos.forEachPosUpToDetailLevel( + this.topSectionDetailLevelRef.byteValue(), + (pos) -> this.updateDataSourceAtPos(pos, chunkDataView) ); + + }, executor); } catch (RejectedExecutionException ignore) { @@ -207,26 +214,6 @@ public abstract class AbstractDataSourceHandler this.topSectionDetailLevelRef.get()) - { - return; - } - - - DhSectionPos chunkSectionPos = chunkDataView.getSectionPos(); - LodUtil.assertTrue(chunkSectionPos.overlapsExactly(pos), "Update failed, chunk [" + chunkSectionPos + "] does not overlap section [" + pos + "]."); - - // update this pos - this.updateDataSourceAtPos(pos, chunkDataView); - - // recursively update the parent pos - DhSectionPos parentPos = pos.getParentPos(); - this.updateDataSourcesRecursively(parentPos, chunkDataView); - } protected void updateDataSourceAtPos(DhSectionPos pos, ChunkSizedFullDataAccessor chunkData) { // a lock is necessary to prevent two threads from writing to the same position at once, diff --git a/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/FullDataFileHandler.java b/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/FullDataFileHandler.java index 503214ef0..8f89ab2a5 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/FullDataFileHandler.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/FullDataFileHandler.java @@ -89,7 +89,11 @@ public class FullDataFileHandler extends AbstractDataSourceHandler
@@ -314,6 +315,21 @@ public class DhSectionPos } } + /** Applies the given consumer to all children of the position at the given section detail level. */ + public void forEachChildDownToDetailLevel(byte minSectionDetailLevel, Function callback) + { + boolean stop = callback.apply(this); + if (stop || minSectionDetailLevel == this.detailLevel) + { + return; + } + + for (int i = 0; i < 4; i++) + { + this.getChildByIndex(i).forEachChildDownToDetailLevel(minSectionDetailLevel, callback); + } + } + /** Applies the given consumer to all children of the position at the given section detail level. */ public void forEachChildAtLevel(byte sectionDetailLevel, Consumer callback) { @@ -329,6 +345,20 @@ public class DhSectionPos } } + /** Applies the given consumer to all children of the position at the given section detail level. */ + public void forEachPosUpToDetailLevel(byte maxSectionDetailLevel, Consumer callback) + { + callback.accept(this); + if (maxSectionDetailLevel == this.detailLevel) + { + return; + } + + this.getParentPos().forEachPosUpToDetailLevel(maxSectionDetailLevel, callback); + } + + + //===============//