mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2025-07-01 02:46:41 +00:00
Feature/unsafe over reflections (#1082)
* Use Unsafe to replace Lock * Start cleaning up everything that has to do with CleanableThreadLocal * Make cancellation work Co-authored-by: NotMyFault <mc.cache@web.de>
This commit is contained in:
@ -24,7 +24,6 @@ import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.object.FaweInputStream;
|
||||
import com.boydti.fawe.object.FaweLimit;
|
||||
import com.boydti.fawe.object.FaweOutputStream;
|
||||
import com.boydti.fawe.object.brush.visualization.VirtualWorld;
|
||||
import com.boydti.fawe.object.changeset.DiskStorageHistory;
|
||||
import com.boydti.fawe.object.clipboard.MultiClipboardHolder;
|
||||
import com.boydti.fawe.object.collection.SparseBitSet;
|
||||
@ -80,6 +79,8 @@ import com.sk89q.worldedit.world.item.ItemTypes;
|
||||
import com.sk89q.worldedit.world.snapshot.experimental.Snapshot;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
@ -92,15 +93,12 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.TimeZone;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
@ -159,7 +157,6 @@ public class LocalSession implements TextureHolder {
|
||||
private transient UUID uuid;
|
||||
private transient volatile long historySize = 0;
|
||||
|
||||
private transient VirtualWorld virtual;
|
||||
private transient BlockVector3 cuiTemporaryBlock;
|
||||
@SuppressWarnings("unused")
|
||||
private transient EditSession.ReorderMode reorderMode = EditSession.ReorderMode.MULTI_STAGE;
|
||||
@ -752,35 +749,6 @@ public class LocalSession implements TextureHolder {
|
||||
return selector.getRegion();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public VirtualWorld getVirtualWorld() {
|
||||
synchronized (dirty) {
|
||||
return virtual;
|
||||
}
|
||||
}
|
||||
|
||||
public void setVirtualWorld(@Nullable VirtualWorld world) {
|
||||
VirtualWorld tmp;
|
||||
synchronized (dirty) {
|
||||
tmp = this.virtual;
|
||||
if (tmp == world) {
|
||||
return;
|
||||
}
|
||||
this.virtual = world;
|
||||
}
|
||||
if (tmp != null) {
|
||||
try {
|
||||
tmp.close(world == null);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (world != null) {
|
||||
Fawe.imp().registerPacketListener();
|
||||
world.update();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the selection world.
|
||||
*
|
||||
@ -1234,10 +1202,6 @@ public class LocalSession implements TextureHolder {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (player != null && previous instanceof BrushTool) {
|
||||
BrushTool brushTool = (BrushTool) previous;
|
||||
brushTool.clear(player);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1723,14 +1687,4 @@ public class LocalSession implements TextureHolder {
|
||||
this.transform = transform;
|
||||
}
|
||||
|
||||
public void unregisterTools(Player player) {
|
||||
synchronized (tools) {
|
||||
for (Tool tool : tools.values()) {
|
||||
if (tool instanceof BrushTool) {
|
||||
((BrushTool) tool).clear(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -23,7 +23,6 @@ import com.boydti.fawe.config.Caption;
|
||||
import com.boydti.fawe.object.brush.BrushSettings;
|
||||
import com.boydti.fawe.object.brush.TargetMode;
|
||||
import com.boydti.fawe.object.brush.scroll.Scroll;
|
||||
import com.boydti.fawe.object.brush.visualization.VisualMode;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.boydti.fawe.util.StringMan;
|
||||
import com.google.common.collect.Iterables;
|
||||
@ -231,31 +230,6 @@ public class ToolUtilCommands {
|
||||
}
|
||||
}
|
||||
|
||||
@Command(
|
||||
name = "visualize",
|
||||
aliases = {"visual", "vis", "/visualize", "/visual", "/vis"},
|
||||
desc = "Toggle between different visualization modes",
|
||||
descFooter = "Toggle between different visualization modes\n"
|
||||
+ "0 = No visualization\n"
|
||||
+ "1 = Single block at target position\n"
|
||||
+ "2 = Glass showing what blocks will be changed"
|
||||
)
|
||||
@CommandPermissions("worldedit.brush.visualize")
|
||||
public void visual(Player player, LocalSession session,
|
||||
@Arg(name = "mode", desc = "int", def = "0")
|
||||
@Range(from = 0, to = 2)
|
||||
int mode) throws WorldEditException {
|
||||
BrushTool tool = session.getBrushTool(player, false);
|
||||
if (tool == null) {
|
||||
player.print(Caption.of("fawe.worldedit.brush.brush.none"));
|
||||
return;
|
||||
}
|
||||
VisualMode[] modes = VisualMode.values();
|
||||
VisualMode newMode = modes[MathMan.wrap(mode, 0, modes.length - 1)];
|
||||
tool.setVisualMode(player, newMode);
|
||||
player.print(Caption.of("fawe.worldedit.brush.brush.visual.mode.set", newMode));
|
||||
}
|
||||
|
||||
@Command(
|
||||
name = "target",
|
||||
aliases = {"tar", "/target", "/tar"},
|
||||
|
@ -19,10 +19,8 @@
|
||||
|
||||
package com.sk89q.worldedit.command.tool;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.beta.implementation.IChunkExtent;
|
||||
import com.boydti.fawe.beta.implementation.processors.NullProcessor;
|
||||
import com.boydti.fawe.beta.implementation.processors.PersistentChunkSendProcessor;
|
||||
import com.boydti.fawe.config.Caption;
|
||||
import com.boydti.fawe.object.brush.BrushSettings;
|
||||
import com.boydti.fawe.object.brush.MovableTool;
|
||||
@ -30,8 +28,6 @@ import com.boydti.fawe.object.brush.ResettableTool;
|
||||
import com.boydti.fawe.object.brush.TargetMode;
|
||||
import com.boydti.fawe.object.brush.scroll.Scroll;
|
||||
import com.boydti.fawe.object.brush.scroll.ScrollTool;
|
||||
import com.boydti.fawe.object.brush.visualization.VisualExtent;
|
||||
import com.boydti.fawe.object.brush.visualization.VisualMode;
|
||||
import com.boydti.fawe.object.extent.ResettableExtent;
|
||||
import com.boydti.fawe.object.mask.MaskedTargetBlock;
|
||||
import com.boydti.fawe.object.pattern.PatternTraverser;
|
||||
@ -93,7 +89,6 @@ public class BrushTool
|
||||
protected static int MAX_RANGE = 500;
|
||||
protected static int DEFAULT_RANGE = 240; // 500 is laggy as the default
|
||||
protected int range = -1;
|
||||
private VisualMode visualMode = VisualMode.NONE;
|
||||
private TargetMode targetMode = TargetMode.TARGET_BLOCK_RANGE;
|
||||
private Mask traceMask = null;
|
||||
private int targetOffset;
|
||||
@ -102,8 +97,6 @@ public class BrushTool
|
||||
private transient BrushSettings secondary = new BrushSettings();
|
||||
private transient BrushSettings context = primary;
|
||||
|
||||
private transient PersistentChunkSendProcessor visualExtent;
|
||||
|
||||
private transient BaseItem holder;
|
||||
|
||||
/**
|
||||
@ -517,26 +510,6 @@ public class BrushTool
|
||||
update();
|
||||
}
|
||||
|
||||
public void setVisualMode(Player player, VisualMode visualMode) {
|
||||
if (visualMode == null) {
|
||||
visualMode = VisualMode.NONE;
|
||||
}
|
||||
if (this.visualMode != visualMode) {
|
||||
if (this.visualMode != VisualMode.NONE) {
|
||||
clear(player);
|
||||
}
|
||||
this.visualMode = visualMode;
|
||||
if (visualMode != VisualMode.NONE) {
|
||||
try {
|
||||
queueVisualization(player);
|
||||
} catch (Throwable e) {
|
||||
WorldEdit.getInstance().getPlatformManager().handleThrowable(e, player);
|
||||
}
|
||||
}
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
public TargetMode getTargetMode() {
|
||||
return targetMode;
|
||||
}
|
||||
@ -545,114 +518,19 @@ public class BrushTool
|
||||
return targetOffset;
|
||||
}
|
||||
|
||||
public VisualMode getVisualMode() {
|
||||
return visualMode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean increment(Player player, int amount) {
|
||||
BrushSettings current = getContext();
|
||||
Scroll tmp = current.getScrollAction();
|
||||
if (tmp != null) {
|
||||
tmp.setTool(this);
|
||||
if (tmp.increment(player, amount)) {
|
||||
if (visualMode != VisualMode.NONE) {
|
||||
try {
|
||||
queueVisualization(player);
|
||||
} catch (Throwable e) {
|
||||
WorldEdit.getInstance().getPlatformManager().handleThrowable(e, player);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (visualMode != VisualMode.NONE) {
|
||||
clear(player);
|
||||
return tmp.increment(player, amount);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void queueVisualization(Player player) {
|
||||
Fawe.get().getVisualQueue().queue(player);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public synchronized void visualize(BrushTool.BrushAction action, Player player)
|
||||
throws WorldEditException {
|
||||
VisualMode mode = getVisualMode();
|
||||
if (mode == VisualMode.NONE) {
|
||||
return;
|
||||
}
|
||||
BrushSettings current = getContext();
|
||||
Brush brush = current.getBrush();
|
||||
if (brush == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
EditSessionBuilder builder =
|
||||
new EditSessionBuilder(player.getWorld()).command(current.toString()).player(player)
|
||||
.allowedRegionsEverywhere().autoQueue(false).blockBag(null).changeSetNull()
|
||||
.fastmode(true).combineStages(true);
|
||||
EditSession editSession = builder.build();
|
||||
|
||||
World world = editSession.getWorld();
|
||||
Supplier<Collection<Player>> players = () -> Collections.singleton(player);
|
||||
|
||||
PersistentChunkSendProcessor newVisualExtent =
|
||||
new PersistentChunkSendProcessor(world, this.visualExtent, players);
|
||||
ExtentTraverser<IChunkExtent> traverser =
|
||||
new ExtentTraverser<>(editSession).find(IChunkExtent.class);
|
||||
if (traverser == null) {
|
||||
throw new IllegalStateException("No queue found");
|
||||
}
|
||||
|
||||
IChunkExtent chunkExtent = traverser.get();
|
||||
if (this.visualExtent != null) {
|
||||
this.visualExtent.init(chunkExtent);
|
||||
}
|
||||
newVisualExtent.init(chunkExtent);
|
||||
|
||||
editSession.addProcessor(newVisualExtent);
|
||||
editSession.addProcessor(NullProcessor.getInstance());
|
||||
|
||||
BlockVector3 position = getPosition(editSession, player);
|
||||
if (position != null) {
|
||||
switch (mode) {
|
||||
case POINT:
|
||||
editSession.setBlock(position, VisualExtent.VISUALIZE_BLOCK_DEFAULT);
|
||||
break;
|
||||
case OUTLINE: {
|
||||
new PatternTraverser(current).reset(editSession);
|
||||
brush.build(editSession, position, current.getMaterial(), current.getSize());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new IllegalStateException("Unexpected value: " + mode);
|
||||
}
|
||||
}
|
||||
editSession.flushQueue();
|
||||
|
||||
if (visualExtent != null) {
|
||||
// clear old data
|
||||
visualExtent.flush();
|
||||
}
|
||||
visualExtent = newVisualExtent;
|
||||
newVisualExtent.flush();
|
||||
}
|
||||
|
||||
public void clear(Player player) {
|
||||
Fawe.get().getVisualQueue().dequeue(player);
|
||||
if (visualExtent != null) {
|
||||
visualExtent.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean move(Player player) {
|
||||
if (visualMode != VisualMode.NONE) {
|
||||
queueVisualization(player);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,6 @@ package com.sk89q.worldedit.entity;
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.config.Caption;
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.object.brush.visualization.VirtualWorld;
|
||||
import com.boydti.fawe.object.clipboard.DiskOptimizedClipboard;
|
||||
import com.boydti.fawe.regions.FaweMaskManager;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
@ -385,14 +384,6 @@ public interface Player extends Entity, Actor {
|
||||
* @return Editing world
|
||||
*/
|
||||
default World getWorldForEditing() {
|
||||
VirtualWorld virtual = getSession().getVirtualWorld();
|
||||
if (virtual != null) {
|
||||
return virtual;
|
||||
}
|
||||
// CFICommands.CFISettings cfi = getMeta("CFISettings");
|
||||
// if (cfi != null && cfi.hasGenerator() && cfi.getGenerator().hasPacketViewer()) {
|
||||
// return cfi.getGenerator();
|
||||
// }
|
||||
return WorldEdit.getInstance().getPlatformManager().getWorldForEditing(getWorld());
|
||||
}
|
||||
|
||||
@ -404,7 +395,6 @@ public interface Player extends Entity, Actor {
|
||||
getSession().setClipboard(null);
|
||||
if (Settings.IMP.HISTORY.DELETE_ON_LOGOUT) {
|
||||
getSession().clearHistory();
|
||||
getSession().unregisterTools(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,6 @@ package com.sk89q.worldedit.extension.platform;
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.object.FaweLimit;
|
||||
import com.boydti.fawe.object.brush.visualization.VirtualWorld;
|
||||
import com.boydti.fawe.util.task.InterruptableCondition;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.entity.MapMetadatable;
|
||||
@ -242,22 +241,6 @@ public interface Actor extends Identifiable, SessionOwner, Subject, MapMetadatab
|
||||
}
|
||||
}
|
||||
}
|
||||
VirtualWorld world = getSession().getVirtualWorld();
|
||||
if (world != null) {
|
||||
if (close) {
|
||||
try {
|
||||
world.close(false);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
world.close(false);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,6 @@ package com.sk89q.worldedit.extension.platform;
|
||||
|
||||
import com.boydti.fawe.config.Caption;
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.object.brush.visualization.VirtualWorld;
|
||||
import com.boydti.fawe.object.exception.FaweException;
|
||||
import com.boydti.fawe.object.pattern.PatternTraverser;
|
||||
import com.boydti.fawe.wrappers.LocationMaskedPlayerWrapper;
|
||||
@ -347,18 +346,6 @@ public class PlatformManager {
|
||||
try {
|
||||
Vector3 vector = location.toVector();
|
||||
|
||||
VirtualWorld virtual = session.getVirtualWorld();
|
||||
if (virtual != null) {
|
||||
if (Settings.IMP.EXPERIMENTAL.OTHER) {
|
||||
LOGGER.info("virtualWorld was not null in handlePlayerInput()");
|
||||
}
|
||||
|
||||
virtual.handleBlockInteract(player, vector.toBlockPoint(), event);
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (event.getType() == Interaction.HIT) {
|
||||
// superpickaxe is special because its primary interaction is a left click, not a right click
|
||||
// in addition, it is implicitly bound to all pickaxe items, not just a single tool item
|
||||
@ -421,16 +408,6 @@ public class PlatformManager {
|
||||
// making changes to the world
|
||||
Player player = createProxyActor(event.getPlayer());
|
||||
LocalSession session = worldEdit.getSessionManager().get(player);
|
||||
VirtualWorld virtual = session.getVirtualWorld();
|
||||
if (virtual != null) {
|
||||
if (Settings.IMP.EXPERIMENTAL.OTHER) {
|
||||
LOGGER.info("virtualWorld was not null in handlePlayerInput()");
|
||||
}
|
||||
virtual.handlePlayerInput(player, event);
|
||||
if (event.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
switch (event.getInputType()) {
|
||||
|
@ -507,6 +507,10 @@ public interface Extent extends InputExtent, OutputExtent {
|
||||
return true;
|
||||
}
|
||||
|
||||
default int getMinY() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
default int getMaxY() {
|
||||
return 255;
|
||||
}
|
||||
|
@ -19,22 +19,25 @@
|
||||
|
||||
package com.sk89q.worldedit.session.request;
|
||||
|
||||
import com.boydti.fawe.object.collection.CleanableThreadLocal;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
|
||||
import java.util.List;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Describes the current request using a {@link ThreadLocal}.
|
||||
*/
|
||||
public final class Request {
|
||||
|
||||
private static final CleanableThreadLocal<Request> threadLocal = new CleanableThreadLocal<>(Request::new);
|
||||
private static final ThreadLocal<Request> threadLocal = ThreadLocal.withInitial(Request::new);
|
||||
// TODO any better way to deal with this?
|
||||
private static final Map<Thread, Request> requests = new ConcurrentHashMap<>();
|
||||
|
||||
@Nullable
|
||||
private World world;
|
||||
@ -49,10 +52,11 @@ public final class Request {
|
||||
private boolean valid;
|
||||
|
||||
private Request() {
|
||||
requests.put(Thread.currentThread(), this);
|
||||
}
|
||||
|
||||
public static List<Request> getAll() {
|
||||
return threadLocal.getAll();
|
||||
public static Collection<Request> getAll() {
|
||||
return requests.values();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -154,6 +158,7 @@ public final class Request {
|
||||
public static void reset() {
|
||||
request().invalidate();
|
||||
threadLocal.remove();
|
||||
requests.remove(Thread.currentThread());
|
||||
}
|
||||
|
||||
/**
|
||||
|
Reference in New Issue
Block a user