diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/ExpressionPattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/ExpressionPattern.java index a9c1ec962..638872ea8 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/ExpressionPattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/ExpressionPattern.java @@ -1,6 +1,7 @@ package com.fastasyncworldedit.core.function.pattern; import com.sk89q.worldedit.function.pattern.AbstractPattern; +import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.internal.expression.EvaluationException; import com.sk89q.worldedit.internal.expression.Expression; import com.sk89q.worldedit.internal.expression.ExpressionException; @@ -57,4 +58,9 @@ public class ExpressionPattern extends AbstractPattern { } } + @Override + public Pattern fork() { + return new ExpressionPattern(this.expression.clone()); + } + } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/Linear2DBlockPattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/Linear2DBlockPattern.java index 523f22541..e99383d06 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/Linear2DBlockPattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/Linear2DBlockPattern.java @@ -7,6 +7,8 @@ import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.world.block.BaseBlock; +import java.util.Arrays; + import static java.lang.Math.floorDiv; /** @@ -52,4 +54,10 @@ public class Linear2DBlockPattern extends AbstractPattern { return patternsArray[index].apply(extent, get, set); } + @Override + public Pattern fork() { + final Pattern[] forked = Arrays.stream(this.patternsArray).map(Pattern::fork).toArray(Pattern[]::new); + return new Linear2DBlockPattern(forked, this.xScale, this.zScale); + } + } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/Linear3DBlockPattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/Linear3DBlockPattern.java index ea2e37588..e4d3822cc 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/Linear3DBlockPattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/Linear3DBlockPattern.java @@ -7,6 +7,8 @@ import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.world.block.BaseBlock; +import java.util.Arrays; + import static java.lang.Math.floorDiv; /** @@ -56,4 +58,10 @@ public class Linear3DBlockPattern extends AbstractPattern { return patternsArray[index].apply(extent, get, set); } + @Override + public Pattern fork() { + final Pattern[] forked = Arrays.stream(this.patternsArray).map(Pattern::fork).toArray(Pattern[]::new); + return new Linear3DBlockPattern(forked, this.xScale, this.yScale, this.zScale); + } + } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/LinearBlockPattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/LinearBlockPattern.java index 0b6ef1be9..c65918e89 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/LinearBlockPattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/LinearBlockPattern.java @@ -47,4 +47,10 @@ public class LinearBlockPattern extends AbstractPattern implements ResettablePat index = 0; } + @Override + public Pattern fork() { + final Pattern[] forked = Arrays.stream(this.patternsArray).map(Pattern::fork).toArray(Pattern[]::new); + return new LinearBlockPattern(forked); + } + } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/MaskedPattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/MaskedPattern.java index 5d840d771..a5210feba 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/MaskedPattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/MaskedPattern.java @@ -43,4 +43,9 @@ public class MaskedPattern extends AbstractPattern { return secondary.apply(extent, get, set); } + @Override + public Pattern fork() { + return new MaskedPattern(this.mask.copy(), this.primary.fork(), this.secondary.fork()); + } + } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/NoXPattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/NoXPattern.java index d9fefb1bc..b4e9aac37 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/NoXPattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/NoXPattern.java @@ -36,4 +36,9 @@ public class NoXPattern extends AbstractPattern { return pattern.apply(extent, mutable, set); } + @Override + public Pattern fork() { + return new NoXPattern(this.pattern.fork()); + } + } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/NoYPattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/NoYPattern.java index 05d26f496..2fefaedfc 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/NoYPattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/NoYPattern.java @@ -36,4 +36,9 @@ public class NoYPattern extends AbstractPattern { return pattern.apply(extent, mutable, set); } + @Override + public Pattern fork() { + return new NoYPattern(this.pattern.fork()); + } + } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/NoZPattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/NoZPattern.java index faebb59aa..8c100c5e3 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/NoZPattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/NoZPattern.java @@ -1,6 +1,7 @@ package com.fastasyncworldedit.core.function.pattern; import com.fastasyncworldedit.core.math.MutableBlockVector3; +import com.fastasyncworldedit.core.queue.Filter; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.function.pattern.AbstractPattern; @@ -36,4 +37,9 @@ public class NoZPattern extends AbstractPattern { return pattern.apply(extent, mutable, set); } + @Override + public Pattern fork() { + return new NoZPattern(this.pattern.fork()); + } + } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/OffsetPattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/OffsetPattern.java index 894f9d06a..628b848e8 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/OffsetPattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/OffsetPattern.java @@ -60,4 +60,9 @@ public class OffsetPattern extends AbstractPattern { return pattern.apply(extent, get, mutable); } + @Override + public Pattern fork() { + return new OffsetPattern(this.pattern.fork(), this.dx, this.dy, this.dz, this.minY, this.maxY); + } + } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/RandomOffsetPattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/RandomOffsetPattern.java index 3eb5c3b77..c0afd02e3 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/RandomOffsetPattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/RandomOffsetPattern.java @@ -72,4 +72,9 @@ public class RandomOffsetPattern extends AbstractPattern { return pattern.apply(extent, get, mutable); } + @Override + public Pattern fork() { + return new RandomOffsetPattern(this.pattern.fork(), this.dx, this.dy, this.dz, this.minY, this.maxY); + } + } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/RelativePattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/RelativePattern.java index cda875f04..541aaa494 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/RelativePattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/RelativePattern.java @@ -63,4 +63,11 @@ public class RelativePattern extends AbstractPattern implements ResettablePatter origin = null; } + @Override + public Pattern fork() { + RelativePattern forked = new RelativePattern(this.pattern.fork(), this.minY, this.maxY); + forked.origin = this.origin; // maintain origin for forks + return forked; + } + } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/SolidRandomOffsetPattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/SolidRandomOffsetPattern.java index 12b64a497..54ecf6676 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/SolidRandomOffsetPattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/SolidRandomOffsetPattern.java @@ -94,4 +94,9 @@ public class SolidRandomOffsetPattern extends AbstractPattern { return pattern.apply(extent, get, set); } + @Override + public Pattern fork() { + return new SolidRandomOffsetPattern(this.pattern.fork(), this.dx, this.dy, this.dz, this.minY, this.maxY); + } + } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/SurfaceRandomOffsetPattern.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/SurfaceRandomOffsetPattern.java index 73327f94a..34866fc54 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/SurfaceRandomOffsetPattern.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/function/pattern/SurfaceRandomOffsetPattern.java @@ -129,4 +129,9 @@ public class SurfaceRandomOffsetPattern extends AbstractPattern { return !block.getBlockType().getMaterial().isMovementBlocker(); } + @Override + public Pattern fork() { + return new SurfaceRandomOffsetPattern(this.pattern.fork(), this.moves, this.minY, this.maxY); + } + } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/buffer/ForgetfulExtentBuffer.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/buffer/ForgetfulExtentBuffer.java index f569acd00..ca2bfd965 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/buffer/ForgetfulExtentBuffer.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/buffer/ForgetfulExtentBuffer.java @@ -235,4 +235,11 @@ public class ForgetfulExtentBuffer extends AbstractDelegateExtent implements Pat }; } + //FAWE - stateful pattern + @Override + public Pattern fork() { + return new ForgetfulExtentBuffer(extent, mask.copy()); + } + //FAWE end + } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/ExtentBufferedCompositePattern.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/ExtentBufferedCompositePattern.java index 49e7f5472..863cf1e25 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/ExtentBufferedCompositePattern.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/ExtentBufferedCompositePattern.java @@ -25,6 +25,8 @@ import com.sk89q.worldedit.extent.buffer.ExtentBuffer; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.world.block.BaseBlock; +import java.util.Arrays; + import static com.google.common.base.Preconditions.checkArgument; /** @@ -64,4 +66,12 @@ public class ExtentBufferedCompositePattern extends AbstractExtentPattern { return lastBlock; } + //FAWE - stateful pattern + @Override + public Pattern fork() { + final Pattern[] forkedPatterns = Arrays.stream(patterns).map(Pattern::fork).toArray(Pattern[]::new); + return new ExtentBufferedCompositePattern(getExtent(), forkedPatterns); + } + //FAWE end + } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/Pattern.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/Pattern.java index 801b07a65..ab284c0cf 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/Pattern.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/Pattern.java @@ -59,6 +59,11 @@ public interface Pattern extends Filter { apply(block, block, block); } + @Override + default Pattern fork() { // covariant return type + return this; + } + //FAWE end /** diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/RandomPattern.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/RandomPattern.java index 1d2df7223..c45629e5f 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/RandomPattern.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/RandomPattern.java @@ -67,6 +67,13 @@ public class RandomPattern extends AbstractPattern { this.collection = RandomCollection.of(weights, random); this.patterns = parent.patterns; } + + private RandomPattern(SimpleRandom random, Map weights) { + this.random = random; + this.weights = weights; + this.collection = RandomCollection.of(weights, random); + this.patterns = new LinkedHashSet<>(weights.keySet()); + } //FAWE end /** @@ -107,6 +114,14 @@ public class RandomPattern extends AbstractPattern { public boolean apply(Extent extent, BlockVector3 get, BlockVector3 set) throws WorldEditException { return collection.next(get.getBlockX(), get.getBlockY(), get.getBlockZ()).apply(extent, get, set); } + + @Override + public Pattern fork() { + final LinkedHashMap newWeights = new LinkedHashMap<>(); + this.weights.forEach((p, w) -> newWeights.put(p.fork(), w)); + return new RandomPattern(this.random, newWeights); + } + //FAWE end } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/StateApplyingPattern.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/StateApplyingPattern.java index 3d834f76b..b328e78ea 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/StateApplyingPattern.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/pattern/StateApplyingPattern.java @@ -29,13 +29,16 @@ import com.sk89q.worldedit.world.block.BlockType; import java.util.Map; import java.util.Map.Entry; +import java.util.concurrent.ConcurrentHashMap; import static com.sk89q.worldedit.blocks.Blocks.resolveProperties; public class StateApplyingPattern extends AbstractExtentPattern { private final Map states; - private final Map, Object>> cache = Maps.newHashMap(); + //FAWE - avoid race conditions + private final Map, Object>> cache = new ConcurrentHashMap<>(); + //FAWE end public StateApplyingPattern(Extent extent, Map statesToSet) { super(extent);