cache = value.get();
+ if (cache.trim(aggressive)) {
iter.remove();
continue;
}
diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/SingleThreadQueueExtent.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/SingleThreadQueueExtent.java
index 31d2946b4..0622f26c9 100644
--- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/SingleThreadQueueExtent.java
+++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/SingleThreadQueueExtent.java
@@ -1,41 +1,49 @@
package com.boydti.fawe.beta.implementation;
-import static com.google.common.base.Preconditions.checkNotNull;
-
import com.boydti.fawe.Fawe;
import com.boydti.fawe.beta.IChunk;
import com.boydti.fawe.beta.IChunkGet;
+import com.boydti.fawe.beta.IChunkSet;
import com.boydti.fawe.beta.IQueueExtent;
+import com.boydti.fawe.beta.implementation.blocks.CharSetBlocks;
+import com.boydti.fawe.beta.implementation.holder.ChunkHolder;
import com.boydti.fawe.beta.implementation.holder.ReferenceChunk;
import com.boydti.fawe.config.Settings;
import com.boydti.fawe.util.MathMan;
import com.boydti.fawe.util.MemUtil;
import com.google.common.util.concurrent.Futures;
+import com.sk89q.worldedit.extent.Extent;
import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap;
+
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
-import java.util.function.Supplier;
/**
* Single threaded implementation for IQueueExtent (still abstract) - Does not implement creation of
* chunks (that has to implemented by the platform e.g. Bukkit)
*
- * This queue is reusable {@link #init(WorldChunkCache)}
+ * This queue is reusable {@link #init(IChunkCache)}
*/
public abstract class SingleThreadQueueExtent implements IQueueExtent {
- // Pool discarded chunks for reuse (can safely be cleared by another thread)
- private static final ConcurrentLinkedQueue CHUNK_POOL = new ConcurrentLinkedQueue<>();
+// // Pool discarded chunks for reuse (can safely be cleared by another thread)
+// private static final ConcurrentLinkedQueue CHUNK_POOL = new ConcurrentLinkedQueue<>();
// Chunks currently being queued / worked on
private final Long2ObjectLinkedOpenHashMap chunks = new Long2ObjectLinkedOpenHashMap<>();
- private WorldChunkCache cache;
+
+ private IChunkCache cacheGet;
+ private IChunkCache cacheSet;
+ private boolean initialized;
+
private Thread currentThread;
private ConcurrentLinkedQueue submissions = new ConcurrentLinkedQueue<>();
// Last access pointers
private IChunk lastChunk;
private long lastPair = Long.MAX_VALUE;
+ private boolean enabledQueue = true;
+
/**
* Safety check to ensure that the thread being used matches the one being initialized on. - Can
* be removed later
@@ -48,23 +56,42 @@ public abstract class SingleThreadQueueExtent implements IQueueExtent {
}
@Override
- public IChunkGet getCachedGet(int x, int z, Supplier supplier) {
- return cache.get(MathMan.pairInt(x, z), supplier);
+ public void enableQueue() {
+ enabledQueue = true;
+ }
+
+ @Override
+ public void disableQueue() {
+ enabledQueue = false;
+ }
+
+ @Override
+ public IChunkGet getCachedGet(int x, int z) {
+ return cacheGet.get(x, z);
+ }
+
+ @Override
+ public IChunkSet getCachedSet(int x, int z) {
+ return cacheSet.get(x, z);
}
/**
* Resets the queue.
*/
protected synchronized void reset() {
+ if (!initialized) return;
checkThread();
- cache = null;
if (!chunks.isEmpty()) {
- CHUNK_POOL.addAll(chunks.values());
+ for (IChunk chunk : chunks.values()) {
+ chunk.recycle();
+ }
chunks.clear();
}
+ enabledQueue = true;
lastChunk = null;
lastPair = Long.MAX_VALUE;
currentThread = null;
+ initialized = false;
}
/**
@@ -73,17 +100,18 @@ public abstract class SingleThreadQueueExtent implements IQueueExtent {
* @param cache
*/
@Override
- public synchronized void init(WorldChunkCache cache) {
- if (this.cache != null) {
- reset();
- }
+ public synchronized void init(Extent extent, IChunkCache get, IChunkCache set) {
+ reset();
currentThread = Thread.currentThread();
- checkNotNull(cache);
- this.cache = cache;
- }
-
- public void returnToPool(IChunk chunk) {
- CHUNK_POOL.add(chunk);
+ if (get == null) {
+ get = (x, z) -> { throw new UnsupportedOperationException(); };
+ }
+ if (set == null) {
+ set = (x, z) -> CharSetBlocks.newInstance();
+ }
+ this.cacheGet = get;
+ this.cacheSet = set;
+ initialized = true;
}
@Override
@@ -116,8 +144,9 @@ public abstract class SingleThreadQueueExtent implements IQueueExtent {
*/
private > T submitUnchecked(IChunk chunk) {
if (chunk.isEmpty()) {
- CHUNK_POOL.add(chunk);
- return (T) (Future) Futures.immediateFuture(null);
+ chunk.recycle();
+ Future result = Futures.immediateFuture(null);
+ return (T) result;
}
if (Fawe.isMainThread()) {
@@ -130,7 +159,8 @@ public abstract class SingleThreadQueueExtent implements IQueueExtent {
@Override
public synchronized boolean trim(boolean aggressive) {
// TODO trim individial chunk sections
- CHUNK_POOL.clear();
+ cacheGet.trim(aggressive);
+ cacheSet.trim(aggressive);
if (Thread.currentThread() == currentThread) {
lastChunk = null;
lastPair = Long.MAX_VALUE;
@@ -157,10 +187,7 @@ public abstract class SingleThreadQueueExtent implements IQueueExtent {
* @return IChunk
*/
private IChunk poolOrCreate(int X, int Z) {
- IChunk next = CHUNK_POOL.poll();
- if (next == null) {
- next = create(false);
- }
+ IChunk next = create(false);
next.init(this, X, Z);
return next;
}
@@ -187,7 +214,7 @@ public abstract class SingleThreadQueueExtent implements IQueueExtent {
checkThread();
final int size = chunks.size();
final boolean lowMem = MemUtil.isMemoryLimited();
- if (lowMem || size > Settings.IMP.QUEUE.TARGET_SIZE) {
+ if (enabledQueue && (lowMem || size > Settings.IMP.QUEUE.TARGET_SIZE)) {
chunk = chunks.removeFirst();
final Future future = submitUnchecked(chunk);
if (future != null && !future.isDone()) {
@@ -211,6 +238,11 @@ public abstract class SingleThreadQueueExtent implements IQueueExtent {
return chunk;
}
+ @Override
+ public IChunk create(boolean isFull) {
+ return ChunkHolder.newInstance();
+ }
+
private void pollSubmissions(int targetSize, boolean aggressive) {
final int overflow = submissions.size() - targetSize;
if (aggressive) {
diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/BitSetBlocks.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/BitSetBlocks.java
index 74498610a..02642433f 100644
--- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/BitSetBlocks.java
+++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/BitSetBlocks.java
@@ -63,7 +63,7 @@ public class BitSetBlocks implements IChunkSet {
@Override
public char[] getArray(int layer) {
- char[] arr = FaweCache.SECTION_BITS_TO_CHAR.get();
+ char[] arr = FaweCache.IMP.SECTION_BITS_TO_CHAR.get();
MemBlockSet.IRow nullRowY = row.getRow(layer);
if (nullRowY instanceof MemBlockSet.RowY) {
char value = blockState.getOrdinalChar();
diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharGetBlocks.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharGetBlocks.java
index 84b857470..2f3dfd368 100644
--- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharGetBlocks.java
+++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharGetBlocks.java
@@ -6,6 +6,8 @@ import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockTypes;
+import java.util.concurrent.Future;
+
public abstract class CharGetBlocks extends CharBlocks implements IChunkGet {
@Override
diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharSetBlocks.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharSetBlocks.java
index aff10f536..ee71ccf56 100644
--- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharSetBlocks.java
+++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/blocks/CharSetBlocks.java
@@ -1,6 +1,8 @@
package com.boydti.fawe.beta.implementation.blocks;
+import com.boydti.fawe.FaweCache;
import com.boydti.fawe.beta.IChunkSet;
+import com.boydti.fawe.config.Settings;
import com.boydti.fawe.util.MathMan;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.world.biome.BiomeType;
@@ -14,21 +16,21 @@ import java.util.Set;
import java.util.UUID;
public class CharSetBlocks extends CharBlocks implements IChunkSet {
+ private static FaweCache.Pool POOL = FaweCache.IMP.registerPool(CharSetBlocks.class, CharSetBlocks::new, Settings.IMP.QUEUE.POOL);
+ public static CharSetBlocks newInstance() {
+ return POOL.poll();
+ }
public BiomeType[] biomes;
public HashMap tiles;
public HashSet entities;
public HashSet entityRemoves;
- public CharSetBlocks(CharBlocks other) {
- super(other);
- if (other instanceof CharSetBlocks) {
-
- }
- }
-
- public CharSetBlocks() {
+ private CharSetBlocks() {}
+ @Override
+ public void recycle() {
+ POOL.offer(this);
}
@Override
diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/holder/ChunkHolder.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/holder/ChunkHolder.java
index a8a08c5d4..d47808dd2 100644
--- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/holder/ChunkHolder.java
+++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/holder/ChunkHolder.java
@@ -1,5 +1,6 @@
package com.boydti.fawe.beta.implementation.holder;
+import com.boydti.fawe.FaweCache;
import com.boydti.fawe.beta.ChunkFilterBlock;
import com.boydti.fawe.beta.Filter;
import com.boydti.fawe.beta.FilterBlockMask;
@@ -10,19 +11,67 @@ import com.boydti.fawe.beta.IChunkSet;
import com.boydti.fawe.beta.IQueueExtent;
import com.boydti.fawe.beta.implementation.SingleThreadQueueExtent;
import com.boydti.fawe.beta.implementation.blocks.CharSetBlocks;
+import com.boydti.fawe.config.Settings;
import com.sk89q.jnbt.CompoundTag;
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 java.util.concurrent.Future;
import java.util.function.Supplier;
import javax.annotation.Nullable;
/**
* An abstract {@link IChunk} class that implements basic get/set blocks
*/
-public abstract class ChunkHolder implements IChunk {
+public class ChunkHolder> implements IChunk {
+
+ private static FaweCache.Pool POOL = FaweCache.IMP.registerPool(ChunkHolder.class, ChunkHolder::new, Settings.IMP.QUEUE.POOL);
+
+ public static ChunkHolder newInstance() {
+ return POOL.poll();
+ }
+
+ private IChunkGet get;
+ private IChunkSet set;
+ private IBlockDelegate delegate;
+ private IQueueExtent extent;
+ private int chunkX;
+ private int chunkZ;
+
+ public ChunkHolder() {
+ this.delegate = NULL;
+ }
+
+ public void init(IBlockDelegate delegate) {
+ this.delegate = delegate;
+ }
+
+ @Override
+ public void recycle() {
+ delegate = NULL;
+ }
+
+ public IBlockDelegate getDelegate() {
+ return delegate;
+ }
+
+ @Override
+ public IQueueExtent getQueue() {
+ return extent;
+ }
+
+ @Override
+ public boolean setTile(int x, int y, int z, CompoundTag tag) {
+ return false;
+ }
+
+ @Override
+ public char[] load(int layer) {
+ return getOrCreateGet().load(layer);
+ }
public static final IBlockDelegate BOTH = new IBlockDelegate() {
@Override
@@ -160,20 +209,6 @@ public abstract class ChunkHolder implements IChunk {
return chunk.getFullBlock(x, y, z);
}
};
- private IChunkGet get;
- private IChunkSet set;
- private IBlockDelegate delegate;
- private IQueueExtent extent;
- private int chunkX;
- private int chunkZ;
-
- public ChunkHolder() {
- this.delegate = NULL;
- }
-
- public ChunkHolder(IBlockDelegate delegate) {
- this.delegate = delegate;
- }
@Override
public void flood(Flood flood, FilterBlockMask mask, ChunkFilterBlock block) {
@@ -264,14 +299,6 @@ public abstract class ChunkHolder implements IChunk {
return set;
}
- /**
- * Create the settable part of this chunk (defaults to a char array)
- * @return
- */
- public IChunkSet createSet() {
- return new CharSetBlocks();
- }
-
/**
* Create a wrapped set object
* - The purpose of wrapping is to allow different extents to intercept / alter behavior
@@ -279,13 +306,7 @@ public abstract class ChunkHolder implements IChunk {
* @return
*/
private IChunkSet newWrappedSet() {
- if (extent instanceof SingleThreadQueueExtent) {
- IChunkSet newSet = extent.getCachedSet(chunkX, chunkZ, this::createSet);
- if (newSet != null) {
- return newSet;
- }
- }
- return createSet();
+ return extent.getCachedSet(chunkX, chunkZ);
}
/**
@@ -295,17 +316,9 @@ public abstract class ChunkHolder implements IChunk {
* @return
*/
private IChunkGet newWrappedGet() {
- if (extent instanceof SingleThreadQueueExtent) {
- IChunkGet newGet = extent.getCachedGet(chunkX, chunkZ, this::get);
- if (newGet != null) {
- return newGet;
- }
- }
- return get();
+ return extent.getCachedGet(chunkX, chunkZ);
}
- public abstract IChunkGet get();
-
@Override
public void init(IQueueExtent extent, int chunkX, int chunkZ) {
this.extent = extent;
@@ -320,6 +333,22 @@ public abstract class ChunkHolder implements IChunk {
get = null;
}
+ @Override
+ public synchronized T call() {
+ if (get != null && set != null) {
+ return getOrCreateGet().call(getOrCreateSet(), this::recycle);
+ }
+ return null;
+ }
+
+ @Override
+ public T call(IChunkSet set, Runnable finalize) {
+ if (get != null && set != null) {
+ return getOrCreateGet().call(set, finalize);
+ }
+ return null;
+ }
+
public IQueueExtent getExtent() {
return extent;
}
diff --git a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/holder/DelegateChunk.java b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/holder/DelegateChunk.java
index 6c285b320..7a284df67 100644
--- a/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/holder/DelegateChunk.java
+++ b/worldedit-core/src/main/java/com/boydti/fawe/beta/implementation/holder/DelegateChunk.java
@@ -1,27 +1,29 @@
package com.boydti.fawe.beta.implementation.holder;
import com.boydti.fawe.beta.IChunk;
+import com.boydti.fawe.beta.IChunkSet;
import com.boydti.fawe.beta.IDelegateChunk;
+import com.sk89q.jnbt.CompoundTag;
+
+import java.util.concurrent.Future;
/**
* Implementation of IDelegateChunk
- *
- * @param
*/
-public class DelegateChunk implements IDelegateChunk {
+public class DelegateChunk implements IDelegateChunk {
- private T parent;
+ private U parent;
- public DelegateChunk(T parent) {
+ public DelegateChunk(U parent) {
this.parent = parent;
}
@Override
- public final T getParent() {
+ public final U getParent() {
return parent;
}
- public final void setParent(T parent) {
+ public final void setParent(U parent) {
this.parent = parent;
}
}
diff --git a/worldedit-core/src/main/java/com/boydti/fawe/command/AnvilCommands.java b/worldedit-core/src/main/java/com/boydti/fawe/command/AnvilCommands.java
index 4b9fb7110..0401419d5 100644
--- a/worldedit-core/src/main/java/com/boydti/fawe/command/AnvilCommands.java
+++ b/worldedit-core/src/main/java/com/boydti/fawe/command/AnvilCommands.java
@@ -475,7 +475,7 @@ public class AnvilCommands {
// });
// if (useData) {
// for (long[] c : map) {
-// BaseBlock block = FaweCache.CACHE_BLOCK[(int) c[0]];
+// BaseBlock block = FaweCache.IMP.CACHE_BLOCK[(int) c[0]];
// String name = BlockType.fromID(block.getId()).getName();
// String str = String.format("%-7s (%.3f%%) %s #%d:%d",
// String.valueOf(c[1]),
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 82229b7bd..18a9b5e59 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
@@ -293,7 +293,13 @@ public class Settings extends Config {
" - Low values may result in FAWE waiting on requests to the main thread",
" - Higher values use more memory and isn't noticeably faster",
})
- public int PRELOAD_CHUNKS = 32;
+ public int PRELOAD_CHUNKS = 100000;
+
+ @Comment({
+ "If pooling is enabled (reduces GC, higher memory usage)",
+ " - Enable to improve performance at the expense of memory",
+ })
+ public boolean POOL = true;
@Comment({
"Discard edits which have been idle for a certain amount of time (ms)",
diff --git a/worldedit-core/src/main/java/com/boydti/fawe/logging/LoggingChangeSet.java b/worldedit-core/src/main/java/com/boydti/fawe/logging/LoggingChangeSet.java
index 8ac50bbde..76809abb3 100644
--- a/worldedit-core/src/main/java/com/boydti/fawe/logging/LoggingChangeSet.java
+++ b/worldedit-core/src/main/java/com/boydti/fawe/logging/LoggingChangeSet.java
@@ -58,10 +58,10 @@ public class LoggingChangeSet extends AbstractDelegateChangeSet {
// loc.x = x;
// loc.y = y;
// loc.z = z;
-// oldBlock.id = FaweCache.getId(combinedId4DataFrom);
-// oldBlock.data = FaweCache.getData(combinedId4DataFrom);
-// newBlock.id = FaweCache.getId(combinedId4DataTo);
-// newBlock.data = FaweCache.getData(combinedId4DataTo);
+// oldBlock.id = FaweCache.IMP.getId(combinedId4DataFrom);
+// oldBlock.data = FaweCache.IMP.getData(combinedId4DataFrom);
+// newBlock.id = FaweCache.IMP.getId(combinedId4DataTo);
+// newBlock.data = FaweCache.IMP.getData(combinedId4DataTo);
// // Log to BlocksHub and parent
// api.logBlock(loc, player, world, oldBlock, newBlock);
parent.add(x, y, z, combinedId4DataFrom, combinedId4DataTo);
diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/brush/visualization/cfi/HeightMapMCAGenerator.java b/worldedit-core/src/main/java/com/boydti/fawe/object/brush/visualization/cfi/HeightMapMCAGenerator.java
index 3d78a73fe..bb2c17763 100644
--- a/worldedit-core/src/main/java/com/boydti/fawe/object/brush/visualization/cfi/HeightMapMCAGenerator.java
+++ b/worldedit-core/src/main/java/com/boydti/fawe/object/brush/visualization/cfi/HeightMapMCAGenerator.java
@@ -1,7 +1,12 @@
package com.boydti.fawe.object.brush.visualization.cfi;
import com.boydti.fawe.Fawe;
+import com.boydti.fawe.FaweCache;
+import com.boydti.fawe.beta.IBlocks;
+import com.boydti.fawe.beta.IChunkGet;
+import com.boydti.fawe.beta.IChunkSet;
import com.boydti.fawe.beta.IQueueExtent;
+import com.boydti.fawe.beta.implementation.FallbackChunkGet;
import com.boydti.fawe.object.FaweInputStream;
import com.boydti.fawe.object.FaweOutputStream;
import com.boydti.fawe.object.FawePlayer;
@@ -44,6 +49,7 @@ import com.sk89q.worldedit.session.ClipboardHolder;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.biome.BiomeTypes;
+import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockID;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
@@ -58,6 +64,7 @@ import java.nio.file.Path;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
+import java.util.concurrent.Future;
import java.util.concurrent.ThreadLocalRandom;
import javax.annotation.Nullable;
@@ -65,13 +72,6 @@ import javax.annotation.Nullable;
public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Drawable, VirtualWorld {
private final MutableBlockVector3 mutable = new MutableBlockVector3();
- private final ThreadLocal indexStore = new ThreadLocal() {
- @Override
- protected int[] initialValue() {
- return new int[256];
- }
- };
-
private final DifferentialBlockBuffer blocks;
protected final DifferentialArray heights;
protected final DifferentialArray biomes;
@@ -1571,7 +1571,7 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
int[] floor = this.floor.get();
int[] overlay = this.overlay != null ? this.overlay.get() : null;
try {
- int[] indexes = indexStore.get();
+ int[] indexes = FaweCache.IMP.INDEX_STORE.get();
int index;
int maxY = 0;
@@ -1902,12 +1902,6 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
}));
}
- @Override
- protected void finalize() throws Throwable {
- IterableThreadLocal.clean(indexStore);
- super.finalize();
- }
-
@Override
public int getMaxY() {
return 255;
@@ -1973,4 +1967,10 @@ public class HeightMapMCAGenerator extends MCAWriter implements StreamChange, Dr
// TODO Auto-generated method stub
return null;
}
+
+ @Override
+ public IChunkGet get(int x, int z) {
+ Fawe.debug("Should not be using buffering with HMMG");
+ return new FallbackChunkGet(this, x, z);
+ }
}
diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/brush/visualization/cfi/WritableMCAChunk.java b/worldedit-core/src/main/java/com/boydti/fawe/object/brush/visualization/cfi/WritableMCAChunk.java
index 6f681bd90..fbe06d76c 100644
--- a/worldedit-core/src/main/java/com/boydti/fawe/object/brush/visualization/cfi/WritableMCAChunk.java
+++ b/worldedit-core/src/main/java/com/boydti/fawe/object/brush/visualization/cfi/WritableMCAChunk.java
@@ -79,10 +79,10 @@ public class WritableMCAChunk {
}
public void write(NBTOutputStream nbtOut) throws IOException {
- int[] blockToPalette = FaweCache.BLOCK_TO_PALETTE.get();
- int[] paletteToBlock = FaweCache.PALETTE_TO_BLOCK.get();
- long[] blockstates = FaweCache.BLOCK_STATES.get();
- int[] blocksCopy = FaweCache.SECTION_BLOCKS.get();
+ int[] blockToPalette = FaweCache.IMP.BLOCK_TO_PALETTE.get();
+ int[] paletteToBlock = FaweCache.IMP.PALETTE_TO_BLOCK.get();
+ long[] blockstates = FaweCache.IMP.BLOCK_STATES.get();
+ int[] blocksCopy = FaweCache.IMP.SECTION_BLOCKS.get();
nbtOut.writeNamedTagName("", NBTConstants.TYPE_COMPOUND);
nbtOut.writeNamedTag("DataVersion", 1631);
diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/FaweChangeSet.java b/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/FaweChangeSet.java
index 6b4b3995f..dc0d27592 100644
--- a/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/FaweChangeSet.java
+++ b/worldedit-core/src/main/java/com/boydti/fawe/object/changeset/FaweChangeSet.java
@@ -52,7 +52,7 @@ public abstract class FaweChangeSet implements ChangeSet {
public FaweChangeSet(String world) {
this.worldName = world;
this.mainThread = Fawe.get() == null || Fawe.isMainThread();
- this.layers = FaweCache.CHUNK_LAYERS;
+ this.layers = FaweCache.IMP.CHUNK_LAYERS;
}
public FaweChangeSet(World world) {
diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/remap/ClipboardRemapper.java b/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/remap/ClipboardRemapper.java
index df9d21db7..e2c00c8e5 100644
--- a/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/remap/ClipboardRemapper.java
+++ b/worldedit-core/src/main/java/com/boydti/fawe/object/clipboard/remap/ClipboardRemapper.java
@@ -223,7 +223,7 @@ public class ClipboardRemapper {
// String name = entry.getKey();
// int id = value.get("id").getAsInt();
// int data = value.get("data").getAsInt();
-// int combined = FaweCache.getCombined(id, data);
+// int combined = FaweCache.IMP.getCombined(id, data);
// map.putIfAbsent(name, new ArrayList<>());
// map.get(name).add(combined);
// }
@@ -496,7 +496,7 @@ public class ClipboardRemapper {
// int combined = block.getCombined();
// if (remap[combined]) {
// char value = remapCombined[combined];
-// BaseBlock newBlock = FaweCache.CACHE_BLOCK[value];
+// BaseBlock newBlock = FaweCache.IMP.CACHE_BLOCK[value];
// newBlock.setNbtData(block.getNbtData());
// return newBlock;
// }
diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/collection/IterableThreadLocal.java b/worldedit-core/src/main/java/com/boydti/fawe/object/collection/IterableThreadLocal.java
index 2aef7daf7..eaa4fe297 100644
--- a/worldedit-core/src/main/java/com/boydti/fawe/object/collection/IterableThreadLocal.java
+++ b/worldedit-core/src/main/java/com/boydti/fawe/object/collection/IterableThreadLocal.java
@@ -1,5 +1,6 @@
package com.boydti.fawe.object.collection;
+import com.boydti.fawe.util.IOUtil;
import com.boydti.fawe.util.MainUtil;
import java.lang.ref.Reference;
import java.lang.reflect.Array;
@@ -8,12 +9,27 @@ import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
+import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentLinkedDeque;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.IntFunction;
+import java.util.function.Supplier;
-public abstract class IterableThreadLocal extends ThreadLocal implements Iterable {
+public class IterableThreadLocal extends ThreadLocal implements Iterable {
private final ConcurrentLinkedDeque allValues = new ConcurrentLinkedDeque<>();
+ private final Supplier supplier;
- public IterableThreadLocal() {
+ public IterableThreadLocal(Supplier supplier) {
+ this.supplier = supplier;
+ }
+
+ public IterableThreadLocal(Supplier supplier, Function modifier) {
+ this.supplier = supplier;
+ }
+
+ public IterableThreadLocal(Supplier supplier, Consumer modifier) {
+ this.supplier = supplier;
}
@Override
@@ -33,7 +49,7 @@ public abstract class IterableThreadLocal extends ThreadLocal implements I
}
public T init() {
- return null;
+ return supplier.get();
}
public void clean() {
diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/collection/MemBlockSet.java b/worldedit-core/src/main/java/com/boydti/fawe/object/collection/MemBlockSet.java
index bb7418ee0..b9ae7a46e 100644
--- a/worldedit-core/src/main/java/com/boydti/fawe/object/collection/MemBlockSet.java
+++ b/worldedit-core/src/main/java/com/boydti/fawe/object/collection/MemBlockSet.java
@@ -20,7 +20,7 @@ import org.jetbrains.annotations.NotNull;
*/
public final class MemBlockSet extends BlockSet {
public final static int BITS_PER_WORD = 6;
- public final static int WORDS = FaweCache.BLOCKS_PER_LAYER >> BITS_PER_WORD;
+ public final static int WORDS = FaweCache.IMP.BLOCKS_PER_LAYER >> BITS_PER_WORD;
public final static IRow NULL_ROW_X = new NullRowX();
public final static IRow NULL_ROW_Z = new NullRowZ();
public final static IRow NULL_ROW_Y = new NullRowY();
@@ -354,7 +354,7 @@ public final class MemBlockSet extends BlockSet {
maxy = y + 1;
}
by = (Y << 4) + y;
- if (by == FaweCache.WORLD_MAX_Y) return FaweCache.WORLD_MAX_Y;
+ if (by == FaweCache.IMP.WORLD_MAX_Y) return FaweCache.IMP.WORLD_MAX_Y;
break outer;
}
}
@@ -823,7 +823,7 @@ public final class MemBlockSet extends BlockSet {
private final IRow[] rows;
public RowZ() {
- this.rows = new IRow[FaweCache.CHUNK_LAYERS];
+ this.rows = new IRow[FaweCache.IMP.CHUNK_LAYERS];
reset();
}
@@ -866,7 +866,7 @@ public final class MemBlockSet extends BlockSet {
}
public void reset() {
- for (int i = 0; i < FaweCache.CHUNK_LAYERS; i++) rows[i] = NULL_ROW_Y;
+ for (int i = 0; i < FaweCache.IMP.CHUNK_LAYERS; i++) rows[i] = NULL_ROW_Y;
}
}
diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/mask/FaweBlockMatcher.java b/worldedit-core/src/main/java/com/boydti/fawe/object/mask/FaweBlockMatcher.java
index 421e3c133..84f3e7aca 100644
--- a/worldedit-core/src/main/java/com/boydti/fawe/object/mask/FaweBlockMatcher.java
+++ b/worldedit-core/src/main/java/com/boydti/fawe/object/mask/FaweBlockMatcher.java
@@ -31,10 +31,10 @@ public abstract class FaweBlockMatcher {
// public boolean apply(BaseBlock oldBlock) {
// int currentId = oldBlock.getId();
// oldBlock.setId(id);
-// if (FaweCache.hasData(currentId)) {
+// if (FaweCache.IMP.hasData(currentId)) {
// oldBlock.setData(0);
// }
-// if (FaweCache.hasNBT(currentId)) {
+// if (FaweCache.IMP.hasNBT(currentId)) {
// oldBlock.setNbtData(null);
// }
// return true;
@@ -47,7 +47,7 @@ public abstract class FaweBlockMatcher {
// int currentId = oldBlock.getId();
// oldBlock.setId(id);
// oldBlock.setData(data);
-// if (FaweCache.hasNBT(currentId)) {
+// if (FaweCache.IMP.hasNBT(currentId)) {
// oldBlock.setNbtData(null);
// }
// return true;
@@ -67,10 +67,10 @@ public abstract class FaweBlockMatcher {
// BaseBlock replace = array[random.random(size)];
// int currentId = block.getId();
// block.setId(replace.getId());
-// if (FaweCache.hasNBT(currentId)) {
+// if (FaweCache.IMP.hasNBT(currentId)) {
// block.setNbtData(null);
// }
-// if (FaweCache.hasData(currentId) || replace.getData() != 0) {
+// if (FaweCache.IMP.hasData(currentId) || replace.getData() != 0) {
// block.setData(replace.getData());
// }
// return true;
@@ -82,7 +82,7 @@ public abstract class FaweBlockMatcher {
public static FaweBlockMatcher fromBlock(BaseBlock block, boolean checkData) {
// final int id = block.getId();
// final int data = block.getData();
-// if (checkData && FaweCache.hasData(id)) {
+// if (checkData && FaweCache.IMP.hasData(id)) {
// return new FaweBlockMatcher() {
// @Override
// public boolean apply(BaseBlock block) {
@@ -104,13 +104,13 @@ public abstract class FaweBlockMatcher {
// if (searchBlocks.size() == 1) {
// return fromBlock(searchBlocks.iterator().next(), checkData);
// }
-// final boolean[] allowedId = new boolean[FaweCache.getId(Character.MAX_VALUE)];
+// final boolean[] allowedId = new boolean[FaweCache.IMP.getId(Character.MAX_VALUE)];
// for (BaseBlock block : searchBlocks) {
// allowedId[block.getId()] = true;
// }
// final boolean[] allowed = new boolean[Character.MAX_VALUE];
// for (BaseBlock block : searchBlocks) {
-// allowed[FaweCache.getCombined(block)] = true;
+// allowed[FaweCache.IMP.getCombined(block)] = true;
// }
// if (checkData) {
// return new FaweBlockMatcher() {
@@ -118,7 +118,7 @@ public abstract class FaweBlockMatcher {
// public boolean apply(BaseBlock block) {
// int id = block.getId();
// if (allowedId[id]) {
-// if (FaweCache.hasData(id)) {
+// if (FaweCache.IMP.hasData(id)) {
// return allowed[(id << 4) + block.getData()];
// }
// return true;
diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/regions/selector/FuzzyRegionSelector.java b/worldedit-core/src/main/java/com/boydti/fawe/object/regions/selector/FuzzyRegionSelector.java
index c373441b4..5b1847e26 100644
--- a/worldedit-core/src/main/java/com/boydti/fawe/object/regions/selector/FuzzyRegionSelector.java
+++ b/worldedit-core/src/main/java/com/boydti/fawe/object/regions/selector/FuzzyRegionSelector.java
@@ -36,7 +36,7 @@ public class FuzzyRegionSelector extends PassthroughExtent implements RegionSele
.player(FawePlayer.wrap(player))
.changeSetNull()
.checkMemory(false)
- .autoQueue(true)
+ .autoQueue(false)
.build());
this.player = player;
this.region = new FuzzyRegion(world, getExtent(), mask);
diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/schematic/MinecraftStructure.java b/worldedit-core/src/main/java/com/boydti/fawe/object/schematic/MinecraftStructure.java
index 70cdc7498..9bd1f5bc4 100644
--- a/worldedit-core/src/main/java/com/boydti/fawe/object/schematic/MinecraftStructure.java
+++ b/worldedit-core/src/main/java/com/boydti/fawe/object/schematic/MinecraftStructure.java
@@ -161,7 +161,7 @@ public class MinecraftStructure implements ClipboardReader, ClipboardWriter {
if (width > WARN_SIZE || height > WARN_SIZE || length > WARN_SIZE) {
Fawe.debug("A structure longer than 32 is unsupported by minecraft (but probably still works)");
}
- Map structure = FaweCache.asMap("version", 1, "author", owner);
+ Map structure = FaweCache.IMP.asMap("version", 1, "author", owner);
// ignored: version / owner
MutableBlockVector3 mutable = new MutableBlockVector3(0, 0, 0);
Int2ObjectArrayMap indexes = new Int2ObjectArrayMap<>();
@@ -211,10 +211,10 @@ public class MinecraftStructure implements ClipboardReader, ClipboardWriter {
List pos = Arrays.asList(point.getX() - min.getX(),
point.getY() - min.getY(), point.getZ() - min.getZ());
if (!block.hasNbtData()) {
- blocks.add(FaweCache.asMap("state", index, "pos", pos));
+ blocks.add(FaweCache.IMP.asMap("state", index, "pos", pos));
} else {
blocks.add(
- FaweCache.asMap("state", index, "pos", pos, "nbt", block.getNbtData()));
+ FaweCache.IMP.asMap("state", index, "pos", pos, "nbt", block.getNbtData()));
}
}
}
@@ -234,14 +234,14 @@ public class MinecraftStructure implements ClipboardReader, ClipboardWriter {
// Replace rotation data
nbtMap.put("Rotation", writeRotation(entity.getLocation()));
nbtMap.put("id", new StringTag(state.getType().getId()));
- Map entityMap = FaweCache.asMap("pos", pos, "blockPos", blockPos, "nbt", nbt);
+ Map entityMap = FaweCache.IMP.asMap("pos", pos, "blockPos", blockPos, "nbt", nbt);
entities.add(entityMap);
}
}
if (!entities.isEmpty()) {
structure.put("entities", entities);
}
- out.writeNamedTag("", FaweCache.asTag(structure));
+ out.writeNamedTag("", FaweCache.IMP.asTag(structure));
close();
}
diff --git a/worldedit-core/src/main/java/com/boydti/fawe/regions/general/plot/FaweLocalBlockQueue.java b/worldedit-core/src/main/java/com/boydti/fawe/regions/general/plot/FaweLocalBlockQueue.java
index ea5cb6080..e248035d3 100644
--- a/worldedit-core/src/main/java/com/boydti/fawe/regions/general/plot/FaweLocalBlockQueue.java
+++ b/worldedit-core/src/main/java/com/boydti/fawe/regions/general/plot/FaweLocalBlockQueue.java
@@ -25,10 +25,11 @@ public class FaweLocalBlockQueue extends LocalBlockQueue {
public final IQueueExtent IMP;
private final LegacyMapper legacyMapper;
+ private final World world;
public FaweLocalBlockQueue(String worldName) {
super(worldName);
- World world = FaweAPI.getWorld(worldName);
+ this.world = FaweAPI.getWorld(worldName);
IMP = Fawe.get().getQueueHandler().getQueue(world);
legacyMapper = LegacyMapper.getInstance();
}
@@ -104,7 +105,7 @@ public class FaweLocalBlockQueue extends LocalBlockQueue {
@Override
public String getWorld() {
- return IMP.getId();
+ return world.getId();
}
@Override
@@ -134,7 +135,7 @@ public class FaweLocalBlockQueue extends LocalBlockQueue {
@Override
public boolean setTile(int x, int y, int z, CompoundTag tag) {
- IMP.setTile(x, y, z, (com.sk89q.jnbt.CompoundTag) FaweCache.asTag(tag));
+ IMP.setTile(x, y, z, (com.sk89q.jnbt.CompoundTag) FaweCache.IMP.asTag(tag));
return true;
}
}
diff --git a/worldedit-core/src/main/java/com/boydti/fawe/regions/general/plot/FaweSchematicHandler.java b/worldedit-core/src/main/java/com/boydti/fawe/regions/general/plot/FaweSchematicHandler.java
index ac39c26ea..5fff70a1e 100644
--- a/worldedit-core/src/main/java/com/boydti/fawe/regions/general/plot/FaweSchematicHandler.java
+++ b/worldedit-core/src/main/java/com/boydti/fawe/regions/general/plot/FaweSchematicHandler.java
@@ -116,7 +116,7 @@ public class FaweSchematicHandler extends SchematicHandler {
public void run(OutputStream output) {
try {
try (PGZIPOutputStream gzip = new PGZIPOutputStream(output)) {
- CompoundTag weTag = (CompoundTag) FaweCache.asTag(tag);
+ CompoundTag weTag = (CompoundTag) FaweCache.IMP.asTag(tag);
try (NBTOutputStream nos = new NBTOutputStream(gzip)) {
Map map = weTag.getValue();
nos.writeNamedTag("Schematic", map.getOrDefault("Schematic", weTag));
diff --git a/worldedit-core/src/main/java/com/boydti/fawe/util/BrushCache.java b/worldedit-core/src/main/java/com/boydti/fawe/util/BrushCache.java
index 7a75d4876..4d5e7ffba 100644
--- a/worldedit-core/src/main/java/com/boydti/fawe/util/BrushCache.java
+++ b/worldedit-core/src/main/java/com/boydti/fawe/util/BrushCache.java
@@ -93,7 +93,7 @@ public final class BrushCache {
} else {
displayMap = ReflectionUtils.getMap(display.getValue());
}
- displayMap.put("Lore", FaweCache.asTag(json.split("\\r?\\n")));
+ displayMap.put("Lore", FaweCache.IMP.asTag(json.split("\\r?\\n")));
String primary = (String) tool.getPrimary().getSettings().get(BrushSettings.SettingType.BRUSH);
String secondary = (String) tool.getSecondary().getSettings().get(BrushSettings.SettingType.BRUSH);
if (primary == null) primary = secondary;
diff --git a/worldedit-core/src/main/java/com/boydti/fawe/util/IOUtil.java b/worldedit-core/src/main/java/com/boydti/fawe/util/IOUtil.java
index 7317b703d..8430a9720 100644
--- a/worldedit-core/src/main/java/com/boydti/fawe/util/IOUtil.java
+++ b/worldedit-core/src/main/java/com/boydti/fawe/util/IOUtil.java
@@ -5,6 +5,11 @@ import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.util.concurrent.Callable;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.IntFunction;
+import java.util.function.Supplier;
public final class IOUtil {
@@ -79,4 +84,30 @@ public final class IOUtil {
out.write(buf, 0, r);
}
}
+
+ public static Supplier supplier(IntFunction funx, int size) {
+ return () -> funx.apply(size);
+ }
+
+ public static Supplier supplier(Supplier supplier, Function modifier) {
+ return () -> modifier.apply(supplier.get());
+ }
+
+ public static Supplier supplier(Supplier supplier, Consumer modifier) {
+ return () -> {
+ T instance = supplier.get();
+ modifier.accept(instance);
+ return instance;
+ };
+ }
+
+ public static Supplier supplier(Callable callable) {
+ return () -> {
+ try {
+ return callable.call();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ };
+ }
}
diff --git a/worldedit-core/src/main/java/com/boydti/fawe/wrappers/WorldWrapper.java b/worldedit-core/src/main/java/com/boydti/fawe/wrappers/WorldWrapper.java
index 965e68ee9..839205736 100644
--- a/worldedit-core/src/main/java/com/boydti/fawe/wrappers/WorldWrapper.java
+++ b/worldedit-core/src/main/java/com/boydti/fawe/wrappers/WorldWrapper.java
@@ -1,6 +1,8 @@
package com.boydti.fawe.wrappers;
+import com.boydti.fawe.beta.IChunkGet;
import com.boydti.fawe.object.RunnableVal;
+import com.boydti.fawe.util.ExtentTraverser;
import com.boydti.fawe.util.TaskManager;
import com.sk89q.jnbt.CompoundTag;
@@ -12,6 +14,8 @@ import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extension.platform.Platform;
+import com.sk89q.worldedit.extent.AbstractDelegateExtent;
+import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.math.BlockVector2;
@@ -57,6 +61,18 @@ public class WorldWrapper extends AbstractWorld {
return world;
}
+ public static World unwrap(Extent extent) {
+ if (extent.isWorld()) {
+ if (extent instanceof World) {
+ return unwrap((World) extent);
+ }
+ if (extent instanceof AbstractDelegateExtent) {
+ return unwrap(new ExtentTraverser<>(extent).find(World.class).get());
+ }
+ }
+ return null;
+ }
+
private WorldWrapper(World parent) {
this.parent = parent;
}
@@ -267,4 +283,9 @@ public class WorldWrapper extends AbstractWorld {
public BlockVector3 getSpawnPosition() {
return parent.getSpawnPosition();
}
+
+ @Override
+ public IChunkGet get(int x, int z) {
+ return parent.get(x, z);
+ }
}
diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java
index 033c629cf..1c002059a 100644
--- a/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java
+++ b/worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java
@@ -164,7 +164,7 @@ import org.slf4j.LoggerFactory;
* using the {@link ChangeSetExtent}.
*/
@SuppressWarnings({"FieldCanBeLocal"})
-public class EditSession extends PassthroughExtent implements SimpleWorld, AutoCloseable {
+public class EditSession extends PassthroughExtent implements AutoCloseable {
private static final Logger log = LoggerFactory.getLogger(EditSession.class);
@@ -3023,33 +3023,10 @@ public class EditSession extends PassthroughExtent implements SimpleWorld, AutoC
Direction.DOWN.toBlockVector(),
};
-
- @Override
- public String getName() {
- return worldName;
- }
-
- @Override public @org.jetbrains.annotations.Nullable Path getStoragePath() {
- return null;
- }
-
- @Override
- public boolean clearContainerBlockContents(BlockVector3 pos) {
- BaseBlock block = getFullBlock(pos);
- CompoundTag nbt = block.getNbtData();
- if (nbt != null) {
- if (nbt.containsKey("items")) {
- return setBlock(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ(), block.toBlockState().toBaseBlock());
- }
- }
- return false;
- }
-
public boolean regenerate(final Region region) {
return regenerate(region, this);
}
- @Override
public boolean regenerate(final Region region, final EditSession session) {
return session.regenerate(region, null, null);
}
@@ -3164,69 +3141,4 @@ public class EditSession extends PassthroughExtent implements SimpleWorld, AutoC
}
return false;
}
-
- @Override
- public void simulateBlockMine(BlockVector3 position) {
- TaskManager.IMP.sync((Supplier