This commit is contained in:
MattBDev 2020-05-11 17:46:55 -04:00
commit 0848e68b9f
17 changed files with 111 additions and 38 deletions

View File

@ -12,7 +12,7 @@ import java.util.function.Function;
public class NMSAdapter {
public static int createPalette(int[] blockToPalette, int[] paletteToBlock, int[] blocksCopy,
int[] num_palette_buffer, char[] set, Map<BlockVector3, Integer> ticking_blocks) {
int[] num_palette_buffer, char[] set, Map<BlockVector3, Integer> ticking_blocks, boolean fastmode) {
int air = 0;
int num_palette = 0;
char lastOrdinal = BlockID.__RESERVED__;
@ -29,7 +29,7 @@ public class NMSAdapter {
air++;
break;
default:
if (!tick_placed) {
if (!fastmode && !tick_placed) {
boolean ticking;
if (ordinal != lastOrdinal) {
ticking = BlockTypesCache.ticking[ordinal];
@ -61,13 +61,14 @@ public class NMSAdapter {
public static int createPalette(int layer, int[] blockToPalette, int[] paletteToBlock,
int[] blocksCopy, int[] num_palette_buffer, Function<Integer, char[]> get, char[] set,
Map<BlockVector3, Integer> ticking_blocks) {
Map<BlockVector3, Integer> ticking_blocks, boolean fastmode) {
int air = 0;
int num_palette = 0;
char[] getArr = null;
char lastOrdinal = BlockID.__RESERVED__;
boolean lastticking = false;
boolean tick_placed = Settings.IMP.EXPERIMENTAL.ALLOW_TICK_PLACED;
boolean tick_existing = Settings.IMP.EXPERIMENTAL.ALLOW_TICK_EXISTING;
for (int i = 0; i < 4096; i++) {
char ordinal = set[i];
switch (ordinal) {
@ -85,7 +86,7 @@ public class NMSAdapter {
air++;
break;
default:
if (!tick_placed) {
if (!fastmode && !tick_placed && tick_existing) {
boolean ticking;
if (ordinal != lastOrdinal) {
ticking = BlockTypesCache.ticking[ordinal];
@ -112,7 +113,7 @@ public class NMSAdapter {
air++;
break;
}
if (tick_placed) {
if (!fastmode && tick_placed) {
boolean ticking;
if (ordinal != lastOrdinal) {
ticking = BlockTypesCache.ticking[ordinal];

View File

@ -199,11 +199,11 @@ public final class BukkitAdapter_1_14 extends NMSAdapter {
/*
NMS conversion
*/
public static ChunkSection newChunkSection(final int layer, final char[] blocks) {
return newChunkSection(layer, null, blocks);
public static ChunkSection newChunkSection(final int layer, final char[] blocks, boolean fastmode) {
return newChunkSection(layer, null, blocks, fastmode);
}
public static ChunkSection newChunkSection(final int layer, final Function<Integer, char[]> get, char[] set) {
public static ChunkSection newChunkSection(final int layer, final Function<Integer, char[]> get, char[] set, boolean fastmode) {
if (set == null) {
return newChunkSection(layer);
}
@ -216,9 +216,9 @@ public final class BukkitAdapter_1_14 extends NMSAdapter {
Map<BlockVector3, Integer> ticking_blocks = new HashMap<>();
int air;
if (get == null) {
air = createPalette(blockToPalette, paletteToBlock, blocksCopy, num_palette_buffer, set, ticking_blocks);
air = createPalette(blockToPalette, paletteToBlock, blocksCopy, num_palette_buffer, set, ticking_blocks, fastmode);
} else {
air = createPalette(layer, blockToPalette, paletteToBlock, blocksCopy, num_palette_buffer, get, set, ticking_blocks);
air = createPalette(layer, blockToPalette, paletteToBlock, blocksCopy, num_palette_buffer, get, set, ticking_blocks, fastmode);
}
int num_palette = num_palette_buffer[0];
// BlockStates

View File

@ -10,6 +10,7 @@ import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks;
import com.boydti.fawe.beta.implementation.queue.QueueHandler;
import com.boydti.fawe.bukkit.adapter.DelegateLock;
import com.boydti.fawe.bukkit.adapter.mc1_14.nbt.LazyCompoundTag_1_14;
import com.boydti.fawe.config.Settings;
import com.boydti.fawe.object.collection.AdaptedMap;
import com.boydti.fawe.object.collection.BitArray;
import com.google.common.base.Suppliers;
@ -228,6 +229,7 @@ public class BukkitGetBlocks_1_14 extends CharGetBlocks {
try {
WorldServer nmsWorld = world;
Chunk nmsChunk = ensureLoaded(nmsWorld, X, Z);
boolean fastmode = set.isFastMode() && Settings.IMP.QUEUE.NO_TICK_FASTMODE;
// Remove existing tiles
{
@ -263,7 +265,7 @@ public class BukkitGetBlocks_1_14 extends CharGetBlocks {
ChunkSection newSection;
ChunkSection existingSection = sections[layer];
if (existingSection == null) {
newSection = BukkitAdapter_1_14.newChunkSection(layer, setArr);
newSection = BukkitAdapter_1_14.newChunkSection(layer, setArr, fastmode);
if (BukkitAdapter_1_14.setSectionAtomic(sections, null, newSection, layer)) {
updateGet(this, nmsChunk, sections, newSection, setArr, layer);
continue;
@ -295,7 +297,7 @@ public class BukkitGetBlocks_1_14 extends CharGetBlocks {
} else if (lock.isModified()) {
this.reset(layer);
}
newSection = BukkitAdapter_1_14.newChunkSection(layer, this::load, setArr);
newSection = BukkitAdapter_1_14.newChunkSection(layer, this::load, setArr, fastmode);
if (!BukkitAdapter_1_14.setSectionAtomic(sections, existingSection, newSection, layer)) {
System.out.println("Failed to set chunk section:" + X + "," + Z + " layer: " + layer);
continue;

View File

@ -186,11 +186,11 @@ public final class BukkitAdapter_1_15 extends NMSAdapter {
/*
NMS conversion
*/
public static ChunkSection newChunkSection(final int layer, final char[] blocks) {
return newChunkSection(layer, null, blocks);
public static ChunkSection newChunkSection(final int layer, final char[] blocks, boolean fastmode) {
return newChunkSection(layer, null, blocks, fastmode);
}
public static ChunkSection newChunkSection(final int layer, final Function<Integer, char[]> get, char[] set) {
public static ChunkSection newChunkSection(final int layer, final Function<Integer, char[]> get, char[] set, boolean fastmode) {
if (set == null) {
return newChunkSection(layer);
}
@ -203,9 +203,9 @@ public final class BukkitAdapter_1_15 extends NMSAdapter {
Map<BlockVector3, Integer> ticking_blocks = new HashMap<>();
int air;
if (get == null) {
air = createPalette(blockToPalette, paletteToBlock, blocksCopy, num_palette_buffer, set, ticking_blocks);
air = createPalette(blockToPalette, paletteToBlock, blocksCopy, num_palette_buffer, set, ticking_blocks, fastmode);
} else {
air = createPalette(layer, blockToPalette, paletteToBlock, blocksCopy, num_palette_buffer, get, set, ticking_blocks);
air = createPalette(layer, blockToPalette, paletteToBlock, blocksCopy, num_palette_buffer, get, set, ticking_blocks, fastmode);
}
int num_palette = num_palette_buffer[0];
// BlockStates

View File

@ -10,6 +10,7 @@ import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks;
import com.boydti.fawe.beta.implementation.queue.QueueHandler;
import com.boydti.fawe.bukkit.adapter.DelegateLock;
import com.boydti.fawe.bukkit.adapter.mc1_15.nbt.LazyCompoundTag_1_15;
import com.boydti.fawe.config.Settings;
import com.boydti.fawe.object.collection.AdaptedMap;
import com.boydti.fawe.object.collection.BitArray;
import com.google.common.base.Suppliers;
@ -236,6 +237,7 @@ public class BukkitGetBlocks_1_15 extends CharGetBlocks {
try {
WorldServer nmsWorld = world;
Chunk nmsChunk = ensureLoaded(nmsWorld, X, Z);
boolean fastmode = set.isFastMode() && Settings.IMP.QUEUE.NO_TICK_FASTMODE;
// Remove existing tiles
{
@ -271,7 +273,7 @@ public class BukkitGetBlocks_1_15 extends CharGetBlocks {
ChunkSection newSection;
ChunkSection existingSection = sections[layer];
if (existingSection == null) {
newSection = BukkitAdapter_1_15.newChunkSection(layer, setArr);
newSection = BukkitAdapter_1_15.newChunkSection(layer, setArr, fastmode);
if (BukkitAdapter_1_15.setSectionAtomic(sections, null, newSection, layer)) {
updateGet(this, nmsChunk, sections, newSection, setArr, layer);
continue;
@ -303,7 +305,7 @@ public class BukkitGetBlocks_1_15 extends CharGetBlocks {
} else if (lock.isModified()) {
this.reset(layer);
}
newSection = BukkitAdapter_1_15.newChunkSection(layer, this::load, setArr);
newSection = BukkitAdapter_1_15.newChunkSection(layer, this::load, setArr, fastmode);
if (!BukkitAdapter_1_15.setSectionAtomic(sections, existingSection, newSection, layer)) {
System.out.println("Failed to set chunk section:" + X + "," + Z + " layer: " + layer);
continue;

View File

@ -187,11 +187,11 @@ public final class BukkitAdapter_1_15_2 extends NMSAdapter {
/*
NMS conversion
*/
public static ChunkSection newChunkSection(final int layer, final char[] blocks) {
return newChunkSection(layer, null, blocks);
public static ChunkSection newChunkSection(final int layer, final char[] blocks, boolean fastmode) {
return newChunkSection(layer, null, blocks, fastmode);
}
public static ChunkSection newChunkSection(final int layer, final Function<Integer, char[]> get, char[] set) {
public static ChunkSection newChunkSection(final int layer, final Function<Integer, char[]> get, char[] set, boolean fastmode) {
if (set == null) {
return newChunkSection(layer);
}
@ -205,10 +205,10 @@ public final class BukkitAdapter_1_15_2 extends NMSAdapter {
int air;
if (get == null) {
air = createPalette(blockToPalette, paletteToBlock, blocksCopy, num_palette_buffer,
set, ticking_blocks);
set, ticking_blocks, fastmode);
} else {
air = createPalette(layer, blockToPalette, paletteToBlock, blocksCopy,
num_palette_buffer, get, set, ticking_blocks);
num_palette_buffer, get, set, ticking_blocks, fastmode);
}
int num_palette = num_palette_buffer[0];
// BlockStates
@ -251,10 +251,11 @@ public final class BukkitAdapter_1_15_2 extends NMSAdapter {
fieldPalette.set(dataPaletteBlocks, palette);
fieldSize.set(dataPaletteBlocks, bitsPerEntry);
setCount(ticking_blocks.size(), 4096 - air, section);
ticking_blocks.forEach((pos, ordinal) -> {
section.setType(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ(),
Block.getByCombinedId(ordinal));
});
if (!fastmode) {
ticking_blocks.forEach((pos, ordinal) -> section
.setType(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ(),
Block.getByCombinedId(ordinal)));
}
} catch (final IllegalAccessException | NoSuchFieldException e) {
throw new RuntimeException(e);
}

View File

@ -8,6 +8,7 @@ import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks;
import com.boydti.fawe.beta.implementation.queue.QueueHandler;
import com.boydti.fawe.bukkit.adapter.DelegateLock;
import com.boydti.fawe.bukkit.adapter.mc1_15_2.nbt.LazyCompoundTag_1_15_2;
import com.boydti.fawe.config.Settings;
import com.boydti.fawe.object.collection.AdaptedMap;
import com.boydti.fawe.object.collection.BitArray;
import com.google.common.base.Suppliers;
@ -243,6 +244,7 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks {
try {
WorldServer nmsWorld = world;
Chunk nmsChunk = ensureLoaded(nmsWorld, X, Z);
boolean fastmode = set.isFastMode() && Settings.IMP.QUEUE.NO_TICK_FASTMODE;
// Remove existing tiles
{
@ -283,7 +285,7 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks {
ChunkSection newSection;
ChunkSection existingSection = sections[layer];
if (existingSection == null) {
newSection = BukkitAdapter_1_15_2.newChunkSection(layer, setArr);
newSection = BukkitAdapter_1_15_2.newChunkSection(layer, setArr, fastmode);
if (BukkitAdapter_1_15_2.setSectionAtomic(sections, null, newSection, layer)) {
updateGet(this, nmsChunk, sections, newSection, setArr, layer);
continue;
@ -315,7 +317,7 @@ public class BukkitGetBlocks_1_15_2 extends CharGetBlocks {
} else if (lock.isModified()) {
this.reset(layer);
}
newSection = BukkitAdapter_1_15_2.newChunkSection(layer, this::load, setArr);
newSection = BukkitAdapter_1_15_2.newChunkSection(layer, this::load, setArr, fastmode);
if (!BukkitAdapter_1_15_2.setSectionAtomic(sections, existingSection, newSection, layer)) {
System.out.println("Failed to set chunk section:" + X + "," + Z + " layer: " + layer);
continue;

View File

@ -3,14 +3,12 @@ package com.boydti.fawe.beta;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.extent.OutputExtent;
import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import java.util.Map;
import javax.annotation.Nullable;
import java.util.Set;
import java.util.UUID;
import javax.annotation.Nullable;
/**
* Interface for setting blocks
@ -42,6 +40,13 @@ public interface IChunkSet extends IBlocks, OutputExtent {
return getBiomes() != null;
}
default boolean isFastMode() {
return false;
}
//default to avoid tricky child classes. We only need it in a few cases anyway.
default void setFastMode(boolean fastMode){}
@Override
IChunkSet reset();

View File

@ -82,6 +82,10 @@ public interface IQueueExtent<T extends IChunk> extends Flushable, Trimable, ICh
return BlockVector3.at(30000000, FaweCache.IMP.WORLD_MAX_Y, 30000000);
}
void setFastMode(boolean fastMode);
boolean isFastMode();
/**
* Create a new root IChunk object<br> - Full chunks will be reused, so a more optimized chunk
* can be returned in that case<br> - Don't wrap the chunk, that should be done in {@link
@ -143,6 +147,7 @@ public interface IQueueExtent<T extends IChunk> extends Flushable, Trimable, ICh
T chunk = this.getOrCreateChunk(chunkX, chunkZ);
// Initialize
chunk.init(this, chunkX, chunkZ);
chunk.setFastMode(isFastMode());
T newChunk = filter.applyChunk(chunk, region);
if (newChunk != null) {

View File

@ -34,6 +34,7 @@ public class CharSetBlocks extends CharBlocks implements IChunkSet {
public BlockVector3ChunkMap<CompoundTag> tiles;
public HashSet<CompoundTag> entities;
public HashSet<UUID> entityRemoves;
private boolean fastMode = false;
private CharSetBlocks() {}
@ -131,6 +132,16 @@ public class CharSetBlocks extends CharBlocks implements IChunkSet {
entityRemoves.add(uuid);
}
@Override
public void setFastMode(boolean fastMode) {
this.fastMode = fastMode;
}
@Override
public boolean isFastMode() {
return fastMode;
}
@Override
public boolean isEmpty() {
if (biomes != null) {

View File

@ -42,6 +42,7 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
private IQueueExtent<? extends IChunk> extent; // the parent queue extent which has this chunk
private int chunkX;
private int chunkZ;
private boolean fastmode;
private ChunkHolder() {
this.delegate = NULL;
@ -100,6 +101,16 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
return getOrCreateGet().load(layer);
}
@Override
public boolean isFastMode() {
return fastmode;
}
@Override
public void setFastMode(boolean fastmode) {
this.fastmode = fastmode;
}
@Override
public CompoundTag getEntity(UUID uuid) {
return delegate.get(this).getEntity(uuid);
@ -313,6 +324,7 @@ public class ChunkHolder<T extends Future<T>> implements IQueueChunk<T> {
public void filterBlocks(Filter filter, ChunkFilterBlock block, @Nullable Region region, boolean full) {
final IChunkGet get = getOrCreateGet();
final IChunkSet set = getOrCreateSet();
set.setFastMode(fastmode);
try {
block.filter(this, get, set, filter, region, full);
} finally {

View File

@ -44,12 +44,14 @@ public class ParallelQueueExtent extends PassthroughExtent implements IQueueWrap
private final QueueHandler handler;
private final BatchProcessorHolder processor;
private int changes;
private final boolean fastmode;
public ParallelQueueExtent(QueueHandler handler, World world) {
public ParallelQueueExtent(QueueHandler handler, World world, boolean fastmode) {
super(handler.getQueue(world, new BatchProcessorHolder()));
this.world = world;
this.handler = handler;
this.processor = (BatchProcessorHolder) getExtent().getProcessor();
this.fastmode = fastmode;
}
@Override
@ -94,6 +96,7 @@ public class ParallelQueueExtent extends PassthroughExtent implements IQueueWrap
final Filter newFilter = filter.fork();
// Create a chunk that we will reuse/reset for each operation
final IQueueExtent<IQueueChunk> queue = getNewQueue();
queue.setFastMode(fastmode);
synchronized (queue) {
ChunkFilterBlock block = null;

View File

@ -49,6 +49,8 @@ public class SingleThreadQueueExtent extends ExtentBatchProcessorHolder implemen
private boolean enabledQueue = true;
private boolean fastmode = false;
/**
* Safety check to ensure that the thread being used matches the one being initialized on. - Can
* be removed later
@ -80,6 +82,16 @@ public class SingleThreadQueueExtent extends ExtentBatchProcessorHolder implemen
return cacheSet.get(chunkX, chunkZ);
}
@Override
public void setFastMode(boolean fastmode) {
this.fastmode = fastmode;
}
@Override
public boolean isFastMode() {
return fastmode;
}
/**
* Resets the queue.
*/

View File

@ -309,6 +309,11 @@ public class Settings extends Config {
})
public int DISCARD_AFTER_MS = 60000;
@Comment({
"When using fastmode also do not bother to fix existing ticking blocks"
})
public boolean NO_TICK_FASTMODE = true;
public static class PROGRESS {
@Comment({"Display constant titles about the progress of a user's edit",
" - false = disabled",
@ -375,6 +380,12 @@ public class Settings extends Config {
"This has no effect on existing blocks one way or the other."
})
public boolean ALLOW_TICK_PLACED = false;
@Comment({
"Force re-ticking of existing blocks not edited by FAWE.",
"This will increase time taken slightly."
})
public boolean ALLOW_TICK_EXISTING = true;
}
public static class WEB {

View File

@ -296,7 +296,7 @@ public class EditSessionBuilder {
if (unwrapped instanceof IQueueExtent) {
extent = queue = (IQueueExtent) unwrapped;
} else if (Settings.IMP.QUEUE.PARALLEL_THREADS > 1 && threaded) {
ParallelQueueExtent parallel = new ParallelQueueExtent(Fawe.get().getQueueHandler(), world);
ParallelQueueExtent parallel = new ParallelQueueExtent(Fawe.get().getQueueHandler(), world, fastmode);
queue = parallel.getExtent();
extent = parallel;
} else {

View File

@ -364,6 +364,12 @@ public class DefaultBlockParser extends InputParser<BaseBlock> {
}
state = fuzzyBuilder.build();
}
} else {
for (Map.Entry<Property<?>, Object> blockState : blockStates.entrySet()) {
@SuppressWarnings("unchecked")
Property<Object> objProp = (Property<Object>) blockState.getKey();
state = state.with(objProp, blockState.getValue());
}
}
}
// this should be impossible but IntelliJ isn't that smart

View File

@ -75,7 +75,7 @@
"fawe.worldedit.history.command.redo.success": "Redo successful {0}.",
"fawe.worldedit.history.command.undo.error": "Nothing left to undo. (See also `/inspect` and `/frb`)",
"fawe.worldedit.history.command.undo.disabled": "Undo disabled, use: //fast",
"fawe.worldedit.history.command.undo.success": "Undo successful{0}.",
"fawe.worldedit.history.command.undo.success": "Undo successful {0}.",
"fawe.worldedit.operation.operation": "Operation queued ({0})",
@ -97,7 +97,7 @@
"fawe.worldedit.selection.selection.shift": "Region shifted",
"fawe.worldedit.selection.selection.cleared": "Selection cleared",
"fawe.worldedit.anvil.world.is.loaded": "The world shouldn't be in use when executing. Unload the world, or use use -f to override (save first)",
"fawe.worldedit.anvil.world.is.loaded": "The world shouldn't be in use when executing. Unload the world, or use -f to override (save first)",
"fawe.worldedit.brush.brush.reset": "Reset your brush. (SHIFT + Click)",
"fawe.worldedit.brush.brush.none": "You aren't holding a brush!",