Skip to content

Commit d3c59b1

Browse files
committed
Re-enable buffering
This is required for masks to work properly.
1 parent c61b273 commit d3c59b1

3 files changed

Lines changed: 121 additions & 11 deletions

File tree

worldedit-core/src/main/java/com/sk89q/worldedit/EditSession.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import com.sk89q.worldedit.extent.NullExtent;
3333
import com.sk89q.worldedit.extent.TracingExtent;
3434
import com.sk89q.worldedit.extent.buffer.ForgetfulExtentBuffer;
35+
import com.sk89q.worldedit.extent.buffer.internal.BatchingExtent;
3536
import com.sk89q.worldedit.extent.cache.LastAccessExtentCache;
3637
import com.sk89q.worldedit.extent.inventory.BlockBag;
3738
import com.sk89q.worldedit.extent.inventory.BlockBagExtent;
@@ -200,6 +201,7 @@ public String getDisplayName() {
200201

201202
private @Nullable SideEffectExtent sideEffectExtent;
202203
private final SurvivalModeExtent survivalExtent;
204+
private @Nullable BatchingExtent batchingExtent;
203205
private @Nullable ChunkBatchingExtent chunkBatchingExtent;
204206
private final BlockBagExtent blockBagExtent;
205207
@SuppressWarnings("deprecation")
@@ -269,6 +271,7 @@ public String getDisplayName() {
269271
this.bypassReorderHistory = traceIfNeeded(new DataValidatorExtent(extent, world));
270272

271273
// This extent can be skipped by calling rawSetBlock()
274+
extent = traceIfNeeded(batchingExtent = new BatchingExtent(extent));
272275
@SuppressWarnings("deprecation")
273276
MultiStageReorder reorder = new MultiStageReorder(extent, false);
274277
extent = traceIfNeeded(reorderExtent = reorder);
@@ -618,10 +621,12 @@ public void setBatchingChunks(boolean batchingChunks) {
618621
}
619622
return;
620623
}
624+
assert batchingExtent != null : "same nullness as chunkBatchingExtent";
621625
if (!batchingChunks && isBatchingChunks()) {
622626
internalFlushSession();
623627
}
624628
chunkBatchingExtent.setEnabled(batchingChunks);
629+
batchingExtent.setEnabled(!batchingChunks);
625630
}
626631

627632
/**
@@ -650,6 +655,8 @@ public void disableBuffering() {
650655
setReorderMode(ReorderMode.NONE);
651656
if (chunkBatchingExtent != null) {
652657
chunkBatchingExtent.setEnabled(false);
658+
assert batchingExtent != null : "same nullness as chunkBatchingExtent";
659+
batchingExtent.setEnabled(true);
653660
}
654661
}
655662

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/*
2+
* WorldEdit, a Minecraft world manipulation toolkit
3+
* Copyright (C) sk89q <http://www.sk89q.com>
4+
* Copyright (C) WorldEdit team and contributors
5+
*
6+
* This program is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation, either version 3 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
18+
*/
19+
20+
package com.sk89q.worldedit.extent.buffer.internal;
21+
22+
import com.google.common.base.Throwables;
23+
import com.sk89q.worldedit.WorldEditException;
24+
import com.sk89q.worldedit.extent.AbstractBufferingExtent;
25+
import com.sk89q.worldedit.extent.Extent;
26+
import com.sk89q.worldedit.function.operation.Operation;
27+
import com.sk89q.worldedit.function.operation.RunContext;
28+
import com.sk89q.worldedit.math.BlockVector3;
29+
import com.sk89q.worldedit.util.collection.BlockMap;
30+
import com.sk89q.worldedit.world.block.BaseBlock;
31+
import com.sk89q.worldedit.world.block.BlockStateHolder;
32+
33+
/**
34+
* An extent that buffers all changes until completed.
35+
*/
36+
public class BatchingExtent extends AbstractBufferingExtent {
37+
38+
private final BlockMap<BaseBlock> blockMap = BlockMap.createForBaseBlock();
39+
private boolean enabled;
40+
41+
public BatchingExtent(Extent extent) {
42+
this(extent, true);
43+
}
44+
45+
public BatchingExtent(Extent extent, boolean enabled) {
46+
super(extent);
47+
this.enabled = enabled;
48+
}
49+
50+
public boolean isEnabled() {
51+
return enabled;
52+
}
53+
54+
public void setEnabled(boolean enabled) {
55+
this.enabled = enabled;
56+
}
57+
58+
public boolean commitRequired() {
59+
return enabled;
60+
}
61+
62+
@Override
63+
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 location, B block) throws WorldEditException {
64+
if (!enabled) {
65+
return setDelegateBlock(location, block);
66+
}
67+
blockMap.put(location, block.toBaseBlock());
68+
return true;
69+
}
70+
71+
@Override
72+
protected BaseBlock getBufferedFullBlock(BlockVector3 position) {
73+
if (!enabled) {
74+
// Early exit if we're not enabled.
75+
return null;
76+
}
77+
return blockMap.get(position);
78+
}
79+
80+
@Override
81+
protected Operation commitBefore() {
82+
if (!commitRequired()) {
83+
return null;
84+
}
85+
return new Operation() {
86+
87+
@Override
88+
public Operation resume(RunContext run) throws WorldEditException {
89+
try {
90+
blockMap.forEach((position, block) -> {
91+
try {
92+
getExtent().setBlock(position, block);
93+
} catch (WorldEditException e) {
94+
throw new RuntimeException(e);
95+
}
96+
});
97+
} catch (RuntimeException e) {
98+
Throwables.throwIfInstanceOf(e.getCause(), WorldEditException.class);
99+
throw e;
100+
}
101+
blockMap.clear();
102+
return null;
103+
}
104+
105+
@Override
106+
public void cancel() {
107+
}
108+
};
109+
}
110+
111+
}

worldedit-core/src/main/java/com/sk89q/worldedit/extent/reorder/ChunkBatchingExtent.java

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
import com.sk89q.worldedit.world.block.BlockStateHolder;
3232

3333
import java.util.ArrayList;
34-
import java.util.Iterator;
3534
import java.util.List;
3635

3736
/**
@@ -91,18 +90,11 @@ protected Operation commitBefore() {
9190
}
9291
return new Operation() {
9392

94-
// we get modified between create/resume -- only create this on resume to prevent CME
95-
private Iterator<BlockVector3> iterator;
96-
9793
@Override
9894
public Operation resume(RunContext run) throws WorldEditException {
99-
if (iterator == null) {
100-
List<BlockVector3> blockVectors = new ArrayList<>(blockMap.keySet());
101-
RegionOptimizedVectorSorter.sort(blockVectors);
102-
iterator = blockVectors.iterator();
103-
}
104-
while (iterator.hasNext()) {
105-
BlockVector3 position = iterator.next();
95+
List<BlockVector3> blockVectors = new ArrayList<>(blockMap.keySet());
96+
RegionOptimizedVectorSorter.sort(blockVectors);
97+
for (BlockVector3 position : blockVectors) {
10698
BaseBlock block = blockMap.get(position);
10799
getExtent().setBlock(position, block);
108100
}

0 commit comments

Comments
 (0)