This commit aims to fix existing issues regarding the "0/-1 blocks affected" bug. Introducing the new LinkedFilter class allows us to use multiple filters for single-filter operations, e.g. applying a pattern to blocks while also counting the amount of blocks applied to. SetFilter.java was also removed due to not being used.
This commit is contained in:
IronApollo 2020-05-07 12:29:18 -04:00
parent afba834b83
commit 8b1a0bbc34
6 changed files with 93 additions and 39 deletions

View File

@ -0,0 +1,36 @@
package com.boydti.fawe.beta.implementation.filter;
import com.boydti.fawe.beta.Filter;
import com.boydti.fawe.beta.implementation.filter.block.DelegateFilter;
import com.boydti.fawe.beta.implementation.filter.block.FilterBlock;
/**
* Filter which links two Filters together for single-filter-input operations.
*
* @param <T> Parent which extends Filter
* @param <S> Child which extends Filter
*/
public final class LinkedFilter<T extends Filter, S extends Filter> extends DelegateFilter<T> {
private final S child;
public LinkedFilter(T parent, S child){
super(parent);
this.child = child;
}
public S getChild(){
return this.child;
}
@Override
public void applyBlock(FilterBlock block) {
this.getParent().applyBlock(block);
this.getChild().applyBlock(block);
}
@Override
public LinkedFilter<LinkedFilter<T,S>, Filter> newInstance(Filter other) {
return new LinkedFilter<>(this, other);
}
}

View File

