Skip to content

Commit deb26cb

Browse files
committed
Restore BatchingExtent for fallback
1 parent 3fe0aac commit deb26cb

File tree

2 files changed

+128
-3
lines changed

2 files changed

+128
-3
lines changed

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

+17-3
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;
@@ -202,6 +203,7 @@ public String getDisplayName() {
202203

203204
private @Nullable SideEffectExtent sideEffectExtent;
204205
private final SurvivalModeExtent survivalExtent;
206+
private @Nullable BatchingExtent batchingExtent;
205207
private @Nullable ChunkBatchingExtent chunkBatchingExtent;
206208
private final BlockBagExtent blockBagExtent;
207209
@SuppressWarnings("deprecation")
@@ -256,10 +258,11 @@ public String getDisplayName() {
256258

257259
// These extents are ALWAYS used
258260
sideEffectExtent = new SideEffectExtent(world);
259-
NativeWorld nativeInterface;
260-
if (WorldEdit.getInstance().getConfiguration().chunkSectionEditing
261+
NativeWorld nativeInterface = null;
262+
boolean usingNativeInterface = WorldEdit.getInstance().getConfiguration().chunkSectionEditing
261263
&& world instanceof AbstractWorld internalWorld
262-
&& (nativeInterface = internalWorld.getNativeInterface()) != null) {
264+
&& (nativeInterface = internalWorld.getNativeInterface()) != null;
265+
if (usingNativeInterface) {
263266
extent = traceIfNeeded(new SectionBufferingExtent(nativeInterface, sideEffectExtent));
264267
} else {
265268
extent = traceIfNeeded(sideEffectExtent);
@@ -278,6 +281,11 @@ public String getDisplayName() {
278281
this.bypassReorderHistory = traceIfNeeded(new DataValidatorExtent(extent, world));
279282

280283
// This extent can be skipped by calling rawSetBlock()
284+
if (!usingNativeInterface) {
285+
// We need to ensure that blocks are not immediately committed to the world for masks
286+
// This is done by the SectionBufferingExtent normally, but if we can't use it we need a fallback
287+
extent = traceIfNeeded(batchingExtent = new BatchingExtent(extent));
288+
}
281289
@SuppressWarnings("deprecation")
282290
MultiStageReorder reorder = new MultiStageReorder(extent, false);
283291
extent = traceIfNeeded(reorderExtent = reorder);
@@ -631,6 +639,9 @@ public void setBatchingChunks(boolean batchingChunks) {
631639
internalFlushSession();
632640
}
633641
chunkBatchingExtent.setEnabled(batchingChunks);
642+
if (batchingExtent != null) {
643+
batchingExtent.setEnabled(!batchingChunks);
644+
}
634645
}
635646

636647
/**
@@ -659,6 +670,9 @@ public void disableBuffering() {
659670
setReorderMode(ReorderMode.NONE);
660671
if (chunkBatchingExtent != null) {
661672
chunkBatchingExtent.setEnabled(false);
673+
if (batchingExtent != null) {
674+
batchingExtent.setEnabled(true);
675+
}
662676
}
663677
}
664678

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+
}

0 commit comments

Comments
 (0)