mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2025-07-12 04:18:34 +00:00
Rework block-batching, create draft of chunk batching
This commit is contained in:
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* WorldEdit, a Minecraft world manipulation toolkit
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldEdit team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.sk89q.worldedit.extent.reorder;
|
||||
|
||||
import com.sk89q.worldedit.BlockVector2D;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.Vector2D;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.function.operation.Operation;
|
||||
import com.sk89q.worldedit.function.operation.RunContext;
|
||||
import com.sk89q.worldedit.function.operation.SetLocatedBlocks;
|
||||
import com.sk89q.worldedit.util.collection.LocatedBlockList;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.SortedMap;
|
||||
import java.util.TreeMap;
|
||||
|
||||
/**
|
||||
* A special extent that batches changes into Minecraft chunks. This helps
|
||||
* improve the speed of setting the blocks, since chunks do not need to be
|
||||
* loaded repeatedly, however it does take more memory due to caching the
|
||||
* blocks.
|
||||
*/
|
||||
public class ChunkBatchingExtent extends AbstractDelegateExtent {
|
||||
|
||||
/**
|
||||
* Comparator optimized for sorting chunks by the region file they reside
|
||||
* in. This allows for file caches to be used while loading the chunk.
|
||||
*/
|
||||
private static final Comparator<Vector2D> REGION_OPTIMIZED_SORT =
|
||||
Comparator.<Vector2D, Vector2D>comparing(vec -> vec.divide(32).floor(), Vector2D.COMPARING_GRID_ARRANGEMENT)
|
||||
.thenComparing(Vector2D.COMPARING_GRID_ARRANGEMENT);
|
||||
|
||||
private final SortedMap<BlockVector2D, LocatedBlockList> batches = new TreeMap<>(REGION_OPTIMIZED_SORT);
|
||||
|
||||
protected ChunkBatchingExtent(Extent extent) {
|
||||
super(extent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBlock(Vector location, BlockStateHolder block) throws WorldEditException {
|
||||
BlockVector2D chunkPos = new BlockVector2D(location.getBlockX() >> 4, location.getBlockZ() >> 4);
|
||||
batches.computeIfAbsent(chunkPos, k -> new LocatedBlockList()).add(location, block);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Operation commitBefore() {
|
||||
return new Operation() {
|
||||
|
||||
private final Iterator<LocatedBlockList> batchIterator = batches.values().iterator();
|
||||
|
||||
@Override
|
||||
public Operation resume(RunContext run) throws WorldEditException {
|
||||
if (!batchIterator.hasNext()) {
|
||||
return null;
|
||||
}
|
||||
new SetLocatedBlocks(getExtent(), batchIterator.next()).resume(run);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addStatusMessages(List<String> messages) {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
@ -19,19 +19,20 @@
|
||||
|
||||
package com.sk89q.worldedit.extent.reorder;
|
||||
|
||||
import com.google.common.collect.Iterators;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.sk89q.worldedit.BlockVector;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.blocks.Blocks;
|
||||
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.function.operation.BlockMapEntryPlacer;
|
||||
import com.sk89q.worldedit.function.operation.Operation;
|
||||
import com.sk89q.worldedit.function.operation.OperationQueue;
|
||||
import com.sk89q.worldedit.function.operation.RunContext;
|
||||
import com.sk89q.worldedit.function.operation.SetLocatedBlocks;
|
||||
import com.sk89q.worldedit.registry.state.Property;
|
||||
import com.sk89q.worldedit.util.collection.TupleArrayList;
|
||||
import com.sk89q.worldedit.util.LocatedBlock;
|
||||
import com.sk89q.worldedit.util.collection.LocatedBlockList;
|
||||
import com.sk89q.worldedit.world.block.BlockCategories;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
@ -50,9 +51,9 @@ import java.util.Set;
|
||||
*/
|
||||
public class MultiStageReorder extends AbstractDelegateExtent implements ReorderingExtent {
|
||||
|
||||
private TupleArrayList<BlockVector, BlockStateHolder> stage1 = new TupleArrayList<>();
|
||||
private TupleArrayList<BlockVector, BlockStateHolder> stage2 = new TupleArrayList<>();
|
||||
private TupleArrayList<BlockVector, BlockStateHolder> stage3 = new TupleArrayList<>();
|
||||
private LocatedBlockList stage1 = new LocatedBlockList();
|
||||
private LocatedBlockList stage2 = new LocatedBlockList();
|
||||
private LocatedBlockList stage3 = new LocatedBlockList();
|
||||
private boolean enabled;
|
||||
|
||||
/**
|
||||
@ -103,18 +104,18 @@ public class MultiStageReorder extends AbstractDelegateExtent implements Reorder
|
||||
|
||||
if (Blocks.shouldPlaceLast(block.getBlockType())) {
|
||||
// Place torches, etc. last
|
||||
stage2.put(location.toBlockVector(), block);
|
||||
stage2.add(location.toBlockVector(), block);
|
||||
return !existing.equalsFuzzy(block);
|
||||
} else if (Blocks.shouldPlaceFinal(block.getBlockType())) {
|
||||
// Place signs, reed, etc even later
|
||||
stage3.put(location.toBlockVector(), block);
|
||||
stage3.add(location.toBlockVector(), block);
|
||||
return !existing.equalsFuzzy(block);
|
||||
} else if (Blocks.shouldPlaceLast(existing.getBlockType())) {
|
||||
// Destroy torches, etc. first
|
||||
super.setBlock(location, BlockTypes.AIR.getDefaultState());
|
||||
return super.setBlock(location, block);
|
||||
} else {
|
||||
stage1.put(location.toBlockVector(), block);
|
||||
stage1.add(location.toBlockVector(), block);
|
||||
return !existing.equalsFuzzy(block);
|
||||
}
|
||||
}
|
||||
@ -122,9 +123,9 @@ public class MultiStageReorder extends AbstractDelegateExtent implements Reorder
|
||||
@Override
|
||||
public Operation commitBefore() {
|
||||
return new OperationQueue(
|
||||
new BlockMapEntryPlacer(
|
||||
new SetLocatedBlocks(
|
||||
getExtent(),
|
||||
Iterators.concat(stage1.iterator(), stage2.iterator())),
|
||||
Iterables.concat(stage1, stage2)),
|
||||
new Stage3Committer());
|
||||
}
|
||||
|
||||
@ -136,10 +137,10 @@ public class MultiStageReorder extends AbstractDelegateExtent implements Reorder
|
||||
|
||||
final Set<BlockVector> blocks = new HashSet<>();
|
||||
final Map<BlockVector, BlockStateHolder> blockTypes = new HashMap<>();
|
||||
for (Map.Entry<BlockVector, BlockStateHolder> entry : stage3) {
|
||||
final BlockVector pt = entry.getKey();
|
||||
for (LocatedBlock entry : stage3) {
|
||||
final BlockVector pt = entry.getLocation().toBlockVector();
|
||||
blocks.add(pt);
|
||||
blockTypes.put(pt, entry.getValue());
|
||||
blockTypes.put(pt, entry.getBlock());
|
||||
}
|
||||
|
||||
while (!blocks.isEmpty()) {
|
||||
|
Reference in New Issue
Block a user