diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/ConcurrentReadClipboard.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/ConcurrentReadClipboard.java new file mode 100644 index 0000000000..e9054ba5ff --- /dev/null +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/ConcurrentReadClipboard.java @@ -0,0 +1,151 @@ +package com.fastasyncworldedit.core.extent.clipboard; + +import com.fastasyncworldedit.core.nbt.FaweCompoundTag; +import com.sk89q.worldedit.entity.Entity; +import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard; +import com.sk89q.worldedit.extent.clipboard.Clipboard; +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.regions.Region; +import com.sk89q.worldedit.world.biome.BiomeType; +import com.sk89q.worldedit.world.block.BaseBlock; +import com.sk89q.worldedit.world.block.BlockState; +import com.sk89q.worldedit.world.block.BlockStateHolder; +import org.jetbrains.annotations.ApiStatus; + +import javax.annotation.Nonnull; +import java.util.Iterator; +import java.util.List; + +@ApiStatus.Experimental // Temporary wrapper +public class ConcurrentReadClipboard implements Clipboard { + + private final Clipboard parent; + + public static Clipboard tryWrap(Clipboard clipboard) { + if (clipboard.supportsParallelAccess()) { + return clipboard; + } + return new ConcurrentReadClipboard(clipboard); + } + + private ConcurrentReadClipboard(Clipboard parent) { + this.parent = parent; + } + + @Override + public synchronized BlockState getBlock(BlockVector3 position) { + return parent.getBlock(position); + } + + @Override + public synchronized BlockState getBlock(int x, int y, int z) { + return parent.getBlock(x, y, z); + } + + @Override + public synchronized BaseBlock getFullBlock(BlockVector3 position) { + return parent.getFullBlock(position); + } + + @Override + public synchronized BaseBlock getFullBlock(int x, int y, int z) { + return parent.getFullBlock(x, y, z); + } + + @Override + public BiomeType getBiomeType(int x, int y, int z) { + return parent.getBiomeType(x, y, z); + } + + @Override + public BiomeType getBiome(BlockVector3 position) { + return parent.getBiome(position); + } + + @Override + public > boolean setBlock(int x, int y, int z, B block) { + throw new UnsupportedOperationException("Wrapper not intended for writing"); + } + + @Override + public boolean tile(int x, int y, int z, FaweCompoundTag tile) { + throw new UnsupportedOperationException("Wrapper not intended for writing"); + } + + @Override + public boolean setBiome(int x, int y, int z, BiomeType biome) { + throw new UnsupportedOperationException("Wrapper not intended for writing"); + } + + @Override + public boolean setBiome(BlockVector3 position, BiomeType biome) { + throw new UnsupportedOperationException("Wrapper not intended for writing"); + } + + @Override + public BlockVector3 getMinimumPoint() { + return parent.getMinimumPoint(); + } + + @Override + public BlockVector3 getMaximumPoint() { + return parent.getMaximumPoint(); + } + + @Override + public List getEntities(Region region) { + return parent.getEntities(region); + } + + @Override + public List getEntities() { + return parent.getEntities(); + } + + @Override + public Region getRegion() { + return parent.getRegion(); + } + + @Override + public BlockVector3 getDimensions() { + return parent.getDimensions(); + } + + @Override + public BlockVector3 getOrigin() { + return parent.getOrigin(); + } + + @Override + public void setOrigin(BlockVector3 origin) { + throw new UnsupportedOperationException("Wrapper not intended for writing"); + } + + @Override + public boolean hasBiomes() { + return parent.hasBiomes(); + } + + @Override + public void removeEntity(Entity entity) { + throw new UnsupportedOperationException("Wrapper not intended for writing"); + } + + @Override + @Nonnull + public Iterator iterator() { + return parent.iterator(); + } + + @Override + public boolean supportsParallelAccess() { + return true; + } + + @Override + public void close() { + parent.close(); + } + +} diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/DiskOptimizedClipboard.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/DiskOptimizedClipboard.java index dc2ba45059..e074fa8dc9 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/DiskOptimizedClipboard.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/DiskOptimizedClipboard.java @@ -303,6 +303,11 @@ public URI getURI() { return file.toURI(); } + @Override + public boolean supportsParallelAccess() { + return true; + } + public File getFile() { return file; } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/EmptyClipboard.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/EmptyClipboard.java index 983ea79b0d..774b2432f6 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/EmptyClipboard.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/EmptyClipboard.java @@ -46,6 +46,11 @@ public void setOrigin(@Nonnull BlockVector3 origin) { public void removeEntity(@Nonnull Entity entity) { } + @Override + public boolean supportsParallelAccess() { + return true; + } + @Nonnull public BlockVector3 getMinimumPoint() { return BlockVector3.ZERO; diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/WorldCopyClipboard.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/WorldCopyClipboard.java index b4e30abacd..8669eda5cb 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/WorldCopyClipboard.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/WorldCopyClipboard.java @@ -102,6 +102,11 @@ public boolean hasBiomes() { return hasBiomes; } + @Override + public boolean supportsParallelAccess() { + return true; + } + @Override public void paste(Extent toExtent, BlockVector3 to, boolean pasteAir, boolean pasteEntities, boolean pasteBiomes) { boolean close = false; diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/BlockArrayClipboard.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/BlockArrayClipboard.java index 9ff666f799..a6f0264042 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/BlockArrayClipboard.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/BlockArrayClipboard.java @@ -385,6 +385,11 @@ public Clipboard getParent() { return parent; } + @Override + public boolean supportsParallelAccess() { + return parent.supportsParallelAccess(); + } + @Override public void close() { this.parent.close(); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/Clipboard.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/Clipboard.java index be702ae4d4..537ce96dd7 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/Clipboard.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/clipboard/Clipboard.java @@ -216,6 +216,15 @@ default URI getURI() { return null; } + /** + * Check if this clipboard supports concurrent reading. + * + * @since TODO + */ + default boolean supportsParallelAccess() { + return false; + } + @Override default T apply(Region region, T filter, boolean full) { if (region.equals(getRegion())) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/ClipboardPattern.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/ClipboardPattern.java index b0fac9c400..a614e41a04 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/ClipboardPattern.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/ClipboardPattern.java @@ -19,6 +19,7 @@ package com.sk89q.worldedit.function.pattern; +import com.fastasyncworldedit.core.extent.clipboard.ConcurrentReadClipboard; import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.math.BlockVector3; @@ -43,7 +44,7 @@ public ClipboardPattern(Clipboard clipboard) { * @param offset the offset */ public ClipboardPattern(Clipboard clipboard, BlockVector3 offset) { - super(clipboard, clipboard.getMinimumPoint(), offset); + super(ConcurrentReadClipboard.tryWrap(clipboard), clipboard.getMinimumPoint(), offset); } }