2015-04-21 22:48:18 +10:00
|
|
|
package com.intellectualcrafters.plot.util;
|
|
|
|
|
2015-08-26 12:02:00 +10:00
|
|
|
import java.util.ArrayDeque;
|
2015-07-27 19:50:04 +02:00
|
|
|
import java.util.HashMap;
|
2015-08-26 14:21:48 +10:00
|
|
|
import java.util.Iterator;
|
2015-07-27 19:50:04 +02:00
|
|
|
import java.util.Map.Entry;
|
2015-04-21 22:48:18 +10:00
|
|
|
|
2015-07-31 00:25:16 +10:00
|
|
|
import com.intellectualcrafters.plot.PS;
|
|
|
|
import com.intellectualcrafters.plot.object.ChunkLoc;
|
|
|
|
import com.intellectualcrafters.plot.object.PlotBlock;
|
|
|
|
|
2015-09-11 20:09:22 +10:00
|
|
|
public class SetBlockQueue
|
|
|
|
{
|
|
|
|
|
2015-04-21 22:48:18 +10:00
|
|
|
private volatile static HashMap<ChunkWrapper, PlotBlock[][]> blocks;
|
2015-04-30 23:57:44 +10:00
|
|
|
private volatile static int allocate = 25;
|
2015-04-21 22:48:18 +10:00
|
|
|
private volatile static boolean running = false;
|
|
|
|
private volatile static boolean locked = false;
|
2015-08-26 12:02:00 +10:00
|
|
|
private volatile static ArrayDeque<Runnable> runnables;
|
2015-05-04 23:53:24 +10:00
|
|
|
private volatile static boolean slow = false;
|
2015-07-03 13:21:21 +02:00
|
|
|
private static long last;
|
|
|
|
private static int lastInt = 0;
|
|
|
|
private static PlotBlock lastBlock = new PlotBlock((short) 0, (byte) 0);
|
2015-09-11 20:09:22 +10:00
|
|
|
|
|
|
|
public synchronized static void allocate(final int t)
|
|
|
|
{
|
2015-04-21 22:48:18 +10:00
|
|
|
allocate = t;
|
|
|
|
}
|
2015-09-11 20:09:22 +10:00
|
|
|
|
|
|
|
public static int getAllocate()
|
|
|
|
{
|
2015-04-30 23:57:44 +10:00
|
|
|
return allocate;
|
|
|
|
}
|
2015-09-11 20:09:22 +10:00
|
|
|
|
|
|
|
public static void setSlow(final boolean value)
|
|
|
|
{
|
2015-05-04 23:53:24 +10:00
|
|
|
slow = value;
|
|
|
|
}
|
2015-09-11 20:09:22 +10:00
|
|
|
|
|
|
|
public synchronized static boolean addNotify(final Runnable whenDone)
|
|
|
|
{
|
|
|
|
if (runnables == null)
|
|
|
|
{
|
|
|
|
if ((blocks == null) || (blocks.size() == 0))
|
|
|
|
{
|
|
|
|
if (whenDone != null)
|
|
|
|
{
|
2015-08-26 12:02:00 +10:00
|
|
|
whenDone.run();
|
|
|
|
}
|
|
|
|
slow = false;
|
|
|
|
locked = false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
runnables = new ArrayDeque<>();
|
2015-04-21 22:48:18 +10:00
|
|
|
}
|
2015-09-11 20:09:22 +10:00
|
|
|
if (whenDone != null)
|
|
|
|
{
|
2015-08-28 08:33:32 +10:00
|
|
|
init();
|
2015-04-21 22:48:18 +10:00
|
|
|
runnables.add(whenDone);
|
|
|
|
}
|
2015-09-11 20:09:22 +10:00
|
|
|
if ((blocks == null) || (blocks.size() == 0) || !blocks.entrySet().iterator().hasNext())
|
|
|
|
{
|
|
|
|
final ArrayDeque<Runnable> tasks = runnables;
|
2015-08-28 08:33:32 +10:00
|
|
|
lastInt = -1;
|
|
|
|
lastBlock = null;
|
|
|
|
runnables = null;
|
|
|
|
running = false;
|
|
|
|
blocks = null;
|
|
|
|
slow = false;
|
2015-09-11 20:09:22 +10:00
|
|
|
if (tasks != null)
|
|
|
|
{
|
|
|
|
for (final Runnable runnable : tasks)
|
|
|
|
{
|
2015-08-28 08:33:32 +10:00
|
|
|
runnable.run();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-08-26 12:02:00 +10:00
|
|
|
return false;
|
2015-04-21 22:48:18 +10:00
|
|
|
}
|
2015-07-03 13:21:21 +02:00
|
|
|
|
2015-09-11 20:09:22 +10:00
|
|
|
public synchronized static void init()
|
|
|
|
{
|
|
|
|
if (blocks == null)
|
|
|
|
{
|
|
|
|
if (MainUtil.x_loc == null)
|
|
|
|
{
|
2015-07-31 00:25:16 +10:00
|
|
|
MainUtil.initCache();
|
2015-04-27 00:56:10 +10:00
|
|
|
}
|
2015-04-21 22:48:18 +10:00
|
|
|
blocks = new HashMap<>();
|
2015-08-26 12:02:00 +10:00
|
|
|
runnables = new ArrayDeque<>();
|
2015-04-21 22:48:18 +10:00
|
|
|
}
|
2015-09-11 20:09:22 +10:00
|
|
|
if (!running)
|
|
|
|
{
|
2015-07-27 04:38:08 +10:00
|
|
|
TaskManager.index.incrementAndGet();
|
2015-04-21 22:48:18 +10:00
|
|
|
final int current = TaskManager.index.intValue();
|
2015-09-11 20:09:22 +10:00
|
|
|
final int task = TaskManager.runTaskRepeat(new Runnable()
|
|
|
|
{
|
2015-04-21 22:48:18 +10:00
|
|
|
@Override
|
2015-09-11 20:09:22 +10:00
|
|
|
public void run()
|
|
|
|
{
|
2015-04-21 22:48:18 +10:00
|
|
|
if (locked) {
|
2015-09-11 20:09:22 +10:00
|
|
|
return;
|
2015-04-21 22:48:18 +10:00
|
|
|
}
|
2015-09-11 20:09:22 +10:00
|
|
|
if ((blocks == null) || (blocks.size() == 0))
|
|
|
|
{
|
2015-07-03 22:15:20 +10:00
|
|
|
PS.get().TASK.cancelTask(TaskManager.tasks.get(current));
|
2015-09-11 20:09:22 +10:00
|
|
|
final ArrayDeque<Runnable> tasks = runnables;
|
2015-08-04 22:21:12 +10:00
|
|
|
lastInt = -1;
|
2015-07-24 03:14:36 +10:00
|
|
|
lastBlock = null;
|
2015-04-21 22:48:18 +10:00
|
|
|
runnables = null;
|
|
|
|
running = false;
|
2015-08-28 08:33:32 +10:00
|
|
|
blocks = null;
|
2015-05-04 23:53:24 +10:00
|
|
|
slow = false;
|
2015-09-11 20:09:22 +10:00
|
|
|
if (tasks != null)
|
|
|
|
{
|
|
|
|
for (final Runnable runnable : tasks)
|
|
|
|
{
|
2015-08-26 12:02:00 +10:00
|
|
|
runnable.run();
|
|
|
|
}
|
|
|
|
}
|
2015-04-21 22:48:18 +10:00
|
|
|
return;
|
|
|
|
}
|
2015-09-11 20:09:22 +10:00
|
|
|
final long newLast = System.currentTimeMillis();
|
2015-08-04 22:21:12 +10:00
|
|
|
last = Math.max(newLast - 50, last);
|
2015-09-11 20:09:22 +10:00
|
|
|
while ((blocks.size() > 0) && ((System.currentTimeMillis() - last) < (50 + allocate)))
|
|
|
|
{
|
2015-04-21 22:48:18 +10:00
|
|
|
if (locked) {
|
2015-09-11 20:09:22 +10:00
|
|
|
return;
|
2015-04-21 22:48:18 +10:00
|
|
|
}
|
2015-09-11 20:09:22 +10:00
|
|
|
final Iterator<Entry<ChunkWrapper, PlotBlock[][]>> iter = blocks.entrySet().iterator();
|
|
|
|
if (!iter.hasNext())
|
|
|
|
{
|
2015-08-28 08:33:32 +10:00
|
|
|
PS.get().TASK.cancelTask(TaskManager.tasks.get(current));
|
2015-09-11 20:09:22 +10:00
|
|
|
final ArrayDeque<Runnable> tasks = runnables;
|
2015-08-28 08:33:32 +10:00
|
|
|
lastInt = -1;
|
|
|
|
lastBlock = null;
|
|
|
|
runnables = null;
|
|
|
|
running = false;
|
|
|
|
blocks = null;
|
|
|
|
slow = false;
|
2015-09-11 20:09:22 +10:00
|
|
|
if (tasks != null)
|
|
|
|
{
|
|
|
|
for (final Runnable runnable : tasks)
|
|
|
|
{
|
2015-08-28 08:33:32 +10:00
|
|
|
runnable.run();
|
|
|
|
}
|
|
|
|
}
|
2015-08-26 14:21:48 +10:00
|
|
|
return;
|
|
|
|
}
|
2015-09-11 20:09:22 +10:00
|
|
|
final Entry<ChunkWrapper, PlotBlock[][]> n = iter.next();
|
|
|
|
final ChunkWrapper chunk = n.getKey();
|
|
|
|
final PlotBlock[][] blocks = n.getValue();
|
|
|
|
final int X = chunk.x << 4;
|
|
|
|
final int Z = chunk.z << 4;
|
|
|
|
final String world = chunk.world;
|
|
|
|
if (slow)
|
|
|
|
{
|
2015-05-04 23:53:24 +10:00
|
|
|
boolean once = false;
|
2015-09-11 20:09:22 +10:00
|
|
|
for (int j = 0; j < blocks.length; j++)
|
|
|
|
{
|
|
|
|
final PlotBlock[] blocksj = blocks[j];
|
|
|
|
if (blocksj != null)
|
|
|
|
{
|
|
|
|
final long start = System.currentTimeMillis();
|
|
|
|
for (int k = 0; k < blocksj.length; k++)
|
|
|
|
{
|
|
|
|
if (once && ((System.currentTimeMillis() - start) > allocate))
|
|
|
|
{
|
2015-05-04 23:53:24 +10:00
|
|
|
SetBlockQueue.blocks.put(n.getKey(), blocks);
|
|
|
|
return;
|
|
|
|
}
|
2015-09-11 20:09:22 +10:00
|
|
|
final PlotBlock block = blocksj[k];
|
|
|
|
if (block != null)
|
|
|
|
{
|
|
|
|
final int x = MainUtil.x_loc[j][k];
|
|
|
|
final int y = MainUtil.y_loc[j][k];
|
|
|
|
final int z = MainUtil.z_loc[j][k];
|
2015-05-04 23:53:24 +10:00
|
|
|
BlockManager.manager.functionSetBlock(world, X + x, y, Z + z, block.id, block.data);
|
|
|
|
blocks[j][k] = null;
|
|
|
|
once = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
SetBlockQueue.blocks.remove(n.getKey());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
SetBlockQueue.blocks.remove(n.getKey());
|
2015-09-11 20:09:22 +10:00
|
|
|
for (int j = 0; j < blocks.length; j++)
|
|
|
|
{
|
|
|
|
final PlotBlock[] blocksj = blocks[j];
|
|
|
|
if (blocksj != null)
|
|
|
|
{
|
|
|
|
for (int k = 0; k < blocksj.length; k++)
|
|
|
|
{
|
|
|
|
final PlotBlock block = blocksj[k];
|
|
|
|
if (block != null)
|
|
|
|
{
|
|
|
|
final int x = MainUtil.x_loc[j][k];
|
|
|
|
final int y = MainUtil.y_loc[j][k];
|
|
|
|
final int z = MainUtil.z_loc[j][k];
|
2015-04-21 22:48:18 +10:00
|
|
|
BlockManager.manager.functionSetBlock(world, X + x, y, Z + z, block.id, block.data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-08-04 22:21:12 +10:00
|
|
|
}, 1);
|
2015-04-21 22:48:18 +10:00
|
|
|
TaskManager.tasks.put(current, task);
|
|
|
|
running = true;
|
|
|
|
}
|
|
|
|
}
|
2015-09-11 20:09:22 +10:00
|
|
|
|
|
|
|
public static void setChunk(final String world, final ChunkLoc loc, final PlotBlock[][] result)
|
|
|
|
{
|
2015-06-10 04:54:00 +10:00
|
|
|
locked = true;
|
2015-09-11 20:09:22 +10:00
|
|
|
if (!running)
|
|
|
|
{
|
2015-06-10 04:54:00 +10:00
|
|
|
init();
|
|
|
|
}
|
2015-09-11 20:09:22 +10:00
|
|
|
final ChunkWrapper wrap = new ChunkWrapper(world, loc.x, loc.z);
|
2015-06-10 04:54:00 +10:00
|
|
|
blocks.put(wrap, result);
|
|
|
|
locked = false;
|
|
|
|
}
|
2015-07-03 13:21:21 +02:00
|
|
|
|
2015-09-11 20:09:22 +10:00
|
|
|
public static void setBlock(final String world, int x, final int y, int z, final PlotBlock block)
|
|
|
|
{
|
2015-04-21 22:48:18 +10:00
|
|
|
locked = true;
|
2015-09-11 20:09:22 +10:00
|
|
|
if (!running)
|
|
|
|
{
|
2015-04-21 22:48:18 +10:00
|
|
|
init();
|
|
|
|
}
|
2015-09-11 20:09:22 +10:00
|
|
|
final int X = x >> 4;
|
|
|
|
final int Z = z >> 4;
|
2015-04-21 22:48:18 +10:00
|
|
|
x -= X << 4;
|
|
|
|
z -= Z << 4;
|
2015-07-03 13:21:21 +02:00
|
|
|
|
2015-09-11 20:09:22 +10:00
|
|
|
final ChunkWrapper wrap = new ChunkWrapper(world, X, Z);
|
2015-07-03 13:21:21 +02:00
|
|
|
PlotBlock[][] result;
|
2015-05-04 23:53:24 +10:00
|
|
|
result = blocks.get(wrap);
|
2015-09-11 20:09:22 +10:00
|
|
|
if (!blocks.containsKey(wrap))
|
|
|
|
{
|
2015-04-21 22:48:18 +10:00
|
|
|
result = new PlotBlock[16][];
|
|
|
|
blocks.put(wrap, result);
|
|
|
|
}
|
2015-09-11 20:09:22 +10:00
|
|
|
if ((y > 255) || (y < 0))
|
|
|
|
{
|
2015-08-30 16:19:35 +10:00
|
|
|
locked = false;
|
|
|
|
return;
|
|
|
|
}
|
2015-09-11 20:09:22 +10:00
|
|
|
if (result[y >> 4] == null)
|
|
|
|
{
|
2015-04-21 22:48:18 +10:00
|
|
|
result[y >> 4] = new PlotBlock[4096];
|
|
|
|
}
|
|
|
|
result[y >> 4][((y & 0xF) << 8) | (z << 4) | x] = block;
|
|
|
|
locked = false;
|
|
|
|
}
|
2015-09-11 20:09:22 +10:00
|
|
|
|
|
|
|
public static void setData(final String world, int x, final int y, int z, final byte data)
|
|
|
|
{
|
2015-06-08 05:37:40 +10:00
|
|
|
locked = true;
|
2015-09-11 20:09:22 +10:00
|
|
|
if (!running)
|
|
|
|
{
|
2015-06-08 05:37:40 +10:00
|
|
|
init();
|
|
|
|
}
|
2015-09-11 20:09:22 +10:00
|
|
|
final int X = x >> 4;
|
|
|
|
final int Z = z >> 4;
|
2015-06-08 05:37:40 +10:00
|
|
|
x -= X << 4;
|
|
|
|
z -= Z << 4;
|
2015-09-11 20:09:22 +10:00
|
|
|
final ChunkWrapper wrap = new ChunkWrapper(world, X, Z);
|
2015-06-08 05:37:40 +10:00
|
|
|
PlotBlock[][] result;
|
|
|
|
result = blocks.get(wrap);
|
2015-09-11 20:09:22 +10:00
|
|
|
if (result == null)
|
|
|
|
{
|
|
|
|
if (blocks == null)
|
|
|
|
{
|
2015-08-28 08:33:32 +10:00
|
|
|
init();
|
|
|
|
}
|
2015-06-08 05:37:40 +10:00
|
|
|
result = new PlotBlock[16][];
|
|
|
|
blocks.put(wrap, result);
|
|
|
|
}
|
2015-09-11 20:09:22 +10:00
|
|
|
if ((y > 255) || (y < 0))
|
|
|
|
{
|
2015-08-30 16:19:35 +10:00
|
|
|
locked = false;
|
|
|
|
return;
|
|
|
|
}
|
2015-09-11 20:09:22 +10:00
|
|
|
if (result[y >> 4] == null)
|
|
|
|
{
|
2015-06-08 05:37:40 +10:00
|
|
|
result[y >> 4] = new PlotBlock[4096];
|
|
|
|
}
|
|
|
|
result[y >> 4][((y & 0xF) << 8) | (z << 4) | x] = new PlotBlock((short) -1, data);
|
|
|
|
locked = false;
|
|
|
|
}
|
2015-09-11 20:09:22 +10:00
|
|
|
|
|
|
|
public static void setBlock(final String world, int x, final int y, int z, final int id)
|
|
|
|
{
|
2015-04-21 22:48:18 +10:00
|
|
|
locked = true;
|
2015-09-11 20:09:22 +10:00
|
|
|
if (!running)
|
|
|
|
{
|
2015-04-21 22:48:18 +10:00
|
|
|
init();
|
|
|
|
}
|
2015-09-11 20:09:22 +10:00
|
|
|
final int X = x >> 4;
|
|
|
|
final int Z = z >> 4;
|
2015-04-21 22:48:18 +10:00
|
|
|
x -= X << 4;
|
|
|
|
z -= Z << 4;
|
2015-09-11 20:09:22 +10:00
|
|
|
final ChunkWrapper wrap = new ChunkWrapper(world, X, Z);
|
2015-05-04 23:53:24 +10:00
|
|
|
PlotBlock[][] result;
|
|
|
|
result = blocks.get(wrap);
|
2015-09-11 20:09:22 +10:00
|
|
|
if (result == null)
|
|
|
|
{
|
|
|
|
if (blocks == null)
|
|
|
|
{
|
2015-08-28 08:33:32 +10:00
|
|
|
init();
|
|
|
|
}
|
2015-04-21 22:48:18 +10:00
|
|
|
result = new PlotBlock[16][];
|
|
|
|
blocks.put(wrap, result);
|
|
|
|
}
|
2015-09-11 20:09:22 +10:00
|
|
|
if ((y > 255) || (y < 0))
|
|
|
|
{
|
2015-08-30 16:19:35 +10:00
|
|
|
locked = false;
|
|
|
|
return;
|
|
|
|
}
|
2015-09-11 20:09:22 +10:00
|
|
|
if (result[y >> 4] == null)
|
|
|
|
{
|
2015-04-21 22:48:18 +10:00
|
|
|
result[y >> 4] = new PlotBlock[4096];
|
|
|
|
}
|
2015-09-11 20:09:22 +10:00
|
|
|
if (id == lastInt)
|
|
|
|
{
|
2015-04-21 22:48:18 +10:00
|
|
|
result[y >> 4][((y & 0xF) << 8) | (z << 4) | x] = lastBlock;
|
|
|
|
}
|
2015-09-11 20:09:22 +10:00
|
|
|
else
|
|
|
|
{
|
2015-04-21 22:48:18 +10:00
|
|
|
lastInt = id;
|
|
|
|
lastBlock = new PlotBlock((short) id, (byte) 0);
|
|
|
|
}
|
|
|
|
result[y >> 4][((y & 0xF) << 8) | (z << 4) | x] = lastBlock;
|
|
|
|
locked = false;
|
|
|
|
}
|
2015-09-11 20:09:22 +10:00
|
|
|
|
|
|
|
public static class ChunkWrapper
|
|
|
|
{
|
|
|
|
public final int x;
|
2015-04-27 00:56:10 +10:00
|
|
|
public final int z;
|
|
|
|
public final String world;
|
2015-09-11 20:09:22 +10:00
|
|
|
|
|
|
|
public ChunkWrapper(final String world, final int x, final int z)
|
|
|
|
{
|
2015-04-21 22:48:18 +10:00
|
|
|
this.world = world;
|
|
|
|
this.x = x;
|
|
|
|
this.z = z;
|
|
|
|
}
|
2015-09-11 20:09:22 +10:00
|
|
|
|
2015-04-21 22:48:18 +10:00
|
|
|
@Override
|
2015-09-11 20:09:22 +10:00
|
|
|
public int hashCode()
|
|
|
|
{
|
2015-04-21 22:48:18 +10:00
|
|
|
int result;
|
2015-09-11 20:09:22 +10:00
|
|
|
if (x >= 0)
|
|
|
|
{
|
|
|
|
if (z >= 0)
|
|
|
|
{
|
|
|
|
result = (x * x) + (3 * x) + (2 * x * z) + z + (z * z);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
final int y1 = -z;
|
|
|
|
result = (x * x) + (3 * x) + (2 * x * y1) + y1 + (y1 * y1) + 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
final int x1 = -x;
|
|
|
|
if (z >= 0)
|
|
|
|
{
|
|
|
|
result = -((x1 * x1) + (3 * x1) + (2 * x1 * z) + z + (z * z));
|
2015-04-21 22:48:18 +10:00
|
|
|
}
|
2015-09-11 20:09:22 +10:00
|
|
|
else
|
|
|
|
{
|
|
|
|
final int y1 = -z;
|
2015-04-21 22:48:18 +10:00
|
|
|
result = -((x1 * x1) + (3 * x1) + (2 * x1 * y1) + y1 + (y1 * y1) + 1);
|
|
|
|
}
|
|
|
|
}
|
2015-09-11 20:09:22 +10:00
|
|
|
result = (result * 31) + world.hashCode();
|
2015-04-21 22:48:18 +10:00
|
|
|
return result;
|
|
|
|
}
|
2015-09-11 20:09:22 +10:00
|
|
|
|
2015-04-21 22:48:18 +10:00
|
|
|
@Override
|
2015-09-11 20:09:22 +10:00
|
|
|
public boolean equals(final Object obj)
|
|
|
|
{
|
|
|
|
if (this == obj) { return true; }
|
|
|
|
if (obj == null) { return false; }
|
|
|
|
if (getClass() != obj.getClass()) { return false; }
|
2015-04-21 22:48:18 +10:00
|
|
|
final ChunkWrapper other = (ChunkWrapper) obj;
|
2015-09-11 20:09:22 +10:00
|
|
|
return ((x == other.x) && (z == other.z) && (world.equals(other.world)));
|
2015-04-21 22:48:18 +10:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|