This commit is contained in:
boy0001 2015-04-16 22:21:04 +10:00
parent 2335708e11
commit 689583334d

View File

@ -1,84 +1,166 @@
package com.intellectualcrafters.plot.util.bukkit; package com.intellectualcrafters.plot.util.bukkit;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map.Entry; import java.util.Map.Entry;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.World; import org.bukkit.World;
import com.intellectualcrafters.plot.util.TaskManager; import com.intellectualcrafters.plot.util.TaskManager;
public class DebugSetBlockQueue { public class DebugSetBlockQueue {
private HashMap<Chunk, short[][]> blocks; private volatile static HashMap<ChunkWrapper, short[][]> blocks;
private int allocate = 100; private volatile static int allocate = 50;
private volatile static boolean running = false;
private volatile static boolean locked = false;
private volatile static HashSet<Runnable> runnables;
public void allocate(int t) { public synchronized static void allocate(int t) {
this.allocate = t; allocate = t;
} }
public DebugSetBlockQueue(final Runnable whenDone) { public synchronized static void addNotify(Runnable whenDone) {
blocks = new HashMap<>(); if (runnables == null) {
TaskManager.index.increment(); TaskManager.runTask(whenDone);
final int current = TaskManager.index.intValue(); }
int task = TaskManager.runTaskRepeat(new Runnable() { else {
@Override runnables.add(whenDone);
public void run() { }
if (blocks.size() == 0) { }
blocks = null;
Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(current)); public synchronized static void init() {
TaskManager.runTask(whenDone); if (blocks == null) {
return; blocks = new HashMap<>();
} runnables = new HashSet<>();
long start = System.currentTimeMillis() + allocate; }
Iterator<Entry<Chunk, short[][]>> i = blocks.entrySet().iterator(); if (!running) {
while (System.currentTimeMillis() < start && i.hasNext()) { TaskManager.index.increment();
Entry<Chunk, short[][]> n = i.next(); final int current = TaskManager.index.intValue();
i.remove(); int task = TaskManager.runTaskRepeat(new Runnable() {
Chunk chunk = n.getKey(); @Override
int X = chunk.getX() << 4; public void run() {
int Z = chunk.getZ() << 4; if (locked) {
short[][] blocks = n.getValue(); return;
World world = chunk.getWorld(); }
for (int j = 0; j < blocks.length; j++) { if (blocks.size() == 0) {
short[] blocksj = blocks[j]; Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(current));
if (blocksj != null) { for (Runnable runnable : runnables) {
for (int k = 0; k < blocksj.length; k++) { TaskManager.runTask(runnable);
short id = blocksj[k]; }
if (id != 0) { runnables = null;
final int y = (j << 4) + (k >> 8); blocks = null;
final int a = (k - ((y & 0xF) << 8)); running = false;
final int z = (a >> 4); return;
final int x = a - (z << 4); }
BukkitSetBlockManager.setBlockManager.set(world, X + x, y, Z + z, id, (byte) 0); long start = System.currentTimeMillis() + allocate;
Iterator<Entry<ChunkWrapper, short[][]>> i = blocks.entrySet().iterator();
while (System.currentTimeMillis() < start && i.hasNext()) {
if (locked) {
return;
}
Entry<ChunkWrapper, short[][]> n = i.next();
i.remove();
ChunkWrapper chunk = n.getKey();
int X = chunk.x << 4;
int Z = chunk.z << 4;
short[][] blocks = n.getValue();
World world = chunk.world;
for (int j = 0; j < blocks.length; j++) {
short[] blocksj = blocks[j];
if (blocksj != null) {
for (int k = 0; k < blocksj.length; k++) {
short id = blocksj[k];
if (id != 0) {
final int y = (j << 4) + (k >> 8);
final int a = (k - ((y & 0xF) << 8));
final int z = (a >> 4);
final int x = a - (z << 4);
BukkitSetBlockManager.setBlockManager.set(world, X + x, y, Z + z, id, (byte) 0);
}
} }
} }
} }
} }
} }
} }, 5);
}, 20); TaskManager.tasks.put(current, task);
TaskManager.tasks.put(current, task); running = true;
}
} }
public static void setBlock(final World world, int x, final int y, int z, final short blkid) {
locked = true;
public void setBlock(final World world, int x, final int y, int z, final short blkid) { if (!running) {
init();
}
int X = x >> 4; int X = x >> 4;
int Z = z >> 4; int Z = z >> 4;
x -= X << 4; x -= X << 4;
z -= Z << 4; z -= Z << 4;
Chunk chunk = world.getChunkAt(X, Z);
short[][] result = blocks.get(chunk); ChunkWrapper wrap = new ChunkWrapper(world, X, Z);
if (!blocks.containsKey(chunk)) { short[][] result = blocks.get(wrap);
if (!blocks.containsKey(wrap)) {
result = new short[16][]; result = new short[16][];
blocks.put(chunk, result); blocks.put(wrap, result);
} }
if (result[y >> 4] == null) { if (result[y >> 4] == null) {
result[y >> 4] = new short[4096]; result[y >> 4] = new short[4096];
} }
result[y >> 4][((y & 0xF) << 8) | (z << 4) | x] = blkid; result[y >> 4][((y & 0xF) << 8) | (z << 4) | x] = blkid;
locked = false;
}
public static class ChunkWrapper {
final int x;
final int z;
final World world;
public ChunkWrapper(World world, int x, int z) {
this.world = world;
this.x = x;
this.z = z;
}
@Override
public int hashCode() {
int result;
if (this.x >= 0) {
if (this.z >= 0) {
result = (this.x * this.x) + (3 * this.x) + (2 * this.x * this.z) + this.z + (this.z * this.z);
} else {
final int y1 = -this.z;
result = (this.x * this.x) + (3 * this.x) + (2 * this.x * y1) + y1 + (y1 * y1) + 1;
}
} else {
final int x1 = -this.x;
if (this.z >= 0) {
result = -((x1 * x1) + (3 * x1) + (2 * x1 * this.z) + this.z + (this.z * this.z));
} else {
final int y1 = -this.z;
result = -((x1 * x1) + (3 * x1) + (2 * x1 * y1) + y1 + (y1 * y1) + 1);
}
}
result = result * 31 + world.hashCode();
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final ChunkWrapper other = (ChunkWrapper) obj;
return ((this.x == other.x) && (this.z == other.z) && (this.world.equals(other.world)));
}
} }
} }