From 5a9ad2e6895ce5535b2c5974edfeac2a3b9b8ec8 Mon Sep 17 00:00:00 2001 From: dordsor21 Date: Sun, 12 Sep 2021 11:32:20 +0100 Subject: [PATCH] Add loadIfPresent method foor use where the section should definitely exist and be FULL --- .../heightmap/HeightmapProcessor.java | 5 ++-- .../history/changeset/AbstractChangeSet.java | 4 +++- .../core/queue/IBatchProcessor.java | 24 ++++++++++++------- .../core/queue/IBlocks.java | 19 +++++++++++++++ .../implementation/blocks/CharBlocks.java | 10 ++++++++ .../sk89q/worldedit/regions/CuboidRegion.java | 3 ++- 6 files changed, 53 insertions(+), 12 deletions(-) diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/processor/heightmap/HeightmapProcessor.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/processor/heightmap/HeightmapProcessor.java index 1119ed431..c42d51677 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/processor/heightmap/HeightmapProcessor.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/processor/heightmap/HeightmapProcessor.java @@ -61,8 +61,9 @@ public class HeightmapProcessor implements IBatchProcessor { if (!(hasSectionSet || hasSectionGet)) { continue; } - char[] setSection = hasSectionSet ? set.load(layer) : null; - if (Arrays.equals(setSection, FaweCache.IMP.EMPTY_CHAR_4096) || Arrays.equals(setSection, AIR_LAYER)) { + char[] setSection = hasSectionSet ? set.loadIfPresent(layer) : null; + if (setSection == null || Arrays.equals(setSection, FaweCache.IMP.EMPTY_CHAR_4096) || + Arrays.equals(setSection, AIR_LAYER)) { hasSectionSet = false; } if (!hasSectionSet && !hasSectionGet) { diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/AbstractChangeSet.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/AbstractChangeSet.java index 76a9052bc..98928dcc6 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/AbstractChangeSet.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/AbstractChangeSet.java @@ -33,6 +33,7 @@ import com.sk89q.worldedit.world.block.BlockState; import java.io.IOException; import java.util.Iterator; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.UUID; import java.util.concurrent.Future; @@ -170,7 +171,8 @@ public abstract class AbstractChangeSet implements ChangeSet, IBatchProcessor { System.arraycopy(tmp, 0, (blocksGet = new char[4096]), 0, 4096); } char[] blocksSet; - System.arraycopy(set.load(layer), 0, (blocksSet = new char[4096]), 0, 4096); + // loadIfPresent shouldn't be null if set.hasSection(layer) is true + System.arraycopy(Objects.requireNonNull(set.loadIfPresent(layer)), 0, (blocksSet = new char[4096]), 0, 4096); // Account for negative layers int by = layer << 4; diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IBatchProcessor.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IBatchProcessor.java index 218ecc203..6770c706c 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IBatchProcessor.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IBatchProcessor.java @@ -44,10 +44,14 @@ public interface IBatchProcessor { for (int layer = set.getMinSectionPosition(); layer <= minLayer; layer++) { if (set.hasSection(layer)) { if (layer == minLayer) { - char[] arr = set.load(layer); - int index = (minY & 15) << 8; - for (int i = 0; i < index; i++) { - arr[i] = 0; + char[] arr = set.loadIfPresent(layer); + if (arr != null) { + int index = (minY & 15) << 8; + for (int i = 0; i < index; i++) { + arr[i] = 0; + } + } else { + arr = new char[4096]; } set.setBlocks(layer, arr); } else { @@ -59,10 +63,14 @@ public interface IBatchProcessor { for (int layer = maxLayer; layer < set.getMaxSectionPosition(); layer++) { if (set.hasSection(layer)) { if (layer == minLayer) { - char[] arr = set.load(layer); - int index = ((maxY + 1) & 15) << 8; - for (int i = index; i < arr.length; i++) { - arr[i] = 0; + char[] arr = set.loadIfPresent(layer); + if (arr != null) { + int index = ((maxY + 1) & 15) << 8; + for (int i = index; i < arr.length; i++) { + arr[i] = 0; + } + } else { + arr = new char[4096]; } set.setBlocks(layer, arr); } else { diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IBlocks.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IBlocks.java index a482af14f..2b4eb84f1 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IBlocks.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IBlocks.java @@ -12,6 +12,7 @@ import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.registry.BlockRegistry; +import javax.annotation.Nullable; import java.io.IOException; import java.util.Map; import java.util.Set; @@ -31,8 +32,26 @@ public interface IBlocks extends Trimable { */ boolean hasSection(int layer); + /** + * Obtain the specified chunk section stored as an array of ordinals. Uses normal minecraft chunk-section position indices + * (length 4096). Operations synchronises on the section and will load the section into memory if not present. For chunk + * GET operations, this will load the data from the world. For chunk SET, this will create a new empty array. + * + * @param layer chunk section layer (may be negative) + * @return char array of ordinals of the chunk section + */ char[] load(int layer); + /** + * Obtain the specified chunk section stored as an array of ordinals if present or null. Uses normal minecraft chunk-section + * position indices (length 4096). Does not synchronise to the section layer as it will not attempt to load into memory. + * + * @param layer chunk section layer (may be negative) + * @return char array of ordinals of the chunk section if present + */ + @Nullable + char[] loadIfPresent(int layer); + BlockState getBlock(int x, int y, int z); Map getTiles(); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/CharBlocks.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/CharBlocks.java index 53950b614..733743f39 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/CharBlocks.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/CharBlocks.java @@ -145,6 +145,16 @@ public abstract class CharBlocks implements IBlocks { } } + @Nullable + @Override + public char[] loadIfPresent(int layer) { + if (layer < minSectionPosition || layer > minSectionPosition) { + return null; + } + layer -= minSectionPosition; + return sections[layer].isFull() ? blocks[layer] : null; + } + @Override public BlockState getBlock(int x, int y, int z) { return BlockTypesCache.states[get(x, y, z)]; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java index 28228589f..fb4c816cf 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java @@ -37,6 +37,7 @@ import javax.annotation.Nonnull; import java.util.AbstractSet; import java.util.Iterator; import java.util.NoSuchElementException; +import java.util.Objects; import java.util.Set; import static com.google.common.base.Preconditions.checkArgument; @@ -769,7 +770,7 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion { for (int layer = get.getMinSectionPosition(); layer < get.getMaxSectionPosition(); layer++) { if (set.hasSection(layer)) { - char[] arr = set.load(layer); + char[] arr = Objects.requireNonNull(set.loadIfPresent(layer)); // This shouldn't be null if above is true if (trimX || trimZ) { int indexY = 0; for (int y = 0; y < 16; y++, indexY += 256) { // For each y layer within a chunk section