Limit processing

This commit is contained in:
Jesse Boyd
2019-11-02 12:13:42 +01:00
parent 0b2bd862a0
commit df9e9e510a
102 changed files with 1339 additions and 501 deletions

View File

@ -24,26 +24,60 @@ import com.boydti.fawe.config.Settings;
import com.boydti.fawe.object.clipboard.CPUOptimizedClipboard;
import com.boydti.fawe.object.clipboard.DiskOptimizedClipboard;
import com.boydti.fawe.object.clipboard.MemoryOptimizedClipboard;
import com.boydti.fawe.object.clipboard.ReadOnlyClipboard;
import com.boydti.fawe.util.EditSessionBuilder;
import com.boydti.fawe.util.MaskTraverser;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter;
import com.sk89q.worldedit.extent.transform.BlockTransformExtent;
import com.sk89q.worldedit.function.RegionFunction;
import com.sk89q.worldedit.function.mask.ExistingBlockMask;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.function.operation.Operations;
import com.sk89q.worldedit.function.visitor.RegionVisitor;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.math.MutableBlockVector2;
import com.sk89q.worldedit.math.transform.Transform;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.regions.Regions;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.block.BlockState;
import javax.annotation.Nullable;
import java.io.Closeable;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;
import java.util.Iterator;
import java.util.UUID;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Specifies an object that implements something suitable as a "clipboard."
*/
public interface Clipboard extends Extent, Iterable<BlockVector3>, Closeable {
static Clipboard create(BlockVector3 size, UUID uuid) {
public static Clipboard create(Region region) {
checkNotNull(region);
checkNotNull(region.getWorld(),
"World cannot be null (use the other constructor for the region)");
EditSession session = new EditSessionBuilder(region.getWorld()).allowedRegionsEverywhere()
.autoQueue(false).build();
return ReadOnlyClipboard.of(session, region);
}
public static Clipboard create(BlockVector3 size, UUID uuid) {
if (Settings.IMP.CLIPBOARD.USE_DISK) {
return new DiskOptimizedClipboard(size, uuid);
} else if (Settings.IMP.CLIPBOARD.COMPRESSION_LEVEL == 0) {
@ -150,4 +184,204 @@ public interface Clipboard extends Extent, Iterable<BlockVector3>, Closeable {
default void close() {
}
/*
Utility methods
*/
/**
* Forwards to paste(world, to, true, true, null)
*
* @param world
* @param to
* @return
*/
default EditSession paste(World world, BlockVector3 to) {
return paste(world, to, true, true, null);
}
default void save(File file, ClipboardFormat format) throws IOException {
checkNotNull(file);
checkNotNull(format);
if (!file.exists()) {
File parent = file.getParentFile();
if (parent != null) {
parent.mkdirs();
}
file.createNewFile();
}
save(new FileOutputStream(file), format);
}
/**
* Save this schematic to a stream
*
* @param stream
* @param format
* @throws IOException
*/
default void save(OutputStream stream, ClipboardFormat format) throws IOException {
checkNotNull(stream);
checkNotNull(format);
try (ClipboardWriter writer = format.getWriter(stream)) {
writer.write(this);
}
}
default EditSession paste(World world, BlockVector3 to, boolean allowUndo, boolean pasteAir,
@Nullable Transform transform) {
return paste(world, to, allowUndo, pasteAir, true, transform);
}
/**
* Paste this schematic in a world
*
* @param world
* @param to
* @param allowUndo
* @param pasteAir
* @param transform
* @return
*/
default EditSession paste(World world, BlockVector3 to, boolean allowUndo, boolean pasteAir,
boolean copyEntities, @Nullable Transform transform) {
checkNotNull(world);
checkNotNull(to);
EditSession editSession;
if (world instanceof EditSession) {
editSession = (EditSession) world;
} else {
EditSessionBuilder builder = new EditSessionBuilder(world).autoQueue(true)
.checkMemory(false).allowedRegionsEverywhere().limitUnlimited();
if (allowUndo) {
editSession = builder.build();
} else {
editSession = builder.changeSetNull().fastmode(true).build();
}
}
Extent extent = this;
Mask sourceMask = editSession.getSourceMask();
if (transform != null && !transform.isIdentity()) {
extent = new BlockTransformExtent(this, transform);
} else if (sourceMask == null) {
paste(editSession, to, pasteAir);
editSession.flushQueue();
return editSession;
}
ForwardExtentCopy copy = new ForwardExtentCopy(extent, this.getRegion(),
this.getOrigin(), editSession, to);
if (transform != null && !transform.isIdentity()) {
copy.setTransform(transform);
}
copy.setCopyingEntities(copyEntities);
if (sourceMask != null) {
new MaskTraverser(sourceMask).reset(extent);
copy.setSourceMask(sourceMask);
editSession.setSourceMask(null);
}
if (!pasteAir) {
copy.setSourceMask(new ExistingBlockMask(this));
}
try {
Operations.completeLegacy(copy);
} catch (MaxChangedBlocksException e) {
e.printStackTrace();
}
editSession.flushQueue();
return editSession;
}
default void paste(Extent extent, BlockVector3 to, boolean pasteAir, @Nullable Transform transform) {
Extent source = this;
if (transform != null && !transform.isIdentity()) {
source = new BlockTransformExtent(this, transform);
}
ForwardExtentCopy copy = new ForwardExtentCopy(source, this.getRegion(), this.getOrigin(), extent, to);
if (transform != null) {
copy.setTransform(transform);
}
copy.setCopyingBiomes(this.hasBiomes());
if (extent instanceof EditSession) {
EditSession editSession = (EditSession) extent;
Mask sourceMask = editSession.getSourceMask();
if (sourceMask != null) {
new MaskTraverser(sourceMask).reset(extent);
copy.setSourceMask(sourceMask);
editSession.setSourceMask(null);
}
}
if (!pasteAir) {
copy.setSourceMask(new ExistingBlockMask(this));
}
Operations.completeBlindly(copy);
}
default void paste(Extent extent, BlockVector3 to, boolean pasteAir) {
Region region = this.getRegion().clone();
final BlockVector3 origin = this.getOrigin();
final boolean copyBiomes = this.hasBiomes();
// To must be relative to the clipboard origin ( player location - clipboard origin ) (as the locations supplied are relative to the world origin)
final int relx = to.getBlockX() - origin.getBlockX();
final int rely = to.getBlockY() - origin.getBlockY();
final int relz = to.getBlockZ() - origin.getBlockZ();
// this.apply(this, new Filter() {
// @Override
// public void applyBlock(FilterBlock block) {
//
// }
// });
System.out.println("Rel " + relx + "," + rely + "," + relz + " | " + to + " | " + origin);
System.out.println("TODO optimize paste using above apply");
Operation visitor = new RegionVisitor(region, new RegionFunction() {
// MutableBlockVector2 mpos2d_2 = new MutableBlockVector2();
MutableBlockVector2 mpos2d = new MutableBlockVector2();
{
mpos2d.setComponents(Integer.MIN_VALUE, Integer.MIN_VALUE);
}
@Override
public boolean apply(BlockVector3 mutable) throws WorldEditException {
BlockState block = getBlock(mutable);
System.out.println("Pos " + mutable);
int xx = mutable.getBlockX() + relx;
int zz = mutable.getBlockZ() + relz;
if (copyBiomes && xx != mpos2d.getBlockX() && zz != mpos2d.getBlockZ()) {
mpos2d.setComponents(xx, zz);
// extent.setBiome(mpos2d, clipboard.getBiome(mpos2d_2.setComponents(mutable.getBlockX(), mutable.getBlockZ())));
extent.setBiome(mpos2d, Clipboard.this
.getBiome(BlockVector2.at(mutable.getBlockX(), mutable.getBlockZ())));
}
if (!pasteAir && block.getBlockType().getMaterial().isAir()) {
return false;
}
extent.setBlock(xx, mutable.getBlockY() + rely, zz, block);
return false;
}
});
Operations.completeBlindly(visitor);
// Entity offset is the paste location subtract the clipboard origin (entity's location is already relative to the world origin)
final int entityOffsetX = to.getBlockX() - origin.getBlockX();
final int entityOffsetY = to.getBlockY() - origin.getBlockY();
final int entityOffsetZ = to.getBlockZ() - origin.getBlockZ();
// entities
for (Entity entity : this.getEntities()) {
// skip players on pasting schematic
if (entity.getState() != null && entity.getState().getType().getId()
.equals("minecraft:player")) {
continue;
}
Location pos = entity.getLocation();
Location newPos = new Location(pos.getExtent(), pos.getX() + entityOffsetX,
pos.getY() + entityOffsetY, pos.getZ() + entityOffsetZ, pos.getYaw(),
pos.getPitch());
extent.createEntity(newPos, entity.getState());
}
}
}

View File

@ -25,7 +25,6 @@ import com.boydti.fawe.config.Settings;
import com.boydti.fawe.object.RunnableVal;
import com.boydti.fawe.object.clipboard.URIClipboardHolder;
import com.boydti.fawe.object.io.PGZIPOutputStream;
import com.boydti.fawe.object.schematic.Schematic;
import com.boydti.fawe.util.MainUtil;
import com.google.gson.Gson;
import com.sk89q.worldedit.LocalSession;
@ -127,12 +126,12 @@ public interface ClipboardFormat {
return holder;
}
default Schematic load(File file) throws IOException {
default Clipboard load(File file) throws IOException {
return load(new FileInputStream(file));
}
default Schematic load(InputStream stream) throws IOException {
return new Schematic(getReader(stream).read());
default Clipboard load(InputStream stream) throws IOException {
return getReader(stream).read();
}