Various fixes for VS / WE

This commit is contained in:
Jesse Boyd 2016-05-28 08:37:16 +10:00
parent b168d1b336
commit a05ae2e550
16 changed files with 207 additions and 52 deletions

View File

@ -34,7 +34,7 @@ public class AsyncBlock implements Block {
@Override @Override
public byte getData() { public byte getData() {
return (byte) (queue.getCombinedId4Data(x, y, z) & 0xF); return (byte) (queue.getCombinedId4Data(x, y, z, 0) & 0xF);
} }
@Override @Override
@ -54,12 +54,12 @@ public class AsyncBlock implements Block {
@Override @Override
public Material getType() { public Material getType() {
return Material.getMaterial(queue.getCombinedId4Data(x, y, z) >> 4); return Material.getMaterial(queue.getCombinedId4Data(x, y, z, 0) >> 4);
} }
@Override @Override
public int getTypeId() { public int getTypeId() {
return queue.getCombinedId4Data(x, y, z) >> 4; return queue.getCombinedId4Data(x, y, z, 0) >> 4;
} }
@Override @Override

View File

@ -22,7 +22,7 @@ public class AsyncBlockState implements BlockState {
public AsyncBlockState(AsyncBlock block) { public AsyncBlockState(AsyncBlock block) {
this.block = block; this.block = block;
int combined = block.queue.getCombinedId4Data(block.x, block.y, block.z); int combined = block.queue.getCombinedId4Data(block.x, block.y, block.z, 0);
this.id = (short) (combined >> 4); this.id = (short) (combined >> 4);
this.data = (byte) (combined & 0xF); this.data = (byte) (combined & 0xF);
if (FaweCache.hasNBT(id)) { if (FaweCache.hasNBT(id)) {

View File

@ -113,7 +113,7 @@ public class AsyncWorld implements World {
@Override @Override
@Deprecated @Deprecated
public int getBlockTypeIdAt(int x, int y, int z) { public int getBlockTypeIdAt(int x, int y, int z) {
return queue.getCombinedId4Data(x, y, z) >> 4; return queue.getCombinedId4Data(x, y, z, 0) >> 4;
} }
@Override @Override
@ -125,7 +125,7 @@ public class AsyncWorld implements World {
@Override @Override
public int getHighestBlockYAt(int x, int z) { public int getHighestBlockYAt(int x, int z) {
for (int y = 255; y >= 0; y--) { for (int y = 255; y >= 0; y--) {
if (queue.getCombinedId4Data(x, y, z) != 0) { if (queue.getCombinedId4Data(x, y, z, 0) != 0) {
return y; return y;
} }
} }

View File

@ -398,7 +398,11 @@ public class Sniper {
FaweChangeSet changeSet = changeQueue.getChangeSet(); FaweChangeSet changeSet = changeQueue.getChangeSet();
FawePlayer<Object> fp = FawePlayer.wrap(getPlayer()); FawePlayer<Object> fp = FawePlayer.wrap(getPlayer());
LocalSession session = fp.getSession(); LocalSession session = fp.getSession();
baseQueue.enqueue();
session.remember(changeSet.toEditSession(fp.getPlayer())); session.remember(changeSet.toEditSession(fp.getPlayer()));
changeQueue.flush();
com.sk89q.worldedit.world.World worldEditWorld = fp.getWorld();
changeQueue.setChangeSet(Settings.STORE_HISTORY_ON_DISK ? new DiskStorageHistory(worldEditWorld, fp.getUUID()) : new MemoryOptimizedHistory(worldEditWorld));
} }
} }

View File

@ -210,7 +210,30 @@ public class BukkitQueue_1_9_R1 extends BukkitQueue_0<Chunk, ChunkSection[], Dat
} }
} }
} }
c.initLighting(); final boolean flag = chunk.getWorld().getEnvironment() == Environment.NORMAL;
{
int i = c.g();
for(int x = 0; x < 16; ++x) {
for (int z = 0; z < 16; ++z) {
int l = 15;
int i1 = i + 16 - 1;
do {
int opacity = c.a(x, i1, z).c();
if (opacity == 0 && l != 15) {
opacity = 1;
}
l -= opacity;
if (l > 0) {
ChunkSection section = sections[i1 >> 4];
if (section != null) {
section.a(x, i1 & 15, z, l);
}
}
--i1;
} while (i1 > 0 && l > 0);
}
}
}
if (((bc.getTotalRelight() == 0) && mode == RelightMode.MINIMAL)) { if (((bc.getTotalRelight() == 0) && mode == RelightMode.MINIMAL)) {
return true; return true;
} }

View File

@ -395,6 +395,10 @@ public class Fawe {
return this.thread; return this.thread;
} }
public boolean isMainThread() {
return Thread.currentThread() == thread;
}
/** /**
* Sets the main thread to the current thread * Sets the main thread to the current thread
* @return * @return

View File

@ -188,8 +188,10 @@ public abstract class CharFaweChunk<T> extends FaweChunk<T> {
char[] vs = this.ids[i]; char[] vs = this.ids[i];
if (vs == null) { if (vs == null) {
vs = this.ids[i] = new char[4096]; vs = this.ids[i] = new char[4096];
this.count[i]++;
} else if (vs[j] == 0) {
this.count[i]++;
} }
this.count[i]++;
switch (id) { switch (id) {
case 0: case 0:
this.air[i]++; this.air[i]++;

View File

@ -7,7 +7,7 @@ import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.world.biome.BaseBiome; import com.sk89q.worldedit.world.biome.BaseBiome;
public class ChangeSetFaweQueue extends DelegateFaweQueue { public class ChangeSetFaweQueue extends DelegateFaweQueue {
private final FaweChangeSet set; private FaweChangeSet set;
public ChangeSetFaweQueue(FaweChangeSet set, FaweQueue parent) { public ChangeSetFaweQueue(FaweChangeSet set, FaweQueue parent) {
super(parent); super(parent);
@ -18,6 +18,10 @@ public class ChangeSetFaweQueue extends DelegateFaweQueue {
return set; return set;
} }
public void setChangeSet(FaweChangeSet set) {
this.set = set;
}
@Override @Override
public boolean setBlock(int x, int y, int z, short id, byte data) { public boolean setBlock(int x, int y, int z, short id, byte data) {
if (super.setBlock(x, y, z, id, data)) { if (super.setBlock(x, y, z, id, data)) {

View File

@ -28,7 +28,6 @@ import java.io.File;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@ -394,4 +393,39 @@ public abstract class FawePlayer<T> {
public EditSession getNewEditSession() { public EditSession getNewEditSession() {
return WorldEdit.getInstance().getEditSessionFactory().getEditSession(getWorld(), -1, getPlayer()); return WorldEdit.getInstance().getEditSessionFactory().getEditSession(getWorld(), -1, getPlayer());
} }
public boolean runIfFree(Runnable run) {
if (getMeta("fawe_action") != null) {
return false;
}
setMeta("fawe_action", true);
try {
run.run();
} catch (Throwable e) {
e.printStackTrace();
} finally {
deleteMeta("fawe_action");
}
return true;
}
public boolean runAsyncIfFree(final Runnable run) {
if (getMeta("fawe_action") != null) {
return false;
}
setMeta("fawe_action", true);
TaskManager.IMP.async(new Runnable() {
@Override
public void run() {
try {
run.run();
} catch (Throwable e) {
e.printStackTrace();
} finally {
deleteMeta("fawe_action");
}
}
});
return true;
}
} }

View File

@ -2,10 +2,12 @@ package com.boydti.fawe.object;
import com.boydti.fawe.Fawe; import com.boydti.fawe.Fawe;
import com.boydti.fawe.config.BBC; import com.boydti.fawe.config.BBC;
import com.boydti.fawe.config.Settings;
import com.boydti.fawe.object.exception.FaweException; import com.boydti.fawe.object.exception.FaweException;
import com.boydti.fawe.util.MainUtil; import com.boydti.fawe.util.MainUtil;
import com.boydti.fawe.util.MemUtil; import com.boydti.fawe.util.MemUtil;
import com.boydti.fawe.util.SetQueue; import com.boydti.fawe.util.SetQueue;
import com.boydti.fawe.util.TaskManager;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.world.biome.BaseBiome; import com.sk89q.worldedit.world.biome.BaseBiome;
@ -13,6 +15,7 @@ import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.LinkedBlockingDeque; import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.atomic.AtomicBoolean;
public abstract class FaweQueue { public abstract class FaweQueue {
@ -189,6 +192,26 @@ public abstract class FaweQueue {
public abstract int size(); public abstract int size();
/**
* Lock the thread until the queue is empty
*/
public void flush() {
if (size() > 0) {
if (Fawe.get().isMainThread()) {
SetQueue.IMP.flush(this);
} else {
final AtomicBoolean running = new AtomicBoolean(true);
addNotifyTask(new Runnable() {
@Override
public void run() {
TaskManager.IMP.notify(running);
}
});
TaskManager.IMP.wait(running, Settings.QUEUE_DISCARD_AFTER);
}
}
}
public void enqueue() { public void enqueue() {
SetQueue.IMP.enqueue(this); SetQueue.IMP.enqueue(this);
} }

View File

@ -24,7 +24,7 @@ public class PlotSquaredFeature extends FaweMaskManager {
final HashSet<RegionWrapper> regions = WEManager.getMask(pp); final HashSet<RegionWrapper> regions = WEManager.getMask(pp);
if (regions.size() == 0) { if (regions.size() == 0) {
Plot plot = pp.getCurrentPlot(); Plot plot = pp.getCurrentPlot();
if (plot.isOwner(pp.getUUID())) { if (plot != null && plot.isOwner(pp.getUUID())) {
System.out.println("INVALID MASK? " + WEManager.getMask(pp) + " | " + plot + " | " + pp.getName()); System.out.println("INVALID MASK? " + WEManager.getMask(pp) + " | " + plot + " | " + pp.getName());
} }
return null; return null;

View File

@ -175,6 +175,45 @@ public class SetQueue {
return queue; return queue;
} }
public void flush(FaweQueue queue) {
SET_TASK.value1 = Long.MAX_VALUE;
SET_TASK.value2 = queue;
if (SET_TASK.value2 == null) {
return;
}
if (Thread.currentThread() != Fawe.get().getMainThread()) {
throw new IllegalStateException("Must be flushed on the main thread!");
}
// Disable the async catcher as it can't discern async vs parallel
SET_TASK.value2.startSet(true);
try {
if (Settings.PARALLEL_THREADS <= 1) {
SET_TASK.run();
} else {
ArrayList<Thread> threads = new ArrayList<Thread>();
for (int i = 0; i < Settings.PARALLEL_THREADS; i++) {
threads.add(new Thread(SET_TASK));
}
for (Thread thread : threads) {
thread.start();
}
for (Thread thread : threads) {
try {
thread.join();
} catch (InterruptedException e) {
MainUtil.handleError(e);
}
}
}
} catch (Throwable e) {
MainUtil.handleError(e);
} finally {
// Enable it again (note that we are still on the main thread)
SET_TASK.value2.endSet(true);
dequeue(queue);
}
}
public FaweQueue getNextQueue() { public FaweQueue getNextQueue() {
while (activeQueues.size() > 0) { while (activeQueues.size() > 0) {
FaweQueue queue = activeQueues.peek(); FaweQueue queue = activeQueues.peek();

View File

@ -396,7 +396,6 @@ public class EditSession implements Extent {
public boolean cancel() { public boolean cancel() {
// Cancel this // Cancel this
if (primaryExtent != null && queue != null) { if (primaryExtent != null && queue != null) {
System.out.println("CANCEL");
try { try {
WEManager.IMP.cancelEdit(primaryExtent, BBC.WORLDEDIT_CANCEL_REASON_MANUAL); WEManager.IMP.cancelEdit(primaryExtent, BBC.WORLDEDIT_CANCEL_REASON_MANUAL);
} catch (Throwable ignore) {} } catch (Throwable ignore) {}
@ -965,27 +964,24 @@ public class EditSession implements Extent {
Operations.completeBlindly(commit()); Operations.completeBlindly(commit());
// Enqueue it // Enqueue it
if (queue != null && queue.size() > 0) { if (queue != null && queue.size() > 0) {
SetQueue.IMP.enqueue(queue); queue.enqueue();
} }
if (changeSet != null) { if (changeSet != null) {
if (Settings.COMBINE_HISTORY_STAGE && queue.size() > 0) { if (Settings.COMBINE_HISTORY_STAGE && queue.size() > 0) {
final AtomicBoolean running = new AtomicBoolean(true); if (Fawe.get().isMainThread()) {
queue.addNotifyTask(new Runnable() { SetQueue.IMP.flush(queue);
@Override } else {
public void run() { final AtomicBoolean running = new AtomicBoolean(true);
TaskManager.IMP.async(new Runnable() { queue.addNotifyTask(new Runnable() {
@Override @Override
public void run() { public void run() {
changeSet.flush(); TaskManager.IMP.notify(running);
TaskManager.IMP.notify(running); }
} });
}); TaskManager.IMP.wait(running, Settings.QUEUE_DISCARD_AFTER);
} }
});
TaskManager.IMP.wait(running, Settings.QUEUE_DISCARD_AFTER);
} else {
changeSet.flush();
} }
changeSet.flush();
} }
} }

View File

@ -200,6 +200,8 @@ public class LocalSession {
if (editSession == null || editSession.getChangeSet() == null) { if (editSession == null || editSession.getChangeSet() == null) {
return; return;
} }
// It should have already been flushed, but just in case!
editSession.flushQueue();
if (Settings.STORE_HISTORY_ON_DISK) { if (Settings.STORE_HISTORY_ON_DISK) {
MAX_HISTORY_SIZE = Integer.MAX_VALUE; MAX_HISTORY_SIZE = Integer.MAX_VALUE;
} }

View File

@ -295,12 +295,14 @@ public final class CommandManager {
} }
if (fp != null) { if (fp != null) {
fp.deleteMeta("fawe_action"); fp.deleteMeta("fawe_action");
final long time = System.currentTimeMillis() - start; if (editSession != null) {
if (time > 0) { final long time = System.currentTimeMillis() - start;
BBC.ACTION_COMPLETE.send(actor, (time / 50d)); if (time > 0) {
ChangeSet fcs = editSession.getChangeSet(); BBC.ACTION_COMPLETE.send(actor, (time / 1000d));
if (fcs != null && fcs instanceof FaweStreamChangeSet) { ChangeSet fcs = editSession.getChangeSet();
MainUtil.sendCompressedMessage((FaweStreamChangeSet) fcs, editSession.getActor()); if (fcs != null && fcs instanceof FaweStreamChangeSet) {
MainUtil.sendCompressedMessage((FaweStreamChangeSet) fcs, editSession.getActor());
}
} }
} }
} }

View File

@ -20,6 +20,7 @@
package com.sk89q.worldedit.extension.platform; package com.sk89q.worldedit.extension.platform;
import com.boydti.fawe.config.BBC; import com.boydti.fawe.config.BBC;
import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.object.exception.FaweException; import com.boydti.fawe.object.exception.FaweException;
import com.boydti.fawe.util.MainUtil; import com.boydti.fawe.util.MainUtil;
import com.sk89q.worldedit.LocalConfiguration; import com.sk89q.worldedit.LocalConfiguration;
@ -335,13 +336,13 @@ public class PlatformManager {
// making changes to the world // making changes to the world
Actor actor = createProxyActor(event.getCause()); Actor actor = createProxyActor(event.getCause());
try { try {
Location location = event.getLocation(); final Location location = event.getLocation();
Vector vector = location.toVector(); Vector vector = location.toVector();
// At this time, only handle interaction from players // At this time, only handle interaction from players
if (actor instanceof Player) { if (actor instanceof Player) {
Player player = (Player) actor; final Player player = (Player) actor;
LocalSession session = worldEdit.getSessionManager().get(actor); final LocalSession session = worldEdit.getSessionManager().get(actor);
if (event.getType() == Interaction.HIT) { if (event.getType() == Interaction.HIT) {
if (player.getItemInHand() == getConfiguration().wandItem) { if (player.getItemInHand() == getConfiguration().wandItem) {
@ -362,7 +363,6 @@ public class PlatformManager {
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
if (player.isHoldingPickAxe() && session.hasSuperPickAxe()) { if (player.isHoldingPickAxe() && session.hasSuperPickAxe()) {
final BlockTool superPickaxe = session.getSuperPickaxe(); final BlockTool superPickaxe = session.getSuperPickaxe();
if (superPickaxe != null && superPickaxe.canUse(player)) { if (superPickaxe != null && superPickaxe.canUse(player)) {
@ -370,15 +370,19 @@ public class PlatformManager {
return; return;
} }
} }
final Tool tool = session.getTool(player.getItemInHand());
Tool tool = session.getTool(player.getItemInHand());
if (tool != null && tool instanceof DoubleActionBlockTool) { if (tool != null && tool instanceof DoubleActionBlockTool) {
if (tool.canUse(player)) { if (tool.canUse(player)) {
((DoubleActionBlockTool) tool).actSecondary(queryCapability(Capability.WORLD_EDITING), getConfiguration(), player, session, location); FawePlayer<?> fp = FawePlayer.wrap(player);
fp.runAsyncIfFree(new Runnable() {
@Override
public void run() {
((DoubleActionBlockTool) tool).actSecondary(queryCapability(Capability.WORLD_EDITING), getConfiguration(), player, session, location);
}
});
event.setCancelled(true); event.setCancelled(true);
} }
} }
} else if (event.getType() == Interaction.OPEN) { } else if (event.getType() == Interaction.OPEN) {
if (player.getItemInHand() == getConfiguration().wandItem) { if (player.getItemInHand() == getConfiguration().wandItem) {
if (!session.isToolControlEnabled()) { if (!session.isToolControlEnabled()) {
@ -398,10 +402,16 @@ public class PlatformManager {
return; return;
} }
Tool tool = session.getTool(player.getItemInHand()); final Tool tool = session.getTool(player.getItemInHand());
if (tool != null && tool instanceof BlockTool) { if (tool != null && tool instanceof BlockTool) {
if (tool.canUse(player)) { if (tool.canUse(player)) {
((BlockTool) tool).actPrimary(queryCapability(Capability.WORLD_EDITING), getConfiguration(), player, session, location); FawePlayer<?> fp = FawePlayer.wrap(player);
fp.runAsyncIfFree(new Runnable() {
@Override
public void run() {
((BlockTool) tool).actPrimary(queryCapability(Capability.WORLD_EDITING), getConfiguration(), player, session, location);
}
});
event.setCancelled(true); event.setCancelled(true);
} }
} }
@ -424,7 +434,7 @@ public class PlatformManager {
public void handlePlayerInput(PlayerInputEvent event) { public void handlePlayerInput(PlayerInputEvent event) {
// Create a proxy actor with a potentially different world for // Create a proxy actor with a potentially different world for
// making changes to the world // making changes to the world
Player player = createProxyActor(event.getPlayer()); final Player player = createProxyActor(event.getPlayer());
try { try {
switch (event.getInputType()) { switch (event.getInputType()) {
case PRIMARY: { case PRIMARY: {
@ -448,12 +458,18 @@ public class PlatformManager {
return; return;
} }
LocalSession session = worldEdit.getSessionManager().get(player); final LocalSession session = worldEdit.getSessionManager().get(player);
Tool tool = session.getTool(player.getItemInHand()); final Tool tool = session.getTool(player.getItemInHand());
if (tool != null && tool instanceof DoubleActionTraceTool) { if (tool != null && tool instanceof DoubleActionTraceTool) {
if (tool.canUse(player)) { if (tool.canUse(player)) {
((DoubleActionTraceTool) tool).actSecondary(queryCapability(Capability.WORLD_EDITING), getConfiguration(), player, session); FawePlayer<?> fp = FawePlayer.wrap(player);
fp.runAsyncIfFree(new Runnable() {
@Override
public void run() {
((DoubleActionTraceTool) tool).actSecondary(queryCapability(Capability.WORLD_EDITING), getConfiguration(), player, session);
}
});
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
@ -480,12 +496,18 @@ public class PlatformManager {
return; return;
} }
LocalSession session = worldEdit.getSessionManager().get(player); final LocalSession session = worldEdit.getSessionManager().get(player);
Tool tool = session.getTool(player.getItemInHand()); final Tool tool = session.getTool(player.getItemInHand());
if (tool != null && tool instanceof TraceTool) { if (tool != null && tool instanceof TraceTool) {
if (tool.canUse(player)) { if (tool.canUse(player)) {
((TraceTool) tool).actPrimary(queryCapability(Capability.WORLD_EDITING), getConfiguration(), player, session); FawePlayer<?> fp = FawePlayer.wrap(player);
fp.runAsyncIfFree(new Runnable() {
@Override
public void run() {
((TraceTool) tool).actPrimary(queryCapability(Capability.WORLD_EDITING), getConfiguration(), player, session);
}
});
event.setCancelled(true); event.setCancelled(true);
return; return;
} }