mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2025-07-06 04:46:40 +00:00
upstream changes
This commit is contained in:
@ -19,8 +19,7 @@
|
||||
|
||||
package com.sk89q.worldedit.extent.reorder;
|
||||
|
||||
import com.google.common.collect.Table;
|
||||
import com.google.common.collect.TreeBasedTable;
|
||||
import com.google.common.collect.ImmutableSortedSet;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.extent.AbstractBufferingExtent;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
@ -28,15 +27,14 @@ import com.sk89q.worldedit.function.operation.Operation;
|
||||
import com.sk89q.worldedit.function.operation.RunContext;
|
||||
import com.sk89q.worldedit.math.BlockVector2;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.math.RegionOptimizedComparator;
|
||||
import com.sk89q.worldedit.util.collection.BlockMap;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* A special extent that batches changes into Minecraft chunks. This helps
|
||||
@ -46,17 +44,7 @@ import java.util.Set;
|
||||
*/
|
||||
public class ChunkBatchingExtent extends AbstractBufferingExtent {
|
||||
|
||||
/**
|
||||
* 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<BlockVector2> REGION_OPTIMIZED_SORT =
|
||||
Comparator.comparing((BlockVector2 vec) -> vec.shr(5), BlockVector2.COMPARING_GRID_ARRANGEMENT)
|
||||
.thenComparing(BlockVector2.COMPARING_GRID_ARRANGEMENT);
|
||||
|
||||
private final Table<BlockVector2, BlockVector3, BaseBlock> batches =
|
||||
TreeBasedTable.create(REGION_OPTIMIZED_SORT, BlockVector3.sortByCoordsYzx());
|
||||
private final Set<BlockVector3> containedBlocks = new HashSet<>();
|
||||
private final BlockMap blockMap = BlockMap.create();
|
||||
private boolean enabled;
|
||||
|
||||
public ChunkBatchingExtent(Extent extent) {
|
||||
@ -80,32 +68,20 @@ public class ChunkBatchingExtent extends AbstractBufferingExtent {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
private BlockVector2 getChunkPos(BlockVector3 location) {
|
||||
return location.shr(4).toBlockVector2();
|
||||
}
|
||||
|
||||
private BlockVector3 getInChunkPos(BlockVector3 location) {
|
||||
return BlockVector3.at(location.getX() & 15, location.getY(), location.getZ() & 15);
|
||||
}
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 location, B block) throws WorldEditException {
|
||||
if (!enabled) {
|
||||
return setDelegateBlock(location, block);
|
||||
}
|
||||
BlockVector2 chunkPos = getChunkPos(location);
|
||||
BlockVector3 inChunkPos = getInChunkPos(location);
|
||||
batches.put(chunkPos, inChunkPos, block.toBaseBlock());
|
||||
containedBlocks.add(location);
|
||||
blockMap.put(location, block.toBaseBlock());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Optional<BaseBlock> getBufferedBlock(BlockVector3 position) {
|
||||
if (!containedBlocks.contains(position)) {
|
||||
return Optional.empty();
|
||||
}
|
||||
return Optional.of(batches.get(getChunkPos(position), getInChunkPos(position)));
|
||||
return Optional.ofNullable(blockMap.get(position));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Operation commitBefore() {
|
||||
if (!commitRequired()) {
|
||||
@ -114,24 +90,21 @@ public class ChunkBatchingExtent extends AbstractBufferingExtent {
|
||||
return new Operation() {
|
||||
|
||||
// we get modified between create/resume -- only create this on resume to prevent CME
|
||||
private Iterator<Map.Entry<BlockVector2, Map<BlockVector3, BaseBlock>>> batchIterator;
|
||||
private Iterator<BlockVector3> iterator;
|
||||
|
||||
@Override
|
||||
public Operation resume(RunContext run) throws WorldEditException {
|
||||
if (batchIterator == null) {
|
||||
batchIterator = batches.rowMap().entrySet().iterator();
|
||||
if (iterator == null) {
|
||||
iterator = ImmutableSortedSet.copyOf(RegionOptimizedComparator.INSTANCE,
|
||||
blockMap.keySet()).iterator();
|
||||
}
|
||||
if (!batchIterator.hasNext()) {
|
||||
return null;
|
||||
while (iterator.hasNext()) {
|
||||
BlockVector3 position = iterator.next();
|
||||
BaseBlock block = blockMap.get(position);
|
||||
getExtent().setBlock(position, block);
|
||||
}
|
||||
Map.Entry<BlockVector2, Map<BlockVector3, BaseBlock>> next = batchIterator.next();
|
||||
BlockVector3 chunkOffset = next.getKey().toBlockVector3().shl(4);
|
||||
for (Map.Entry<BlockVector3, BaseBlock> block : next.getValue().entrySet()) {
|
||||
getExtent().setBlock(block.getKey().add(chunkOffset), block.getValue());
|
||||
containedBlocks.remove(block.getKey());
|
||||
}
|
||||
batchIterator.remove();
|
||||
return this;
|
||||
blockMap.clear();
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -24,23 +24,23 @@ import com.sk89q.worldedit.extent.AbstractBufferingExtent;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.function.operation.Operation;
|
||||
import com.sk89q.worldedit.function.operation.OperationQueue;
|
||||
import com.sk89q.worldedit.function.operation.SetLocatedBlocks;
|
||||
import com.sk89q.worldedit.function.operation.RunContext;
|
||||
import com.sk89q.worldedit.function.operation.SetBlockMap;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.util.collection.LocatedBlockList;
|
||||
import com.sk89q.worldedit.util.collection.BlockMap;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockCategories;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import com.sk89q.worldedit.world.block.BlockType;
|
||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Re-orders blocks into several stages.
|
||||
@ -142,8 +142,7 @@ public class MultiStageReorder extends AbstractBufferingExtent implements Reorde
|
||||
priorityMap.put(BlockTypes.MOVING_PISTON, PlacementPriority.FINAL);
|
||||
}
|
||||
|
||||
private final Set<BlockVector3> containedBlocks = new HashSet<>();
|
||||
private Map<PlacementPriority, LocatedBlockList> stages = new HashMap<>();
|
||||
private Map<PlacementPriority, BlockMap> stages = new HashMap<>();
|
||||
|
||||
private boolean enabled;
|
||||
|
||||
@ -177,7 +176,7 @@ public class MultiStageReorder extends AbstractBufferingExtent implements Reorde
|
||||
this.enabled = enabled;
|
||||
|
||||
for (PlacementPriority priority : PlacementPriority.values()) {
|
||||
stages.put(priority, new LocatedBlockList());
|
||||
stages.put(priority, BlockMap.create());
|
||||
}
|
||||
}
|
||||
|
||||
@ -219,7 +218,7 @@ public class MultiStageReorder extends AbstractBufferingExtent implements Reorde
|
||||
return setDelegateBlock(location, block);
|
||||
}
|
||||
|
||||
BlockState existing = getBlock(location);
|
||||
BlockState existing = getExtent().getBlock(location);
|
||||
PlacementPriority priority = getPlacementPriority(block);
|
||||
PlacementPriority srcPriority = getPlacementPriority(existing);
|
||||
|
||||
@ -228,13 +227,13 @@ public class MultiStageReorder extends AbstractBufferingExtent implements Reorde
|
||||
|
||||
switch (srcPriority) {
|
||||
case FINAL:
|
||||
stages.get(PlacementPriority.CLEAR_FINAL).add(location, replacement);
|
||||
stages.get(PlacementPriority.CLEAR_FINAL).put(location, replacement);
|
||||
break;
|
||||
case LATE:
|
||||
stages.get(PlacementPriority.CLEAR_LATE).add(location, replacement);
|
||||
stages.get(PlacementPriority.CLEAR_LATE).put(location, replacement);
|
||||
break;
|
||||
case LAST:
|
||||
stages.get(PlacementPriority.CLEAR_LAST).add(location, replacement);
|
||||
stages.get(PlacementPriority.CLEAR_LAST).put(location, replacement);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -243,16 +242,12 @@ public class MultiStageReorder extends AbstractBufferingExtent implements Reorde
|
||||
}
|
||||
}
|
||||
|
||||
stages.get(priority).add(location, block);
|
||||
containedBlocks.add(location);
|
||||
stages.get(priority).put(location, block.toBaseBlock());
|
||||
return !existing.equalsFuzzy(block);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Optional<BaseBlock> getBufferedBlock(BlockVector3 position) {
|
||||
if (!containedBlocks.contains(position)) {
|
||||
return Optional.empty();
|
||||
}
|
||||
return stages.values().stream()
|
||||
.map(blocks -> blocks.get(position))
|
||||
.filter(Objects::nonNull)
|
||||
@ -266,7 +261,17 @@ public class MultiStageReorder extends AbstractBufferingExtent implements Reorde
|
||||
}
|
||||
List<Operation> operations = new ArrayList<>();
|
||||
for (PlacementPriority priority : PlacementPriority.values()) {
|
||||
operations.add(new SetLocatedBlocks(getExtent(), stages.get(priority)));
|
||||
BlockMap blocks = stages.get(priority);
|
||||
operations.add(new SetBlockMap(getExtent(), blocks) {
|
||||
@Override
|
||||
public Operation resume(RunContext run) throws WorldEditException {
|
||||
Operation operation = super.resume(run);
|
||||
if (operation == null) {
|
||||
blocks.clear();
|
||||
}
|
||||
return operation;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return new OperationQueue(operations);
|
||||
|
Reference in New Issue
Block a user