From 35fd159e79ead572813cdf0cee28bc92340a7caa Mon Sep 17 00:00:00 2001 From: Jesse Boyd Date: Thu, 25 Apr 2019 20:32:27 +1000 Subject: [PATCH] WIP rewrite of NMS pipeline --- .../fawe/bukkit/v1_13/beta/CachedChunk.java | 29 ++++ .../fawe/bukkit/v1_13/beta/CharBlocks.java | 5 + .../fawe/bukkit/v1_13/beta/CharGetBlocks.java | 7 + .../fawe/bukkit/v1_13/beta/CharSetBlocks.java | 14 ++ .../fawe/bukkit/v1_13/beta/IBlocks.java | 5 + .../boydti/fawe/bukkit/v1_13/beta/IChunk.java | 20 +++ .../fawe/bukkit/v1_13/beta/IGetBlocks.java | 4 + .../fawe/bukkit/v1_13/beta/ISetBlocks.java | 4 + .../bukkit/v1_13/beta/RegionCachedChunk.java | 9 ++ .../bukkit/v1_13/beta/ReusableExtent.java | 150 ++++++++++++++++++ .../bukkit/v1_13/beta/holder/ChunkHolder.java | 13 ++ .../bukkit/v1_13/beta/holder/SetChunk.java | 7 + .../java/com/boydti/fawe/config/Settings.java | 2 +- .../com/boydti/fawe/jnbt/anvil/MCAChunk.java | 3 - 14 files changed, 268 insertions(+), 4 deletions(-) create mode 100644 worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/beta/CachedChunk.java create mode 100644 worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/beta/CharBlocks.java create mode 100644 worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/beta/CharGetBlocks.java create mode 100644 worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/beta/CharSetBlocks.java create mode 100644 worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/beta/IBlocks.java create mode 100644 worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/beta/IChunk.java create mode 100644 worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/beta/IGetBlocks.java create mode 100644 worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/beta/ISetBlocks.java create mode 100644 worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/beta/RegionCachedChunk.java create mode 100644 worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/beta/ReusableExtent.java create mode 100644 worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/beta/holder/ChunkHolder.java create mode 100644 worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/beta/holder/SetChunk.java diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/beta/CachedChunk.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/beta/CachedChunk.java new file mode 100644 index 000000000..3a2df1006 --- /dev/null +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/beta/CachedChunk.java @@ -0,0 +1,29 @@ +package com.boydti.fawe.bukkit.v1_13.beta; + +import com.sk89q.jnbt.CompoundTag; +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 net.minecraft.server.v1_13_R2.Chunk; +import net.minecraft.server.v1_13_R2.ChunkSection; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.UUID; + +public class CachedChunk { + private GetBlocks get; + private SetBlocks set; + + public CachedChunk(ReusableExtent parent) { + + } + + + public void init(int X, int Z) { + + } + + +} diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/beta/CharBlocks.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/beta/CharBlocks.java new file mode 100644 index 000000000..b1a202380 --- /dev/null +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/beta/CharBlocks.java @@ -0,0 +1,5 @@ +package com.boydti.fawe.bukkit.v1_13.beta; + +public class CharBlocks implements IBlocks { + protected char[][] blocks; +} diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/beta/CharGetBlocks.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/beta/CharGetBlocks.java new file mode 100644 index 000000000..62a05b707 --- /dev/null +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/beta/CharGetBlocks.java @@ -0,0 +1,7 @@ +package com.boydti.fawe.bukkit.v1_13.beta; + +import net.minecraft.server.v1_13_R2.ChunkSection; + +public class CharGetBlocks extends CharBlocks implements IGetBlocks { + private ChunkSection[] sections; +} diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/beta/CharSetBlocks.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/beta/CharSetBlocks.java new file mode 100644 index 000000000..66c2f4197 --- /dev/null +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/beta/CharSetBlocks.java @@ -0,0 +1,14 @@ +package com.boydti.fawe.bukkit.v1_13.beta; + +import com.sk89q.jnbt.CompoundTag; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.UUID; + +public class CharSetBlocks extends CharBlocks implements ISetBlocks { + private byte[] biomes; + private HashMap tiles; + private HashSet entities; + private HashSet entityRemoves; +} diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/beta/IBlocks.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/beta/IBlocks.java new file mode 100644 index 000000000..187a914d3 --- /dev/null +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/beta/IBlocks.java @@ -0,0 +1,5 @@ +package com.boydti.fawe.bukkit.v1_13.beta; + +public interface IBlocks { + +} diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/beta/IChunk.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/beta/IChunk.java new file mode 100644 index 000000000..b9372b0d2 --- /dev/null +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/beta/IChunk.java @@ -0,0 +1,20 @@ +package com.boydti.fawe.bukkit.v1_13.beta; + +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; + +public interface IChunk { + /* set */ + void setBiome(int x, int z, BiomeType biome); + + void setBlock(int x, int y, int z, BlockStateHolder holder); + + /* get */ + BiomeType getBiome(int x, int z); + + BlockState getBlock(int x, int y, int z); + + BaseBlock getFullBlock(int x, int y, int z); +} diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/beta/IGetBlocks.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/beta/IGetBlocks.java new file mode 100644 index 000000000..446a6a4d6 --- /dev/null +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/beta/IGetBlocks.java @@ -0,0 +1,4 @@ +package com.boydti.fawe.bukkit.v1_13.beta; + +public interface IGetBlocks extends IBlocks { +} diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/beta/ISetBlocks.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/beta/ISetBlocks.java new file mode 100644 index 000000000..90f45b8c8 --- /dev/null +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/beta/ISetBlocks.java @@ -0,0 +1,4 @@ +package com.boydti.fawe.bukkit.v1_13.beta; + +public interface ISetBlocks extends IBlocks { +} diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/beta/RegionCachedChunk.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/beta/RegionCachedChunk.java new file mode 100644 index 000000000..7984a0b80 --- /dev/null +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/beta/RegionCachedChunk.java @@ -0,0 +1,9 @@ +package com.boydti.fawe.bukkit.v1_13.beta; + +import net.minecraft.server.v1_13_R2.Chunk; + +public class RegionCachedChunk extends CachedChunk { + public RegionCachedChunk(Chunk chunk) { + super(chunk); + } +} diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/beta/ReusableExtent.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/beta/ReusableExtent.java new file mode 100644 index 000000000..e095eb27c --- /dev/null +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/beta/ReusableExtent.java @@ -0,0 +1,150 @@ +package com.boydti.fawe.bukkit.v1_13.beta; + +import com.boydti.fawe.Fawe; +import com.boydti.fawe.jnbt.anvil.MCAFilter; +import com.boydti.fawe.util.TaskManager; +import com.boydti.fawe.wrappers.WorldWrapper; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.bukkit.BukkitWorld; +import com.sk89q.worldedit.function.mask.Mask; +import com.sk89q.worldedit.math.BlockVector2; +import com.sk89q.worldedit.regions.Region; +import com.sk89q.worldedit.world.World; +import com.sk89q.worldedit.world.biome.BiomeType; +import com.sk89q.worldedit.world.block.BlockState; +import com.sk89q.worldedit.world.block.BlockStateHolder; +import net.minecraft.server.v1_13_R2.WorldServer; +import org.bukkit.Bukkit; +import org.bukkit.craftbukkit.v1_13_R2.CraftWorld; + +import java.util.Iterator; +import java.util.Set; +import java.util.concurrent.ForkJoinPool; + +import static com.google.common.base.Preconditions.checkNotNull; + +public class ReusableExtent { + private WorldWrapper wrapped; + private World world; + private org.bukkit.World bukkitWorld; + private WorldServer nmsWorld; + + private void reset() { + if (world != null) { + wrapped = null; + world = null; + bukkitWorld = null; + nmsWorld = null; + lowMemory = false; + } + } + + public void init(World world) { + reset(); + checkNotNull(world); + if (world instanceof EditSession) { + world = ((EditSession) world).getWorld(); + } + checkNotNull(world); + if (world instanceof WorldWrapper) { + this.wrapped = (WorldWrapper) world; + world = WorldWrapper.unwrap(world); + } else { + this.world = WorldWrapper.wrap(world); + } + this.world = world; + if (world instanceof BukkitWorld) { + this.bukkitWorld = ((BukkitWorld) world).getWorld(); + } else { + this.bukkitWorld = Bukkit.getWorld(world.getName()); + } + checkNotNull(this.bukkitWorld); + CraftWorld craftWorld = ((CraftWorld) bukkitWorld); + this.nmsWorld = craftWorld.getHandle(); + // Save world + } + + private boolean lowMemory; + + public void setLowMemory() { + lowMemory = true; + // set queue state to active + // trim cached chunks + } + + private CachedChunk getCachedChunk(int x, int z) { + // check last + // otherwise create/load + // get cached chunk from bukkit + // otherwise load + // TODO load async (with paper) + if (lowMemory) { + if (Fawe.isMainThread()) { + // submit other chunks + next(); + } else { + // wait until empty + } + } + } + + void setBlock(int x, int y, int z, BlockStateHolder holder) { + CachedChunk chunk = getCachedChunk(x, z); + chunk.setBlock(x & 15, y, z & 15, holder); + } + + void setBiome(int x, int z, BiomeType biome) { + CachedChunk chunk = getCachedChunk(x, z); + chunk.setBiome(x, z, biome); + } + + BlockState getBlock(int x, int y, int z) { + CachedChunk chunk = getCachedChunk(x, z); + return chunk.getBlock(x & 15, y, z & 15); + } + + BiomeType getBiome(int x, int z) { + CachedChunk chunk = getCachedChunk(x, z); + return chunk.getBiome(x, z); + } + + public void apply(Region region, MCAFilter filter) { // TODO not MCAFilter, but another similar class + // TODO iterate by mca file + Set chunks = region.getChunks(); + Iterator chunksIter = chunks.iterator(); + ForkJoinPool pool = TaskManager.IMP.getPublicForkJoinPool(); + for (int i = 0; i < Runtime.getRuntime().availableProcessors(); i++) { + pool.submit(new Runnable() { + @Override + public void run() { + while (true) { + BlockVector2 pos; + synchronized (chunksIter) { + if (!chunksIter.hasNext()) return; + pos = chunksIter.next(); + } + int cx = pos.getX(); + int cz = pos.getZ(); + CachedChunk chunk = getCachedChunk(cx, cz); + try { + if (!filter.appliesChunk(cx, cz)) { + continue; + } + T value = filter.get(); + chunk = filter.applyChunk(chunk, value); + + if (chunk == null) continue; + + // TODO if region contains all parts + chunk.filter(filter); + // else + chunk.filter(region, filter); + } finally { + // TODO submit chunk + } + } + } + }); + } + } +} \ No newline at end of file diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/beta/holder/ChunkHolder.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/beta/holder/ChunkHolder.java new file mode 100644 index 000000000..cba2c2e3a --- /dev/null +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/beta/holder/ChunkHolder.java @@ -0,0 +1,13 @@ +package com.boydti.fawe.bukkit.v1_13.beta.holder; + +import com.boydti.fawe.bukkit.v1_13.beta.IChunk; + +public class ChunkHolder implements IChunk { + private ChunkHolder implementation; + + public ChunkHolder() { + + } + + public ChunkHolder(IChunkH) +} diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/beta/holder/SetChunk.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/beta/holder/SetChunk.java new file mode 100644 index 000000000..6d58ef8c4 --- /dev/null +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/beta/holder/SetChunk.java @@ -0,0 +1,7 @@ +package com.boydti.fawe.bukkit.v1_13.beta.holder; + +import com.boydti.fawe.bukkit.v1_13.beta.IChunk; + +public class SetChunk extends ChunkHolder { + +} diff --git a/worldedit-core/src/main/java/com/boydti/fawe/config/Settings.java b/worldedit-core/src/main/java/com/boydti/fawe/config/Settings.java index f66b12a69..cedb96acf 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/config/Settings.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/config/Settings.java @@ -257,8 +257,8 @@ public class Settings extends Config { public static class QUEUE { @Comment({ "This should equal the number of processors you have", - " - Set this to 1 if you need reliable `/timings`" }) + @Final public int PARALLEL_THREADS = Math.max(1, Runtime.getRuntime().availableProcessors()); @Create public static PROGRESS PROGRESS; diff --git a/worldedit-core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAChunk.java b/worldedit-core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAChunk.java index 3e4f4262d..c382792e7 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAChunk.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/jnbt/anvil/MCAChunk.java @@ -78,9 +78,6 @@ public class MCAChunk extends FaweChunk { } public void write(NBTOutputStream nbtOut) throws IOException { - - - nbtOut.writeNamedTagName("", NBTConstants.TYPE_COMPOUND); nbtOut.writeLazyCompoundTag("Level", out -> { out.writeNamedTag("V", (byte) 1);