@ -1,14 +1,21 @@
package com.sk89q.worldedit.function.mask; package com.boydti.fawe.beta.implementation.filter;
import com.boydti.fawe.beta.implementation.filter.block.DelegateFilter; import com.boydti.fawe.beta.implementation.filter.block.DelegateFilter;
import com.boydti.fawe.beta.Filter; import com.boydti.fawe.beta.Filter;
import com.boydti.fawe.beta.implementation.filter.block.FilterBlock; import com.boydti.fawe.beta.implementation.filter.block.FilterBlock;
import com.sk89q.worldedit.function.mask.Mask;
import java.util.function.Supplier; import java.util.function.Supplier;
/**
* Filter with an attached Mask used for deciding whether a block is eligible for being applied to.
*
* @param <T> Parent which extends Filter
*/
public class MaskFilter<T extends Filter> extends DelegateFilter<T> { public class MaskFilter<T extends Filter> extends DelegateFilter<T> {
private final Supplier<Mask> supplier; private final Supplier<Mask> supplier;
private final Mask mask; private final Mask mask;
private int changes;
public MaskFilter(T other, Mask mask) { public MaskFilter(T other, Mask mask) {
this(other, () -> mask); this(other, () -> mask);
@ -28,9 +35,19 @@ public class MaskFilter<T extends Filter> extends DelegateFilter<T> {
public void applyBlock(FilterBlock block) { public void applyBlock(FilterBlock block) {
if (mask.test(block, block)) { if (mask.test(block, block)) {
getParent().applyBlock(block); getParent().applyBlock(block);
this.changes++;
} }
} }
/**
* Get the number of blocks which passed the Mask test and were applied to
*
* @return number of blocks which passed the Mask test and were applied to
*/
public int getBlocksApplied(){
return this.changes;
}
@Override @Override
public MaskFilter newInstance(Filter other) { public MaskFilter newInstance(Filter other) {
return new MaskFilter<>(other, supplier); return new MaskFilter<>(other, supplier);

View File

@ -1,19 +0,0 @@
package com.boydti.fawe.beta.implementation.filter;
import com.boydti.fawe.beta.Filter;
import com.boydti.fawe.beta.implementation.filter.block.FilterBlock;
import com.sk89q.worldedit.world.block.BlockState;
public class SetFilter implements Filter {
private final BlockState state;
public SetFilter(BlockState state) {
this.state = state;
}
@Override
public void applyBlock(FilterBlock block) {
block.setBlock(state);
}
}

View File

@ -1,13 +1,14 @@
package com.boydti.fawe.beta.implementation.queue; package com.boydti.fawe.beta.implementation.queue;
import com.boydti.fawe.FaweCache; import com.boydti.fawe.FaweCache;
import com.boydti.fawe.beta.IQueueChunk;
import com.boydti.fawe.beta.IQueueWrapper;
import com.boydti.fawe.beta.implementation.filter.block.ChunkFilterBlock;
import com.boydti.fawe.beta.Filter; import com.boydti.fawe.beta.Filter;
import com.boydti.fawe.beta.IQueueChunk;
import com.boydti.fawe.beta.IQueueExtent; import com.boydti.fawe.beta.IQueueExtent;
import com.boydti.fawe.beta.IQueueWrapper;
import com.boydti.fawe.beta.implementation.filter.CountFilter; import com.boydti.fawe.beta.implementation.filter.CountFilter;
import com.boydti.fawe.beta.implementation.filter.DistrFilter; import com.boydti.fawe.beta.implementation.filter.DistrFilter;
import com.boydti.fawe.beta.implementation.filter.LinkedFilter;
import com.boydti.fawe.beta.implementation.filter.block.ChunkFilterBlock;
import com.boydti.fawe.beta.implementation.processors.BatchProcessorHolder; import com.boydti.fawe.beta.implementation.processors.BatchProcessorHolder;
import com.boydti.fawe.config.Settings; import com.boydti.fawe.config.Settings;
import com.boydti.fawe.object.clipboard.WorldCopyClipboard; import com.boydti.fawe.object.clipboard.WorldCopyClipboard;
@ -16,6 +17,7 @@ import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.extent.PassthroughExtent; import com.sk89q.worldedit.extent.PassthroughExtent;
import com.sk89q.worldedit.extent.clipboard.Clipboard; import com.sk89q.worldedit.extent.clipboard.Clipboard;
import com.sk89q.worldedit.function.mask.BlockMask; import com.sk89q.worldedit.function.mask.BlockMask;
import com.sk89q.worldedit.function.mask.BlockMaskBuilder;
import com.sk89q.worldedit.function.mask.ExistingBlockMask; import com.sk89q.worldedit.function.mask.ExistingBlockMask;
import com.sk89q.worldedit.function.mask.Mask; import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.pattern.BlockPattern; import com.sk89q.worldedit.function.pattern.BlockPattern;
@ -36,13 +38,12 @@ import java.util.Set;
import java.util.concurrent.ForkJoinTask; import java.util.concurrent.ForkJoinTask;
import java.util.stream.IntStream; import java.util.stream.IntStream;
import static com.google.common.base.Preconditions.checkNotNull;
public class ParallelQueueExtent extends PassthroughExtent implements IQueueWrapper { public class ParallelQueueExtent extends PassthroughExtent implements IQueueWrapper {
private final World world; private final World world;
private final QueueHandler handler; private final QueueHandler handler;
private final BatchProcessorHolder processor; private final BatchProcessorHolder processor;
private int changes;
public ParallelQueueExtent(QueueHandler handler, World world) { public ParallelQueueExtent(QueueHandler handler, World world) {
super(handler.getQueue(world, new BatchProcessorHolder())); super(handler.getQueue(world, new BatchProcessorHolder()));
@ -52,8 +53,8 @@ public class ParallelQueueExtent extends PassthroughExtent implements IQueueWrap
} }
@Override @Override
public IQueueExtent getExtent() { public IQueueExtent<IQueueChunk> getExtent() {
return (IQueueExtent) super.getExtent(); return (IQueueExtent<IQueueChunk>) super.getExtent();
} }
@Override @Override
@ -126,10 +127,6 @@ public class ParallelQueueExtent extends PassthroughExtent implements IQueueWrap
return filter; return filter;
} }
public int getChanges() {
return -1;
}
@Override @Override
public int countBlocks(Region region, Mask searchMask) { public int countBlocks(Region region, Mask searchMask) {
return return
@ -142,33 +139,30 @@ public class ParallelQueueExtent extends PassthroughExtent implements IQueueWrap
@Override @Override
public <B extends BlockStateHolder<B>> int setBlocks(Region region, B block) throws MaxChangedBlocksException { public <B extends BlockStateHolder<B>> int setBlocks(Region region, B block) throws MaxChangedBlocksException {
apply(region, block, true); return this.changes = apply(region, new BlockMaskBuilder().add(block).build(this).toFilter(new CountFilter())).getParent().getTotal();
return getChanges();
} }
@Override @Override
public int setBlocks(Region region, Pattern pattern) throws MaxChangedBlocksException { public int setBlocks(Region region, Pattern pattern) throws MaxChangedBlocksException {
apply(region, pattern, true); return this.changes = apply(region, new LinkedFilter<>(pattern, new CountFilter()), true).getChild().getTotal();
return getChanges();
} }
@Override @Override
public int setBlocks(Set<BlockVector3> vset, Pattern pattern) { public int setBlocks(Set<BlockVector3> vset, Pattern pattern) {
if (vset instanceof Region) { if (vset instanceof Region) {
setBlocks((Region) vset, pattern); this.changes = setBlocks((Region) vset, pattern);
} }
// TODO optimize parallel // TODO optimize parallel
for (BlockVector3 blockVector3 : vset) { for (BlockVector3 blockVector3 : vset) {
pattern.apply(this, blockVector3, blockVector3); pattern.apply(this, blockVector3, blockVector3);
} }
return getChanges(); return this.changes;
} }
@Override @Override
public int replaceBlocks(Region region, Mask mask, Pattern pattern) public int replaceBlocks(Region region, Mask mask, Pattern pattern)
throws MaxChangedBlocksException { throws MaxChangedBlocksException {
apply(region, mask.toFilter(pattern), false); return this.changes = apply(region, mask.toFilter(pattern), false).getBlocksApplied();
return getChanges();
} }
@Override @Override

View File

@ -1069,6 +1069,31 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
return this.changes; return this.changes;
} }
@Override
public <B extends BlockStateHolder<B>> int setBlocks(Region region, B block) throws MaxChangedBlocksException {
return this.changes = super.setBlocks(region, block);
}
@Override
public int setBlocks(Region region, Pattern pattern) throws MaxChangedBlocksException {
return this.changes = super.setBlocks(region, pattern);
}
@Override
public <B extends BlockStateHolder<B>> int replaceBlocks(Region region, Set<BaseBlock> filter, B replacement) throws MaxChangedBlocksException {
return this.changes = super.replaceBlocks(region, filter, replacement);
}
@Override
public int replaceBlocks(Region region, Set<BaseBlock> filter, Pattern pattern) throws MaxChangedBlocksException {
return this.changes = super.replaceBlocks(region, filter, pattern);
}
@Override
public int replaceBlocks(Region region, Mask mask, Pattern pattern) throws MaxChangedBlocksException {
return this.changes = super.replaceBlocks(region, mask, pattern);
}
/** /**
* Fills an area recursively in the X/Z directions. * Fills an area recursively in the X/Z directions.
* *

View File

@ -20,6 +20,7 @@
package com.sk89q.worldedit.function.mask; package com.sk89q.worldedit.function.mask;
import com.boydti.fawe.beta.Filter; import com.boydti.fawe.beta.Filter;
import com.boydti.fawe.beta.implementation.filter.MaskFilter;
import com.boydti.fawe.beta.implementation.filter.block.FilterBlock; import com.boydti.fawe.beta.implementation.filter.block.FilterBlock;
import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.extent.NullExtent; import com.sk89q.worldedit.extent.NullExtent;