Skip to content

Commit 3f1652b

Browse files
committed
Restore BatchingExtent for fallback
1 parent 899d6c8 commit 3f1652b

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

Lines changed: 17 additions & 3 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;
@@ -203,6 +204,7 @@ public String getDisplayName() {
203204

204205
private @Nullable SideEffectExtent sideEffectExtent;
205206
private final SurvivalModeExtent survivalExtent;
207+
private @Nullable BatchingExtent batchingExtent;
206208
private @Nullable ChunkBatchingExtent chunkBatchingExtent;
207209
private final BlockBagExtent blockBagExtent;
208210
@SuppressWarnings("deprecation")
@@ -257,10 +259,11 @@ public String getDisplayName() {
257259

258260
// These extents are ALWAYS used
259261
sideEffectExtent = new SideEffectExtent(world);
260-
NativeWorld nativeInterface;
261-
if (WorldEdit.getInstance().getConfiguration().chunkSectionEditing
262+
NativeWorld nativeInterface = null;
263+
boolean usingNativeInterface = WorldEdit.getInstance().getConfiguration().chunkSectionEditing
262264
&& world instanceof AbstractWorld internalWorld
263-
&& (nativeInterface = internalWorld.getNativeInterface()) != null) {
265+
&& (nativeInterface = internalWorld.getNativeInterface()) != null;
266+
if (usingNativeInterface) {
264267
extent = traceIfNeeded(new SectionBufferingExtent(nativeInterface, sideEffectExtent));
265268
} else {
266269
extent = traceIfNeeded(sideEffectExtent);
@@ -280,6 +283,11 @@ public String getDisplayName() {
280283
this.bypassReorderHistory = traceIfNeeded(new DataValidatorExtent(extent, world));
281284

282285
// This extent can be skipped by calling rawSetBlock()
286+
if (!usingNativeInterface) {
287+
// We need to ensure that blocks are not immediately committed to the world for masks
288+
// This is done by the SectionBufferingExtent normally, but if we can't use it we need a fallback
289+
extent = traceIfNeeded(batchingExtent = new BatchingExtent(extent));
290+
}
283291
@SuppressWarnings("deprecation")
284292
MultiStageReorder reorder = new MultiStageReorder(extent, false);
285293
extent = traceIfNeeded(reorderExtent = reorder);
@@ -633,6 +641,9 @@ public void setBatchingChunks(boolean batchingChunks) {
633641
internalFlushSession();
634642
}
635643
chunkBatchingExtent.setEnabled(batchingChunks);
644+
if (batchingExtent != null) {
645+
batchingExtent.setEnabled(!batchingChunks);
646+
}
636647
}
637648

638649
/**
@@ -661,6 +672,9 @@ public void disableBuffering() {
661672
setReorderMode(ReorderMode.NONE);
662673
if (chunkBatchingExtent != null) {
663674
chunkBatchingExtent.setEnabled(false);
675+
if (batchingExtent != null) {
676+
batchingExtent.setEnabled(true);
677+
}
664678
}
665679
}
666680

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

0 commit comments

Comments
 (0)