Optimize copy and load
This commit is contained in:
parent
1f539f4b80
commit
1bd8c3935a
@ -28,7 +28,7 @@ ext {
|
|||||||
date = git.head().date.format("yy.MM.dd")
|
date = git.head().date.format("yy.MM.dd")
|
||||||
revision = "-${git.head().abbreviatedId}"
|
revision = "-${git.head().abbreviatedId}"
|
||||||
parents = git.head().parentIds;
|
parents = git.head().parentIds;
|
||||||
index = -91; // Offset to mach CI
|
index = -92; // Offset to mach CI
|
||||||
int major, minor, patch;
|
int major, minor, patch;
|
||||||
major = minor = patch = 0;
|
major = minor = patch = 0;
|
||||||
for (;parents != null && !parents.isEmpty();index++) {
|
for (;parents != null && !parents.isEmpty();index++) {
|
||||||
|
@ -105,6 +105,7 @@ import com.sk89q.worldedit.regions.CuboidRegion;
|
|||||||
import com.sk89q.worldedit.regions.EllipsoidRegion;
|
import com.sk89q.worldedit.regions.EllipsoidRegion;
|
||||||
import com.sk89q.worldedit.regions.selector.CuboidRegionSelector;
|
import com.sk89q.worldedit.regions.selector.CuboidRegionSelector;
|
||||||
import com.sk89q.worldedit.regions.shape.ArbitraryShape;
|
import com.sk89q.worldedit.regions.shape.ArbitraryShape;
|
||||||
|
import com.sk89q.worldedit.session.ClipboardHolder;
|
||||||
import com.sk89q.worldedit.session.PasteBuilder;
|
import com.sk89q.worldedit.session.PasteBuilder;
|
||||||
import com.sk89q.worldedit.session.SessionManager;
|
import com.sk89q.worldedit.session.SessionManager;
|
||||||
import com.sk89q.worldedit.session.request.Request;
|
import com.sk89q.worldedit.session.request.Request;
|
||||||
@ -460,6 +461,7 @@ public class Fawe {
|
|||||||
// Clipboards
|
// Clipboards
|
||||||
BlockArrayClipboard.inject(); // Optimizations + disk
|
BlockArrayClipboard.inject(); // Optimizations + disk
|
||||||
CuboidClipboard.inject(); // Optimizations
|
CuboidClipboard.inject(); // Optimizations
|
||||||
|
ClipboardHolder.inject(); // Closeable
|
||||||
// Regions
|
// Regions
|
||||||
CuboidRegion.inject(); // Optimizations
|
CuboidRegion.inject(); // Optimizations
|
||||||
// Extents
|
// Extents
|
||||||
|
@ -39,19 +39,19 @@ public class SchematicStreamer extends NBTStreamer {
|
|||||||
addReader("Schematic.Blocks.#", new ByteReader() {
|
addReader("Schematic.Blocks.#", new ByteReader() {
|
||||||
@Override
|
@Override
|
||||||
public void run(int index, int value) {
|
public void run(int index, int value) {
|
||||||
fc.setId(index, value);
|
if (value != 0) fc.setId(index, value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
addReader("Schematic.Data.#", new ByteReader() {
|
addReader("Schematic.Data.#", new ByteReader() {
|
||||||
@Override
|
@Override
|
||||||
public void run(int index, int value) {
|
public void run(int index, int value) {
|
||||||
fc.setData(index, value);
|
if (value != 0) fc.setData(index, value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
addReader("Schematic.AddBlocks.#", new ByteReader() {
|
addReader("Schematic.AddBlocks.#", new ByteReader() {
|
||||||
@Override
|
@Override
|
||||||
public void run(int index, int value) {
|
public void run(int index, int value) {
|
||||||
fc.setAdd(index, value);
|
if (value != 0) fc.setAdd(index, value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -71,6 +71,16 @@ public class AbstractDelegateFaweClipboard extends FaweClipboard {
|
|||||||
parent.setDimensions(dimensions);
|
parent.setDimensions(dimensions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void flush() {
|
||||||
|
parent.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
parent.close();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Vector getDimensions() {
|
public Vector getDimensions() {
|
||||||
return parent.getDimensions();
|
return parent.getDimensions();
|
||||||
|
@ -5,7 +5,6 @@ import com.boydti.fawe.FaweCache;
|
|||||||
import com.boydti.fawe.config.Settings;
|
import com.boydti.fawe.config.Settings;
|
||||||
import com.boydti.fawe.jnbt.NBTStreamer;
|
import com.boydti.fawe.jnbt.NBTStreamer;
|
||||||
import com.boydti.fawe.object.IntegerTrio;
|
import com.boydti.fawe.object.IntegerTrio;
|
||||||
import com.boydti.fawe.object.io.BufferedRandomAccessFile;
|
|
||||||
import com.boydti.fawe.util.MainUtil;
|
import com.boydti.fawe.util.MainUtil;
|
||||||
import com.boydti.fawe.util.ReflectionUtils;
|
import com.boydti.fawe.util.ReflectionUtils;
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
@ -22,6 +21,11 @@ import com.sk89q.worldedit.regions.CuboidRegion;
|
|||||||
import java.io.Closeable;
|
import java.io.Closeable;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.RandomAccessFile;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.MappedByteBuffer;
|
||||||
|
import java.nio.channels.FileChannel;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@ -50,8 +54,11 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
|||||||
private final HashSet<ClipboardEntity> entities;
|
private final HashSet<ClipboardEntity> entities;
|
||||||
private final File file;
|
private final File file;
|
||||||
|
|
||||||
private final BufferedRandomAccessFile raf;
|
private RandomAccessFile braf;
|
||||||
|
private MappedByteBuffer mbb;
|
||||||
|
|
||||||
private int last;
|
private int last;
|
||||||
|
private FileChannel fc;
|
||||||
|
|
||||||
public DiskOptimizedClipboard(int width, int height, int length, UUID uuid) {
|
public DiskOptimizedClipboard(int width, int height, int length, UUID uuid) {
|
||||||
this(width, height, length, MainUtil.getFile(Fawe.imp().getDirectory(), Settings.IMP.PATHS.CLIPBOARD + File.separator + uuid + ".bd"));
|
this(width, height, length, MainUtil.getFile(Fawe.imp().getDirectory(), Settings.IMP.PATHS.CLIPBOARD + File.separator + uuid + ".bd"));
|
||||||
@ -62,14 +69,16 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
|||||||
nbtMap = new HashMap<>();
|
nbtMap = new HashMap<>();
|
||||||
entities = new HashSet<>();
|
entities = new HashSet<>();
|
||||||
this.file = file;
|
this.file = file;
|
||||||
this.raf = new BufferedRandomAccessFile(file, "rw", 16);
|
this.braf = new RandomAccessFile(file, "rw");
|
||||||
raf.setLength(file.length());
|
braf.setLength(file.length());
|
||||||
long size = (raf.length() - HEADER_SIZE) >> 1;
|
init();
|
||||||
raf.seek(2);
|
long size = (braf.length() - HEADER_SIZE) >> 1;
|
||||||
|
|
||||||
|
mbb.position(2);
|
||||||
last = Integer.MIN_VALUE;
|
last = Integer.MIN_VALUE;
|
||||||
width = (int) raf.readChar();
|
width = (int) mbb.getChar();
|
||||||
height = (int) raf.readChar();
|
height = (int) mbb.getChar();
|
||||||
length = (int) raf.readChar();
|
length = (int) mbb.getChar();
|
||||||
area = width * length;
|
area = width * length;
|
||||||
autoCloseTask();
|
autoCloseTask();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@ -77,6 +86,13 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void init() throws IOException {
|
||||||
|
if (this.fc == null) {
|
||||||
|
this.fc = braf.getChannel();
|
||||||
|
this.mbb = fc.map(FileChannel.MapMode.READ_WRITE, 0, file.length());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Vector getDimensions() {
|
public Vector getDimensions() {
|
||||||
return new Vector(width, height, length);
|
return new Vector(width, height, length);
|
||||||
@ -90,15 +106,15 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
raf.seek(8);
|
mbb.position(8);
|
||||||
last = Integer.MIN_VALUE;
|
last = Integer.MIN_VALUE;
|
||||||
int ox = raf.readShort();
|
int ox = mbb.getShort();
|
||||||
int oy = raf.readShort();
|
int oy = mbb.getShort();
|
||||||
int oz = raf.readShort();
|
int oz = mbb.getShort();
|
||||||
BlockArrayClipboard clipboard = new BlockArrayClipboard(region, this);
|
BlockArrayClipboard clipboard = new BlockArrayClipboard(region, this);
|
||||||
clipboard.setOrigin(new Vector(ox, oy, oz));
|
clipboard.setOrigin(new Vector(ox, oy, oz));
|
||||||
return clipboard;
|
return clipboard;
|
||||||
} catch (IOException e) {
|
} catch (Throwable e) {
|
||||||
MainUtil.handleError(e);
|
MainUtil.handleError(e);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@ -115,22 +131,26 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
|||||||
this.area = width * length;
|
this.area = width * length;
|
||||||
try {
|
try {
|
||||||
if (!file.exists()) {
|
if (!file.exists()) {
|
||||||
|
File parent = file.getParentFile();
|
||||||
|
if (parent != null) {
|
||||||
file.getParentFile().mkdirs();
|
file.getParentFile().mkdirs();
|
||||||
|
}
|
||||||
file.createNewFile();
|
file.createNewFile();
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
MainUtil.handleError(e);
|
MainUtil.handleError(e);
|
||||||
}
|
}
|
||||||
this.raf = new BufferedRandomAccessFile(file, "rw", 16);
|
this.braf = new RandomAccessFile(file, "rw");
|
||||||
long volume = (long) width * (long) height * (long) length * 2l + (long) HEADER_SIZE;
|
long volume = (long) width * (long) height * (long) length * 2l + (long) HEADER_SIZE;
|
||||||
raf.setLength(0);
|
braf.setLength(0);
|
||||||
raf.setLength(volume);
|
braf.setLength(volume);
|
||||||
|
init();
|
||||||
// write length etc
|
// write length etc
|
||||||
raf.seek(2);
|
mbb.position(2);
|
||||||
last = Integer.MIN_VALUE;
|
last = Integer.MIN_VALUE;
|
||||||
raf.writeChar(width);
|
mbb.putChar((char) width);
|
||||||
raf.writeChar(height);
|
mbb.putChar((char) height);
|
||||||
raf.writeChar(length);
|
mbb.putChar((char) length);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
@ -139,12 +159,12 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
|||||||
@Override
|
@Override
|
||||||
public void setOrigin(Vector offset) {
|
public void setOrigin(Vector offset) {
|
||||||
try {
|
try {
|
||||||
raf.seek(8);
|
mbb.position(8);
|
||||||
last = Integer.MIN_VALUE;
|
last = Integer.MIN_VALUE;
|
||||||
raf.writeShort(offset.getBlockX());
|
mbb.putShort((short) offset.getBlockX());
|
||||||
raf.writeShort(offset.getBlockY());
|
mbb.putShort((short) offset.getBlockY());
|
||||||
raf.writeShort(offset.getBlockZ());
|
mbb.putShort((short) offset.getBlockZ());
|
||||||
} catch (IOException e) {
|
} catch (Throwable e) {
|
||||||
MainUtil.handleError(e);
|
MainUtil.handleError(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -157,34 +177,51 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
|||||||
length = dimensions.getBlockZ();
|
length = dimensions.getBlockZ();
|
||||||
area = width * length;
|
area = width * length;
|
||||||
long size = width * height * length * 2l + HEADER_SIZE;
|
long size = width * height * length * 2l + HEADER_SIZE;
|
||||||
raf.setLength(size);
|
braf.setLength(size);
|
||||||
raf.seek(2);
|
init();
|
||||||
|
mbb.position(2);
|
||||||
last = Integer.MIN_VALUE;
|
last = Integer.MIN_VALUE;
|
||||||
raf.writeChar(width);
|
mbb.putChar((char) width);
|
||||||
raf.writeChar(height);
|
mbb.putChar((char) height);
|
||||||
raf.writeChar(length);
|
mbb.putChar((char) length);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
MainUtil.handleError(e);
|
MainUtil.handleError(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void flush() {
|
public void flush() {
|
||||||
try {
|
mbb.force();
|
||||||
raf.flush();
|
|
||||||
} catch (IOException e) {
|
|
||||||
MainUtil.handleError(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public DiskOptimizedClipboard(int width, int height, int length) {
|
public DiskOptimizedClipboard(int width, int height, int length) {
|
||||||
this(width, height, length, MainUtil.getFile(Fawe.imp().getDirectory(), Settings.IMP.PATHS.CLIPBOARD + File.separator + UUID.randomUUID() + ".bd"));
|
this(width, height, length, MainUtil.getFile(Fawe.imp().getDirectory(), Settings.IMP.PATHS.CLIPBOARD + File.separator + UUID.randomUUID() + ".bd"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void closeDirectBuffer(ByteBuffer cb) {
|
||||||
|
if (cb==null || !cb.isDirect()) return;
|
||||||
|
|
||||||
|
// we could use this type cast and call functions without reflection code,
|
||||||
|
// but static import from sun.* package is risky for non-SUN virtual machine.
|
||||||
|
//try { ((sun.nio.ch.DirectBuffer)cb).cleaner().clean(); } catch (Exception ex) { }
|
||||||
|
try {
|
||||||
|
Method cleaner = cb.getClass().getMethod("cleaner");
|
||||||
|
cleaner.setAccessible(true);
|
||||||
|
Method clean = Class.forName("sun.misc.Cleaner").getMethod("clean");
|
||||||
|
clean.setAccessible(true);
|
||||||
|
clean.invoke(cleaner.invoke(cb));
|
||||||
|
} catch(Exception ex) { }
|
||||||
|
cb = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
try {
|
try {
|
||||||
raf.close();
|
mbb.force();
|
||||||
|
fc.close();
|
||||||
|
braf.close();
|
||||||
file.setWritable(true);
|
file.setWritable(true);
|
||||||
System.gc();
|
closeDirectBuffer(mbb);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
MainUtil.handleError(e);
|
MainUtil.handleError(e);
|
||||||
}
|
}
|
||||||
@ -213,37 +250,37 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
|||||||
@Override
|
@Override
|
||||||
public void streamIds(NBTStreamer.ByteReader task) {
|
public void streamIds(NBTStreamer.ByteReader task) {
|
||||||
try {
|
try {
|
||||||
raf.seek(HEADER_SIZE);
|
mbb.force();
|
||||||
|
mbb.position(HEADER_SIZE);
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (int y = 0; y < height; y++) {
|
for (int y = 0; y < height; y++) {
|
||||||
for (int z = 0; z < length; z++) {
|
for (int z = 0; z < length; z++) {
|
||||||
for (int x = 0; x < width; x++) {
|
for (int x = 0; x < width; x++) {
|
||||||
int combinedId = raf.readChar();
|
int combinedId = mbb.getChar();
|
||||||
task.run(index++, FaweCache.getId(combinedId));
|
task.run(index++, FaweCache.getId(combinedId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (Throwable e) {
|
||||||
MainUtil.handleError(e);
|
MainUtil.handleError(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static long start;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void streamDatas(NBTStreamer.ByteReader task) {
|
public void streamDatas(NBTStreamer.ByteReader task) {
|
||||||
try {
|
try {
|
||||||
raf.seek(HEADER_SIZE);
|
mbb.force();
|
||||||
|
mbb.position(HEADER_SIZE);
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (int y = 0; y < height; y++) {
|
for (int y = 0; y < height; y++) {
|
||||||
for (int z = 0; z < length; z++) {
|
for (int z = 0; z < length; z++) {
|
||||||
for (int x = 0; x < width; x++) {
|
for (int x = 0; x < width; x++) {
|
||||||
int combinedId = raf.readChar();
|
int combinedId = mbb.getChar();
|
||||||
task.run(index++, FaweCache.getData(combinedId));
|
task.run(index++, FaweCache.getData(combinedId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (Throwable e) {
|
||||||
MainUtil.handleError(e);
|
MainUtil.handleError(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -256,7 +293,8 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
|||||||
@Override
|
@Override
|
||||||
public void forEach(final BlockReader task, boolean air) {
|
public void forEach(final BlockReader task, boolean air) {
|
||||||
try {
|
try {
|
||||||
raf.seek(HEADER_SIZE);
|
mbb.force();
|
||||||
|
mbb.position(HEADER_SIZE);
|
||||||
IntegerTrio trio = new IntegerTrio();
|
IntegerTrio trio = new IntegerTrio();
|
||||||
final boolean hasTile = !nbtMap.isEmpty();
|
final boolean hasTile = !nbtMap.isEmpty();
|
||||||
if (air) {
|
if (air) {
|
||||||
@ -264,7 +302,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
|||||||
for (int y = 0; y < height; y++) {
|
for (int y = 0; y < height; y++) {
|
||||||
for (int z = 0; z < length; z++) {
|
for (int z = 0; z < length; z++) {
|
||||||
for (int x = 0; x < width; x++) {
|
for (int x = 0; x < width; x++) {
|
||||||
char combinedId = raf.readChar();
|
char combinedId = mbb.getChar();
|
||||||
BaseBlock block = FaweCache.CACHE_BLOCK[combinedId];
|
BaseBlock block = FaweCache.CACHE_BLOCK[combinedId];
|
||||||
if (block.canStoreNBTData()) {
|
if (block.canStoreNBTData()) {
|
||||||
trio.set(x, y, z);
|
trio.set(x, y, z);
|
||||||
@ -282,7 +320,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
|||||||
for (int y = 0; y < height; y++) {
|
for (int y = 0; y < height; y++) {
|
||||||
for (int z = 0; z < length; z++) {
|
for (int z = 0; z < length; z++) {
|
||||||
for (int x = 0; x < width; x++) {
|
for (int x = 0; x < width; x++) {
|
||||||
char combinedId = raf.readChar();
|
char combinedId = mbb.getChar();
|
||||||
BaseBlock block = FaweCache.CACHE_BLOCK[combinedId];
|
BaseBlock block = FaweCache.CACHE_BLOCK[combinedId];
|
||||||
task.run(x, y, z, block);
|
task.run(x, y, z, block);
|
||||||
}
|
}
|
||||||
@ -293,7 +331,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
|||||||
for (int y = 0; y < height; y++) {
|
for (int y = 0; y < height; y++) {
|
||||||
for (int z = 0; z < length; z++) {
|
for (int z = 0; z < length; z++) {
|
||||||
for (int x = 0; x < width; x++) {
|
for (int x = 0; x < width; x++) {
|
||||||
int combinedId = raf.readChar();
|
int combinedId = mbb.getChar();
|
||||||
if (combinedId != 0) {
|
if (combinedId != 0) {
|
||||||
BaseBlock block = FaweCache.CACHE_BLOCK[combinedId];
|
BaseBlock block = FaweCache.CACHE_BLOCK[combinedId];
|
||||||
if (block.canStoreNBTData()) {
|
if (block.canStoreNBTData()) {
|
||||||
@ -310,7 +348,7 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (Throwable e) {
|
||||||
MainUtil.handleError(e);
|
MainUtil.handleError(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -324,10 +362,10 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
|||||||
try {
|
try {
|
||||||
int i = getIndex(x, y, z);
|
int i = getIndex(x, y, z);
|
||||||
if (i != last + 1) {
|
if (i != last + 1) {
|
||||||
raf.seek((HEADER_SIZE) + (i << 1));
|
mbb.position((HEADER_SIZE) + (i << 1));
|
||||||
}
|
}
|
||||||
last = i;
|
last = i;
|
||||||
int combinedId = raf.readChar();
|
int combinedId = mbb.getChar();
|
||||||
BaseBlock block = FaweCache.CACHE_BLOCK[combinedId];
|
BaseBlock block = FaweCache.CACHE_BLOCK[combinedId];
|
||||||
if (block.canStoreNBTData()) {
|
if (block.canStoreNBTData()) {
|
||||||
CompoundTag nbt = nbtMap.get(new IntegerTrio(x, y, z));
|
CompoundTag nbt = nbtMap.get(new IntegerTrio(x, y, z));
|
||||||
@ -358,13 +396,13 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
|||||||
try {
|
try {
|
||||||
int i = x + ((ylast == y) ? ylasti : (ylasti = ((ylast = y)) * area)) + ((zlast == z) ? zlasti : (zlasti = (zlast = z) * width));
|
int i = x + ((ylast == y) ? ylasti : (ylasti = ((ylast = y)) * area)) + ((zlast == z) ? zlasti : (zlasti = (zlast = z) * width));
|
||||||
if (i != last + 1) {
|
if (i != last + 1) {
|
||||||
raf.seek((HEADER_SIZE) + (i << 1));
|
mbb.position((HEADER_SIZE) + (i << 1));
|
||||||
}
|
}
|
||||||
last = i;
|
last = i;
|
||||||
final int id = block.getId();
|
final int id = block.getId();
|
||||||
final int data = block.getData();
|
final int data = block.getData();
|
||||||
int combined = (id << 4) + data;
|
int combined = (id << 4) + data;
|
||||||
raf.writeChar(combined);
|
mbb.putChar((char) combined);
|
||||||
CompoundTag tile = block.getNbtData();
|
CompoundTag tile = block.getNbtData();
|
||||||
if (tile != null) {
|
if (tile != null) {
|
||||||
setTile(x, y, z, tile);
|
setTile(x, y, z, tile);
|
||||||
@ -379,16 +417,20 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
|||||||
@Override
|
@Override
|
||||||
public void setId(int i, int id) {
|
public void setId(int i, int id) {
|
||||||
try {
|
try {
|
||||||
|
int index;
|
||||||
if (i != last + 1) {
|
if (i != last + 1) {
|
||||||
raf.seek((HEADER_SIZE) + (i << 1));
|
index = (HEADER_SIZE) + (i << 1);
|
||||||
|
} else {
|
||||||
|
index = mbb.position();
|
||||||
}
|
}
|
||||||
last = i;
|
last = i;
|
||||||
|
mbb.position(index + 1);
|
||||||
// 00000000 00000000
|
// 00000000 00000000
|
||||||
// [ id ]data
|
// [ id ]data
|
||||||
int id1 = raf.readCurrent();
|
byte id2 = mbb.get();
|
||||||
raf.writeUnsafe(id >> 4);
|
mbb.position(index);
|
||||||
int id2 = raf.readCurrent();
|
mbb.put((byte) (id >> 4));
|
||||||
raf.writeUnsafe(((id & 0xFF) << 4) + (id2 & 0xFF));
|
mbb.put((byte) (((id & 0xFF) << 4) + (id2 & 0xFF)));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
MainUtil.handleError(e);
|
MainUtil.handleError(e);
|
||||||
}
|
}
|
||||||
@ -397,10 +439,10 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
|||||||
public void setCombined(int i, int combined) {
|
public void setCombined(int i, int combined) {
|
||||||
try {
|
try {
|
||||||
if (i != last + 1) {
|
if (i != last + 1) {
|
||||||
raf.seek((HEADER_SIZE) + (i << 1));
|
mbb.position((HEADER_SIZE) + (i << 1));
|
||||||
}
|
}
|
||||||
last = i;
|
last = i;
|
||||||
raf.writeChar(combined);
|
mbb.putChar((char) combined);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
MainUtil.handleError(e);
|
MainUtil.handleError(e);
|
||||||
}
|
}
|
||||||
@ -409,15 +451,14 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
|||||||
@Override
|
@Override
|
||||||
public void setAdd(int i, int add) {
|
public void setAdd(int i, int add) {
|
||||||
try {
|
try {
|
||||||
if (i != last + 1) {
|
|
||||||
raf.seek((HEADER_SIZE) + (i << 1));
|
|
||||||
}
|
|
||||||
last = i;
|
last = i;
|
||||||
|
int index = (HEADER_SIZE) + (i << 1);
|
||||||
|
mbb.position(index);
|
||||||
// 00000000 00000000
|
// 00000000 00000000
|
||||||
// [ id ]data
|
// [ id ]data
|
||||||
int id = (raf.readCurrent() & 0xFF);
|
char combined = mbb.getChar();
|
||||||
raf.writeUnsafe(id + (add >> 4));
|
mbb.position(index);
|
||||||
raf.read1();
|
mbb.putChar((char) ((combined & 0xFFFF) + (add << 12)));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
MainUtil.handleError(e);
|
MainUtil.handleError(e);
|
||||||
}
|
}
|
||||||
@ -426,17 +467,17 @@ public class DiskOptimizedClipboard extends FaweClipboard implements Closeable {
|
|||||||
@Override
|
@Override
|
||||||
public void setData(int i, int data) {
|
public void setData(int i, int data) {
|
||||||
try {
|
try {
|
||||||
|
int index;
|
||||||
if (i != last + 1) {
|
if (i != last + 1) {
|
||||||
raf.seek((HEADER_SIZE) + (i << 1) + 1);
|
index = (HEADER_SIZE) + (i << 1) + 1;
|
||||||
} else {
|
} else {
|
||||||
raf.seek(raf.getFilePointer() + 1);
|
index = mbb.position() + 1;
|
||||||
}
|
}
|
||||||
|
mbb.position(index);
|
||||||
last = i;
|
last = i;
|
||||||
// 00000000 00000000
|
byte id = mbb.get();
|
||||||
// [ id ]data
|
mbb.position(index);
|
||||||
// int skip = raf.read1();
|
mbb.put((byte) ((id & 0xF0) + data));
|
||||||
int id2 = raf.readCurrent();
|
|
||||||
raf.writeUnsafe((id2 & 0xF0) + data);
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
MainUtil.handleError(e);
|
MainUtil.handleError(e);
|
||||||
}
|
}
|
||||||
|
@ -94,6 +94,10 @@ public abstract class FaweClipboard {
|
|||||||
return tiles;
|
return tiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void close() {}
|
||||||
|
|
||||||
|
public void flush() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores entity data.
|
* Stores entity data.
|
||||||
*/
|
*/
|
||||||
|
@ -34,4 +34,11 @@ public class MultiClipboardHolder extends ClipboardHolder{
|
|||||||
public void setTransform(Transform transform) {
|
public void setTransform(Transform transform) {
|
||||||
holder.setTransform(transform);
|
holder.setTransform(transform);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
for (ClipboardHolder holder : holders) {
|
||||||
|
if (holder != null) holder.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
package com.boydti.fawe.object.clipboard;
|
|
||||||
|
|
||||||
import com.google.common.io.ByteSource;
|
|
||||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
|
|
||||||
import com.sk89q.worldedit.world.registry.WorldData;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class RandomClipboardHolder extends LazyClipboardHolder {
|
|
||||||
public RandomClipboardHolder(ByteSource source, ClipboardFormat format, WorldData worldData, UUID uuid) {
|
|
||||||
super(source, format, worldData, uuid);
|
|
||||||
}
|
|
||||||
}
|
|
@ -28,7 +28,6 @@ import com.boydti.fawe.object.FawePlayer;
|
|||||||
import com.boydti.fawe.object.RunnableVal2;
|
import com.boydti.fawe.object.RunnableVal2;
|
||||||
import com.boydti.fawe.object.changeset.DiskStorageHistory;
|
import com.boydti.fawe.object.changeset.DiskStorageHistory;
|
||||||
import com.boydti.fawe.object.changeset.FaweChangeSet;
|
import com.boydti.fawe.object.changeset.FaweChangeSet;
|
||||||
import com.boydti.fawe.object.clipboard.DiskOptimizedClipboard;
|
|
||||||
import com.boydti.fawe.object.extent.ResettableExtent;
|
import com.boydti.fawe.object.extent.ResettableExtent;
|
||||||
import com.boydti.fawe.util.EditSessionBuilder;
|
import com.boydti.fawe.util.EditSessionBuilder;
|
||||||
import com.boydti.fawe.util.MainUtil;
|
import com.boydti.fawe.util.MainUtil;
|
||||||
@ -45,8 +44,6 @@ import com.sk89q.worldedit.command.tool.SinglePickaxe;
|
|||||||
import com.sk89q.worldedit.command.tool.Tool;
|
import com.sk89q.worldedit.command.tool.Tool;
|
||||||
import com.sk89q.worldedit.entity.Player;
|
import com.sk89q.worldedit.entity.Player;
|
||||||
import com.sk89q.worldedit.extension.platform.Actor;
|
import com.sk89q.worldedit.extension.platform.Actor;
|
||||||
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
|
||||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
|
||||||
import com.sk89q.worldedit.extent.inventory.BlockBag;
|
import com.sk89q.worldedit.extent.inventory.BlockBag;
|
||||||
import com.sk89q.worldedit.function.mask.Mask;
|
import com.sk89q.worldedit.function.mask.Mask;
|
||||||
import com.sk89q.worldedit.function.mask.Masks;
|
import com.sk89q.worldedit.function.mask.Masks;
|
||||||
@ -794,14 +791,8 @@ public class LocalSession {
|
|||||||
* @param clipboard the clipboard, or null if the clipboard is to be cleared
|
* @param clipboard the clipboard, or null if the clipboard is to be cleared
|
||||||
*/
|
*/
|
||||||
public void setClipboard(@Nullable ClipboardHolder clipboard) {
|
public void setClipboard(@Nullable ClipboardHolder clipboard) {
|
||||||
if (this.clipboard != null && clipboard != null) {
|
if (this.clipboard != null) {
|
||||||
Clipboard clip = clipboard.getClipboard();
|
this.clipboard.close();
|
||||||
if (clip instanceof BlockArrayClipboard) {
|
|
||||||
BlockArrayClipboard bac = (BlockArrayClipboard) clip;
|
|
||||||
if (bac.IMP instanceof DiskOptimizedClipboard) {
|
|
||||||
((DiskOptimizedClipboard) bac.IMP).flush();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
this.clipboard = clipboard;
|
this.clipboard = clipboard;
|
||||||
}
|
}
|
||||||
|
@ -112,6 +112,7 @@ public class ClipboardCommands {
|
|||||||
if (volume >= limit.MAX_CHECKS) {
|
if (volume >= limit.MAX_CHECKS) {
|
||||||
throw new FaweException(BBC.WORLDEDIT_CANCEL_REASON_MAX_CHECKS);
|
throw new FaweException(BBC.WORLDEDIT_CANCEL_REASON_MAX_CHECKS);
|
||||||
}
|
}
|
||||||
|
session.setClipboard(null);
|
||||||
final Vector origin = region.getMinimumPoint();
|
final Vector origin = region.getMinimumPoint();
|
||||||
final int mx = origin.getBlockX();
|
final int mx = origin.getBlockX();
|
||||||
final int my = origin.getBlockY();
|
final int my = origin.getBlockY();
|
||||||
@ -149,7 +150,7 @@ public class ClipboardCommands {
|
|||||||
if (volume >= limit.MAX_CHECKS) {
|
if (volume >= limit.MAX_CHECKS) {
|
||||||
throw new FaweException(BBC.WORLDEDIT_CANCEL_REASON_MAX_CHECKS);
|
throw new FaweException(BBC.WORLDEDIT_CANCEL_REASON_MAX_CHECKS);
|
||||||
}
|
}
|
||||||
|
session.setClipboard(null);
|
||||||
BlockArrayClipboard clipboard = new BlockArrayClipboard(region, player.getUniqueId());
|
BlockArrayClipboard clipboard = new BlockArrayClipboard(region, player.getUniqueId());
|
||||||
clipboard.setOrigin(session.getPlacementPosition(player));
|
clipboard.setOrigin(session.getPlacementPosition(player));
|
||||||
ForwardExtentCopy copy = new ForwardExtentCopy(editSession, region, clipboard, region.getMinimumPoint());
|
ForwardExtentCopy copy = new ForwardExtentCopy(editSession, region, clipboard, region.getMinimumPoint());
|
||||||
@ -193,6 +194,7 @@ public class ClipboardCommands {
|
|||||||
if (volume >= limit.MAX_CHANGES) {
|
if (volume >= limit.MAX_CHANGES) {
|
||||||
throw new FaweException(BBC.WORLDEDIT_CANCEL_REASON_MAX_CHANGES);
|
throw new FaweException(BBC.WORLDEDIT_CANCEL_REASON_MAX_CHANGES);
|
||||||
}
|
}
|
||||||
|
session.setClipboard(null);
|
||||||
final Vector origin = region.getMinimumPoint();
|
final Vector origin = region.getMinimumPoint();
|
||||||
final int mx = origin.getBlockX();
|
final int mx = origin.getBlockX();
|
||||||
final int my = origin.getBlockY();
|
final int my = origin.getBlockY();
|
||||||
@ -232,6 +234,7 @@ public class ClipboardCommands {
|
|||||||
if (volume >= limit.MAX_CHANGES) {
|
if (volume >= limit.MAX_CHANGES) {
|
||||||
throw new FaweException(BBC.WORLDEDIT_CANCEL_REASON_MAX_CHANGES);
|
throw new FaweException(BBC.WORLDEDIT_CANCEL_REASON_MAX_CHANGES);
|
||||||
}
|
}
|
||||||
|
session.setClipboard(null);
|
||||||
BlockArrayClipboard clipboard = new BlockArrayClipboard(region, player.getUniqueId());
|
BlockArrayClipboard clipboard = new BlockArrayClipboard(region, player.getUniqueId());
|
||||||
clipboard.setOrigin(session.getPlacementPosition(player));
|
clipboard.setOrigin(session.getPlacementPosition(player));
|
||||||
ForwardExtentCopy copy = new ForwardExtentCopy(editSession, region, clipboard, region.getMinimumPoint());
|
ForwardExtentCopy copy = new ForwardExtentCopy(editSession, region, clipboard, region.getMinimumPoint());
|
||||||
|
@ -103,6 +103,7 @@ public class SchematicCommands {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
WorldData wd = player.getWorld().getWorldData();
|
WorldData wd = player.getWorld().getWorldData();
|
||||||
|
session.setClipboard(null);
|
||||||
ClipboardHolder[] all = format.loadAllFromInput(player, wd, filename, true);
|
ClipboardHolder[] all = format.loadAllFromInput(player, wd, filename, true);
|
||||||
if (all != null) {
|
if (all != null) {
|
||||||
MultiClipboardHolder multi = new MultiClipboardHolder(wd, all);
|
MultiClipboardHolder multi = new MultiClipboardHolder(wd, all);
|
||||||
@ -177,6 +178,7 @@ public class SchematicCommands {
|
|||||||
final ClipboardReader reader = format.getReader(in);
|
final ClipboardReader reader = format.getReader(in);
|
||||||
final WorldData worldData = player.getWorld().getWorldData();
|
final WorldData worldData = player.getWorld().getWorldData();
|
||||||
final Clipboard clipboard;
|
final Clipboard clipboard;
|
||||||
|
session.setClipboard(null);
|
||||||
if (reader instanceof SchematicReader) {
|
if (reader instanceof SchematicReader) {
|
||||||
clipboard = ((SchematicReader) reader).read(player.getWorld().getWorldData(), player.getUniqueId());
|
clipboard = ((SchematicReader) reader).read(player.getWorld().getWorldData(), player.getUniqueId());
|
||||||
} else if (reader instanceof StructureFormat) {
|
} else if (reader instanceof StructureFormat) {
|
||||||
|
@ -115,6 +115,10 @@ public class BlockArrayClipboard implements Clipboard, LightingExtent {
|
|||||||
this.mz = origin.getBlockZ();
|
this.mz = origin.getBlockZ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void close() {
|
||||||
|
IMP.close();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Region getRegion() {
|
public Region getRegion() {
|
||||||
return region.clone();
|
return region.clone();
|
||||||
|
@ -0,0 +1,112 @@
|
|||||||
|
/*
|
||||||
|
* 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.session;
|
||||||
|
|
||||||
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
|
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
||||||
|
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||||
|
import com.sk89q.worldedit.math.transform.Identity;
|
||||||
|
import com.sk89q.worldedit.math.transform.Transform;
|
||||||
|
import com.sk89q.worldedit.world.registry.WorldData;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds the clipboard and the current transform on the clipboard.
|
||||||
|
*/
|
||||||
|
public class ClipboardHolder {
|
||||||
|
|
||||||
|
private final WorldData worldData;
|
||||||
|
private final Clipboard clipboard;
|
||||||
|
private Transform transform = new Identity();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance with the given clipboard.
|
||||||
|
*
|
||||||
|
* @param clipboard the clipboard
|
||||||
|
* @param worldData the mapping of blocks, entities, and so on
|
||||||
|
*/
|
||||||
|
public ClipboardHolder(Clipboard clipboard, WorldData worldData) {
|
||||||
|
checkNotNull(clipboard);
|
||||||
|
checkNotNull(worldData);
|
||||||
|
this.clipboard = clipboard;
|
||||||
|
this.worldData = worldData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the mapping used for blocks, entities, and so on.
|
||||||
|
*
|
||||||
|
* @return the mapping
|
||||||
|
*/
|
||||||
|
public WorldData getWorldData() {
|
||||||
|
return worldData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the clipboard.
|
||||||
|
* <p>
|
||||||
|
* If there is a transformation applied, the returned clipboard will
|
||||||
|
* not contain its effect.
|
||||||
|
*
|
||||||
|
* @return the clipboard
|
||||||
|
*/
|
||||||
|
public Clipboard getClipboard() {
|
||||||
|
return clipboard;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the transform.
|
||||||
|
*
|
||||||
|
* @param transform the transform
|
||||||
|
*/
|
||||||
|
public void setTransform(Transform transform) {
|
||||||
|
checkNotNull(transform);
|
||||||
|
this.transform = transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the transform.
|
||||||
|
*
|
||||||
|
* @return the transform
|
||||||
|
*/
|
||||||
|
public Transform getTransform() {
|
||||||
|
return transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a builder for an operation to paste this clipboard.
|
||||||
|
*
|
||||||
|
* @return a builder
|
||||||
|
*/
|
||||||
|
public PasteBuilder createPaste(Extent targetExtent, WorldData targetWorldData) {
|
||||||
|
return new PasteBuilder(this, targetExtent, targetWorldData);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close() {
|
||||||
|
if (clipboard instanceof BlockArrayClipboard) {
|
||||||
|
((BlockArrayClipboard) clipboard).close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Class<?> inject() {
|
||||||
|
return ClipboardHolder.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -221,6 +221,7 @@ public class SessionManager {
|
|||||||
|
|
||||||
private void save(SessionHolder holder) {
|
private void save(SessionHolder holder) {
|
||||||
SessionKey key = holder.key;
|
SessionKey key = holder.key;
|
||||||
|
holder.session.setClipboard(null);
|
||||||
if (key.isPersistent()) {
|
if (key.isPersistent()) {
|
||||||
try {
|
try {
|
||||||
if (holder.session.compareAndResetDirty()) {
|
if (holder.session.compareAndResetDirty()) {
|
||||||
|
Loading…
Reference in New Issue
Block a user