diff --git a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/fullData/sources/FullDataSourceV2.java b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/fullData/sources/FullDataSourceV2.java index 8e20be290..bbac771da 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/fullData/sources/FullDataSourceV2.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/fullData/sources/FullDataSourceV2.java @@ -37,6 +37,7 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper; import com.seibel.distanthorizons.coreapi.ModInfo; import it.unimi.dsi.fastutil.longs.LongArrayList; import org.apache.logging.log4j.Logger; +import org.jetbrains.annotations.NotNull; import javax.annotation.Nullable; import java.util.Arrays; @@ -223,8 +224,8 @@ public class FullDataSourceV2 implements IDataSource public LongArrayList get(int relX, int relZ) throws IndexOutOfBoundsException { return this.dataPoints[relativePosToIndex(relX, relZ)]; } @Override - public boolean update(FullDataSourceV2 inputDataSource, @Nullable IDhLevel level) { return this.update(inputDataSource); } - public boolean update(FullDataSourceV2 inputDataSource) + public boolean update(@NotNull FullDataSourceV2 inputDataSource, @Nullable IDhLevel level) { return this.update(inputDataSource); } + public boolean update(@NotNull FullDataSourceV2 inputDataSource) { byte thisDetailLevel = this.pos.getDetailLevel(); byte inputDetailLevel = inputDataSource.pos.getDetailLevel(); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/file/AbstractNewDataSourceHandler.java b/core/src/main/java/com/seibel/distanthorizons/core/file/AbstractNewDataSourceHandler.java index 0f5244621..1495dc2a4 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/file/AbstractNewDataSourceHandler.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/file/AbstractNewDataSourceHandler.java @@ -11,6 +11,7 @@ import com.seibel.distanthorizons.core.util.LodUtil; import com.seibel.distanthorizons.core.util.threading.PositionalLockProvider; import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil; import org.apache.logging.log4j.Logger; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.File; @@ -110,7 +111,7 @@ public abstract class AbstractNewDataSourceHandler /** * Returns the {@link TDataSource} for the given section position.
- * The returned data source may be null if there was a problem.

+ * The returned data source may be null if repo is in the process of shutting down.

* * This call is concurrent. I.e. it supports being called by multiple threads at the same time. */ @@ -135,9 +136,10 @@ public abstract class AbstractNewDataSourceHandler } /** * Should only be used in internal file handler methods where we are already running on a file handler thread. - * Shouldn't return null. + * Can return null if the repo is in the process of being shut down * @see AbstractNewDataSourceHandler#getAsync(DhSectionPos) */ + @Nullable public TDataSource get(DhSectionPos pos) { TDataSource dataSource = null; @@ -170,7 +172,7 @@ public abstract class AbstractNewDataSourceHandler // data updating // //===============// - public CompletableFuture updateDataSourceAsync(FullDataSourceV2 inputDataSource) + public CompletableFuture updateDataSourceAsync(@NotNull FullDataSourceV2 inputDataSource) { ThreadPoolExecutor executor = ThreadPoolUtil.getUpdatePropagatorExecutor(); if (executor == null || executor.isTerminated()) @@ -211,7 +213,7 @@ public abstract class AbstractNewDataSourceHandler * After this method returns the inputData will be written to file. * @param updatePos the position to update */ - protected void updateDataSourceAtPos(DhSectionPos updatePos, FullDataSourceV2 inputData, boolean lockOnUpdatePos) + protected void updateDataSourceAtPos(DhSectionPos updatePos, @NotNull FullDataSourceV2 inputData, boolean lockOnUpdatePos) { boolean methodLocked = false; // 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/FullDataSourceProviderV2.java b/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/FullDataSourceProviderV2.java index 506cf5016..9fe3c89c9 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/FullDataSourceProviderV2.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/FullDataSourceProviderV2.java @@ -250,8 +250,11 @@ public class FullDataSourceProviderV2 try (FullDataSourceV2 dataSource = this.get(childPos)) { - this.updateDataSourceAtPos(parentUpdatePos, dataSource, false); - this.repo.setApplyToParent(childPos, false); + if (dataSource != null) // can return null when the file handler is being shut down + { + this.updateDataSourceAtPos(parentUpdatePos, dataSource, false); + this.repo.setApplyToParent(childPos, false); + } } } catch (Exception e) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/LodRenderSection.java b/core/src/main/java/com/seibel/distanthorizons/core/render/LodRenderSection.java index 0952559b2..e619aaafe 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/LodRenderSection.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/LodRenderSection.java @@ -138,6 +138,12 @@ public class LodRenderSection implements IDebugRenderable, AutoCloseable { // get this positions data source fullDataSource = this.fullDataSourceProvider.get(this.pos); + if (fullDataSource == null) + { + // the file handler is being shut down, we won't be rendering anything anyway + return; + } + renderSource = FullDataToRenderDataTransformer.transformFullDataToRenderSource(fullDataSource, this.level); if (renderSource.isEmpty()) {