FastAsyncWorldedit/src/main/java/com/boydti/fawe/util/SetBlockQueue.java

144 lines
4.1 KiB
Java

package com.boydti.fawe.util;
import java.util.ArrayDeque;
import java.util.concurrent.atomic.AtomicInteger;
import com.boydti.fawe.object.FaweChunk;
import com.sk89q.worldedit.world.biome.BaseBiome;
public class SetBlockQueue {
public static final SetBlockQueue IMP = new SetBlockQueue();
public FaweQueue queue;
private final AtomicInteger time_waiting = new AtomicInteger(2);
private final AtomicInteger time_current = new AtomicInteger(0);
private final ArrayDeque<Runnable> runnables = new ArrayDeque<>();
private long last;
private long last2;
public SetBlockQueue() {
TaskManager.IMP.repeat(new Runnable() {
@Override
public void run() {
if (!MemUtil.isMemoryFree()) {
final int mem = MemUtil.calculateMemory();
if (mem != Integer.MAX_VALUE) {
if (mem <= 1) {
queue.saveMemory();
return;
}
if (forceChunkSet()) {
System.gc();
} else {
time_current.incrementAndGet();
tasks();
}
return;
}
}
long free = 50 + Math.min(50 + last - (last = System.currentTimeMillis()), last2 - System.currentTimeMillis());
time_current.incrementAndGet();
do {
if (isWaiting()) {
return;
}
final FaweChunk<?> current = queue.next();
if (current == null) {
time_waiting.set(Math.max(time_waiting.get(), time_current.get() - 2));
tasks();
return;
}
} while ((last2 = System.currentTimeMillis()) - last < free);
time_waiting.set(time_current.get() - 1);
}
}, 1);
}
public boolean forceChunkSet() {
final FaweChunk<?> set = queue.next();
return set != null;
}
public boolean isWaiting() {
return time_waiting.get() >= time_current.get();
}
public boolean isDone() {
return (time_waiting.get() + 1) < time_current.get();
}
public void setWaiting() {
time_waiting.set(time_current.get() + 1);
}
public boolean addTask(final Runnable whenDone) {
if (isDone()) {
// Run
tasks();
if (whenDone != null) {
whenDone.run();
}
return true;
}
if (whenDone != null) {
runnables.add(whenDone);
}
return false;
}
public boolean tasks() {
if (runnables.size() == 0) {
return false;
}
final ArrayDeque<Runnable> tmp = runnables.clone();
runnables.clear();
for (final Runnable runnable : tmp) {
runnable.run();
}
return true;
}
/**
* @param world
* @param x
* @param y
* @param z
* @param id
* @param data
* @return
*/
public boolean setBlock(final String world, final int x, final int y, final int z, final short id, final byte data) {
SetBlockQueue.IMP.setWaiting();
return queue.setBlock(world, x, y, z, id, data);
}
/**
* @param world
* @param x
* @param y
* @param z
* @param id
* @return
*/
public boolean setBlock(final String world, final int x, final int y, final int z, final short id) {
SetBlockQueue.IMP.setWaiting();
return queue.setBlock(world, x, y, z, id, (byte) 0);
}
/**
* @param world
* @param x
* @param y
* @param z
* @param id
* @param data
* @return
*/
public boolean setBiome(final String world, final int x, final int z, BaseBiome biome) {
SetBlockQueue.IMP.setWaiting();
return queue.setBiome(world, x, z, biome);
}
}