Mirror von
https://github.com/IntellectualSites/FastAsyncWorldEdit.git
synchronisiert 2024-11-08 04:20:06 +01:00
Various minor changes
Dieser Commit ist enthalten in:
Ursprung
e2d7a5918d
Commit
b818c03f84
@ -13,25 +13,9 @@ public class DBHandler {
|
|||||||
|
|
||||||
public final static DBHandler IMP = new DBHandler();
|
public final static DBHandler IMP = new DBHandler();
|
||||||
|
|
||||||
private Map<String, RollbackDatabase> databases = new ConcurrentHashMap<>(8, 0.9f, 1);
|
private Map<World, RollbackDatabase> databases = new ConcurrentHashMap<>(8, 0.9f, 1);
|
||||||
|
|
||||||
public RollbackDatabase getDatabase(World world) {
|
public RollbackDatabase getDatabase(World world) {
|
||||||
String worldName = world.getName();
|
|
||||||
RollbackDatabase database = databases.get(worldName);
|
|
||||||
if (database != null) {
|
|
||||||
return database;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
database = new RollbackDatabase(world);
|
|
||||||
databases.put(worldName, database);
|
|
||||||
return database;
|
|
||||||
} catch (Throwable e) {
|
|
||||||
log.error("No JDBC driver found!\n TODO: Bundle driver with FAWE (or disable database)", e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public RollbackDatabase getDatabase(String world) {
|
|
||||||
RollbackDatabase database = databases.get(world);
|
RollbackDatabase database = databases.get(world);
|
||||||
if (database != null) {
|
if (database != null) {
|
||||||
return database;
|
return database;
|
||||||
@ -41,8 +25,9 @@ public class DBHandler {
|
|||||||
databases.put(world, database);
|
databases.put(world, database);
|
||||||
return database;
|
return database;
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
log.error("No JDBC driver found!", e);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package com.boydti.fawe.database;
|
package com.boydti.fawe.database;
|
||||||
|
|
||||||
import com.boydti.fawe.Fawe;
|
import com.boydti.fawe.Fawe;
|
||||||
import com.boydti.fawe.FaweAPI;
|
|
||||||
import com.boydti.fawe.config.Settings;
|
import com.boydti.fawe.config.Settings;
|
||||||
import com.boydti.fawe.logging.rollback.RollbackOptimizedHistory;
|
import com.boydti.fawe.logging.rollback.RollbackOptimizedHistory;
|
||||||
import com.boydti.fawe.object.collection.YieldIterable;
|
import com.boydti.fawe.object.collection.YieldIterable;
|
||||||
@ -36,7 +35,6 @@ public class RollbackDatabase extends AsyncNotifyQueue {
|
|||||||
|
|
||||||
private final String prefix;
|
private final String prefix;
|
||||||
private final File dbLocation;
|
private final File dbLocation;
|
||||||
private final String worldName;
|
|
||||||
private final World world;
|
private final World world;
|
||||||
private Connection connection;
|
private Connection connection;
|
||||||
|
|
||||||
@ -56,14 +54,9 @@ public class RollbackDatabase extends AsyncNotifyQueue {
|
|||||||
|
|
||||||
private ConcurrentLinkedQueue<RollbackOptimizedHistory> historyChanges = new ConcurrentLinkedQueue<>();
|
private ConcurrentLinkedQueue<RollbackOptimizedHistory> historyChanges = new ConcurrentLinkedQueue<>();
|
||||||
|
|
||||||
public RollbackDatabase(String world) throws SQLException, ClassNotFoundException {
|
RollbackDatabase(World world) throws SQLException, ClassNotFoundException {
|
||||||
this(FaweAPI.getWorld(world));
|
|
||||||
}
|
|
||||||
|
|
||||||
public RollbackDatabase(World world) throws SQLException, ClassNotFoundException {
|
|
||||||
super((t, e) -> e.printStackTrace());
|
super((t, e) -> e.printStackTrace());
|
||||||
this.prefix = "";
|
this.prefix = "";
|
||||||
this.worldName = world.getName();
|
|
||||||
this.world = world;
|
this.world = world;
|
||||||
this.dbLocation = MainUtil.getFile(Fawe.imp().getDirectory(), Settings.IMP.PATHS.HISTORY + File.separator + world.getName() + File.separator + "summary.db");
|
this.dbLocation = MainUtil.getFile(Fawe.imp().getDirectory(), Settings.IMP.PATHS.HISTORY + File.separator + world.getName() + File.separator + "summary.db");
|
||||||
connection = openConnection();
|
connection = openConnection();
|
||||||
@ -180,7 +173,6 @@ public class RollbackDatabase extends AsyncNotifyQueue {
|
|||||||
int count = 0;
|
int count = 0;
|
||||||
String stmtStr = ascending ? uuid == null ? GET_EDITS_ASC : GET_EDITS_USER_ASC :
|
String stmtStr = ascending ? uuid == null ? GET_EDITS_ASC : GET_EDITS_USER_ASC :
|
||||||
uuid == null ? GET_EDITS : GET_EDITS_USER;
|
uuid == null ? GET_EDITS : GET_EDITS_USER;
|
||||||
// `time`>? AND `x2`>=? AND `x1`<=? AND `z2`>=? AND `z1`<=? AND `y2`>=? AND `y1`<=? AND `player`=? ORDER BY `time` DESC, `id` DESC"
|
|
||||||
try (PreparedStatement stmt = connection.prepareStatement(stmtStr)) {
|
try (PreparedStatement stmt = connection.prepareStatement(stmtStr)) {
|
||||||
stmt.setInt(1, (int) (minTime / 1000));
|
stmt.setInt(1, (int) (minTime / 1000));
|
||||||
stmt.setInt(2, pos1.getBlockX());
|
stmt.setInt(2, pos1.getBlockX());
|
||||||
@ -200,10 +192,7 @@ public class RollbackDatabase extends AsyncNotifyQueue {
|
|||||||
do {
|
do {
|
||||||
count++;
|
count++;
|
||||||
Supplier<RollbackOptimizedHistory> history = create(result);
|
Supplier<RollbackOptimizedHistory> history = create(result);
|
||||||
// if (history.getBDFile().exists())
|
|
||||||
{
|
|
||||||
yieldIterable.accept(history);
|
yieldIterable.accept(history);
|
||||||
}
|
|
||||||
} while (result.next());
|
} while (result.next());
|
||||||
}
|
}
|
||||||
if (delete && uuid != null) {
|
if (delete && uuid != null) {
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
package com.boydti.fawe.object.brush;
|
|
||||||
|
|
||||||
import com.sk89q.worldedit.command.tool.BrushTool;
|
|
||||||
import com.sk89q.worldedit.command.tool.brush.Brush;
|
|
||||||
|
|
||||||
public abstract class AbstractBrush implements Brush {
|
|
||||||
private BrushTool tool;
|
|
||||||
|
|
||||||
public AbstractBrush(BrushTool tool) {
|
|
||||||
this.tool = tool;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTool(BrushTool tool) {
|
|
||||||
this.tool = tool;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BrushTool getTool() {
|
|
||||||
return tool;
|
|
||||||
}
|
|
||||||
}
|
|
@ -46,23 +46,17 @@ public class StencilBrush extends HeightBrush {
|
|||||||
} else {
|
} else {
|
||||||
add = 0;
|
add = 0;
|
||||||
}
|
}
|
||||||
double scale = (yscale / sizeDouble) * (maxY + 1);
|
|
||||||
final HeightMap map = getHeightMap();
|
final HeightMap map = getHeightMap();
|
||||||
map.setSize(size);
|
map.setSize(size);
|
||||||
int cutoff = onlyWhite ? maxY : 0;
|
int cutoff = onlyWhite ? maxY : 0;
|
||||||
final SolidBlockMask solid = new SolidBlockMask(editSession);
|
final SolidBlockMask solid = new SolidBlockMask(editSession);
|
||||||
final AdjacentAnyMask adjacent = new AdjacentAnyMask(Masks.negate(solid));
|
|
||||||
|
|
||||||
// BlockVector3 pos = player.getLocation();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Location loc = editSession.getPlayer().getLocation();
|
Location loc = editSession.getPlayer().getLocation();
|
||||||
float yaw = loc.getYaw();
|
float yaw = loc.getYaw();
|
||||||
float pitch = loc.getPitch();
|
float pitch = loc.getPitch();
|
||||||
AffineTransform transform = new AffineTransform().rotateY((-yaw) % 360).rotateX(pitch - 90).inverse();
|
AffineTransform transform = new AffineTransform().rotateY((-yaw) % 360).rotateX(pitch - 90).inverse();
|
||||||
|
|
||||||
|
double scale = (yscale / sizeDouble) * (maxY + 1);
|
||||||
RecursiveVisitor visitor = new RecursiveVisitor(new AbstractExtentMask(editSession) {
|
RecursiveVisitor visitor = new RecursiveVisitor(new AbstractExtentMask(editSession) {
|
||||||
private final MutableVector3 mutable = new MutableVector3();
|
private final MutableVector3 mutable = new MutableVector3();
|
||||||
@Override
|
@Override
|
||||||
@ -96,8 +90,4 @@ public class StencilBrush extends HeightBrush {
|
|||||||
visitor.visit(position);
|
visitor.visit(position);
|
||||||
Operations.completeBlindly(visitor);
|
Operations.completeBlindly(visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void apply(double val) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -37,12 +37,10 @@ public class SurfaceSpline implements Brush {
|
|||||||
if (path.isEmpty() || !pos.equals(path.get(path.size() - 1))) {
|
if (path.isEmpty() || !pos.equals(path.get(path.size() - 1))) {
|
||||||
int max = editSession.getNearestSurfaceTerrainBlock(pos.getBlockX(), pos.getBlockZ(), pos.getBlockY(), 0, editSession.getMaxY());
|
int max = editSession.getNearestSurfaceTerrainBlock(pos.getBlockX(), pos.getBlockZ(), pos.getBlockY(), 0, editSession.getMaxY());
|
||||||
if (max == -1) return;
|
if (max == -1) return;
|
||||||
// pos.mutY(max);
|
|
||||||
path.add(BlockVector3.at(pos.getBlockX(), max, pos.getBlockZ()));
|
path.add(BlockVector3.at(pos.getBlockX(), max, pos.getBlockZ()));
|
||||||
editSession.getPlayer().print(TranslatableComponent.of("fawe.worldedit.brush.spline.primary.2"));
|
editSession.getPlayer().printInfo(TranslatableComponent.of("fawe.worldedit.brush.spline.primary.2"));
|
||||||
if (!vis) return;
|
if (!vis) return;
|
||||||
}
|
}
|
||||||
LocalBlockVectorSet vset = new LocalBlockVectorSet();
|
|
||||||
final List<Node> nodes = new ArrayList<>(path.size());
|
final List<Node> nodes = new ArrayList<>(path.size());
|
||||||
final KochanekBartelsInterpolation interpol = new KochanekBartelsInterpolation();
|
final KochanekBartelsInterpolation interpol = new KochanekBartelsInterpolation();
|
||||||
|
|
||||||
@ -56,6 +54,7 @@ public class SurfaceSpline implements Brush {
|
|||||||
MutableBlockVector3 mutable = MutableBlockVector3.at(0, 0, 0);
|
MutableBlockVector3 mutable = MutableBlockVector3.at(0, 0, 0);
|
||||||
interpol.setNodes(nodes);
|
interpol.setNodes(nodes);
|
||||||
final double splinelength = interpol.arcLength(0, 1);
|
final double splinelength = interpol.arcLength(0, 1);
|
||||||
|
LocalBlockVectorSet vset = new LocalBlockVectorSet();
|
||||||
for (double loop = 0; loop <= 1; loop += 1D / splinelength / quality) {
|
for (double loop = 0; loop <= 1; loop += 1D / splinelength / quality) {
|
||||||
final Vector3 tipv = interpol.getPosition(loop);
|
final Vector3 tipv = interpol.getPosition(loop);
|
||||||
final int tipx = MathMan.roundInt(tipv.getX());
|
final int tipx = MathMan.roundInt(tipv.getX());
|
||||||
@ -93,6 +92,6 @@ public class SurfaceSpline implements Brush {
|
|||||||
editSession.setBlocks(newSet, pattern);
|
editSession.setBlocks(newSet, pattern);
|
||||||
if (!vis) path.clear();
|
if (!vis) path.clear();
|
||||||
}
|
}
|
||||||
editSession.getPlayer().print(TranslatableComponent.of("fawe.worldedit.brush.spline.secondary"));
|
editSession.getPlayer().printInfo(TranslatableComponent.of("fawe.worldedit.brush.spline.secondary"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -228,9 +228,6 @@ public abstract class AbstractChangeSet implements ChangeSet, IBatchProcessor {
|
|||||||
|
|
||||||
public abstract Iterator<Change> getIterator(boolean redo);
|
public abstract Iterator<Change> getIterator(boolean redo);
|
||||||
|
|
||||||
public void delete() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public EditSession toEditSession(Player player) {
|
public EditSession toEditSession(Player player) {
|
||||||
return toEditSession(player, null);
|
return toEditSession(player, null);
|
||||||
}
|
}
|
||||||
|
@ -1,539 +0,0 @@
|
|||||||
package com.boydti.fawe.util.task;
|
|
||||||
|
|
||||||
import com.boydti.fawe.Fawe;
|
|
||||||
import com.boydti.fawe.beta.IQueueExtent;
|
|
||||||
import com.boydti.fawe.beta.implementation.queue.QueueHandler;
|
|
||||||
import com.boydti.fawe.object.Metadatable;
|
|
||||||
import com.boydti.fawe.object.RunnableVal;
|
|
||||||
import com.boydti.fawe.util.TaskManager;
|
|
||||||
import java.util.ArrayDeque;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.concurrent.ForkJoinPool;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
public class TaskBuilder extends Metadatable {
|
|
||||||
|
|
||||||
private final ForkJoinPool pool = new ForkJoinPool();
|
|
||||||
private final ArrayDeque<RunnableTask> tasks;
|
|
||||||
private Object result = null;
|
|
||||||
private Thread.UncaughtExceptionHandler handler;
|
|
||||||
|
|
||||||
public TaskBuilder() {
|
|
||||||
this(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public TaskBuilder(Thread.UncaughtExceptionHandler handler) {
|
|
||||||
tasks = new ArrayDeque<>();
|
|
||||||
this.handler = handler;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TaskBuilder async(Task task) {
|
|
||||||
tasks.add(RunnableTask.adapt(task, TaskType.ASYNC));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TaskBuilder async(ReceiveTask<Object> task) {
|
|
||||||
tasks.add(RunnableTask.adapt(task, TaskType.ASYNC));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TaskBuilder async(ReturnTask task) {
|
|
||||||
tasks.add(RunnableTask.adapt(task, TaskType.ASYNC));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TaskBuilder async(Runnable task) {
|
|
||||||
tasks.add(RunnableTask.adapt(task, TaskType.ASYNC));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TaskBuilder sync(Task task) {
|
|
||||||
tasks.add(RunnableTask.adapt(task, TaskType.SYNC));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TaskBuilder sync(ReceiveTask<Object> task) {
|
|
||||||
tasks.add(RunnableTask.adapt(task, TaskType.SYNC));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TaskBuilder sync(ReturnTask task) {
|
|
||||||
tasks.add(RunnableTask.adapt(task, TaskType.SYNC));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TaskBuilder sync(Runnable task) {
|
|
||||||
tasks.add(RunnableTask.adapt(task, TaskType.SYNC));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TaskBuilder delay(int ticks) {
|
|
||||||
tasks.add(RunnableDelayedTask.adapt(ticks));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TaskBuilder delay(DelayedTask task) {
|
|
||||||
tasks.add(RunnableDelayedTask.adapt(task));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Run some sync tasks in parallel<br>
|
|
||||||
* - All sync parallel tasks, which occur directly after each other will be run at the same time
|
|
||||||
*
|
|
||||||
* @param run
|
|
||||||
* @return this
|
|
||||||
*/
|
|
||||||
public TaskBuilder syncParallel(Runnable run) {
|
|
||||||
tasks.add(RunnableTask.adapt(run, TaskType.SYNC_PARALLEL));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TaskBuilder syncParallel(Task run) {
|
|
||||||
tasks.add(RunnableTask.adapt(run, TaskType.SYNC_PARALLEL));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TaskBuilder syncParallel(ReceiveTask<Object> run) {
|
|
||||||
tasks.add(RunnableTask.adapt(run, TaskType.SYNC_PARALLEL));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TaskBuilder syncParallel(ReturnTask run) {
|
|
||||||
tasks.add(RunnableTask.adapt(run, TaskType.SYNC_PARALLEL));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Run some async tasks in parallel<br>
|
|
||||||
* - All async parallel tasks which occur directly after each other will be run at the same time
|
|
||||||
*
|
|
||||||
* @param run
|
|
||||||
* @return this
|
|
||||||
*/
|
|
||||||
public TaskBuilder asyncParallel(Runnable run) {
|
|
||||||
tasks.add(RunnableTask.adapt(run, TaskType.ASYNC_PARALLEL));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TaskBuilder asyncParallel(Task run) {
|
|
||||||
tasks.add(RunnableTask.adapt(run, TaskType.ASYNC_PARALLEL));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TaskBuilder asyncParallel(ReceiveTask<Object> run) {
|
|
||||||
tasks.add(RunnableTask.adapt(run, TaskType.ASYNC_PARALLEL));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TaskBuilder asyncParallel(ReturnTask run) {
|
|
||||||
tasks.add(RunnableTask.adapt(run, TaskType.ASYNC_PARALLEL));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Run a split task when the server has free time<br>
|
|
||||||
* - i.e. To maintain high tps
|
|
||||||
* - Use the split() method within task execution
|
|
||||||
* - FAWE will be able to pause execution at these points
|
|
||||||
*
|
|
||||||
* @param run
|
|
||||||
* @return this
|
|
||||||
*/
|
|
||||||
public TaskBuilder syncWhenFree(SplitTask run) {
|
|
||||||
tasks.add(run);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TaskBuilder syncWhenFree(Task run) {
|
|
||||||
tasks.add(RunnableTask.adapt(run, TaskType.SYNC_WHEN_FREE));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TaskBuilder syncWhenFree(ReceiveTask<Object> run) {
|
|
||||||
tasks.add(RunnableTask.adapt(run, TaskType.SYNC_WHEN_FREE));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TaskBuilder syncWhenFree(ReturnTask run) {
|
|
||||||
tasks.add(RunnableTask.adapt(run, TaskType.SYNC_WHEN_FREE));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TaskBuilder abortIfTrue(Task<Boolean, Object> run) {
|
|
||||||
tasks.add(RunnableTask.adapt(run, TaskType.ABORT));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TaskBuilder abortIfTrue(final Runnable run) {
|
|
||||||
tasks.add(RunnableTask.adapt((Task<Boolean, Boolean>) previous -> {
|
|
||||||
if (previous == Boolean.TRUE) run.run();
|
|
||||||
return previous == Boolean.TRUE;
|
|
||||||
}, TaskType.ABORT));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TaskBuilder abortIfNull(final Runnable run) {
|
|
||||||
tasks.add(RunnableTask.adapt((Task<Boolean, Object>) previous -> {
|
|
||||||
if (previous == null) run.run();
|
|
||||||
return previous == null;
|
|
||||||
}, TaskType.ABORT));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TaskBuilder abortIfEqual(final Runnable run, final Object other) {
|
|
||||||
tasks.add(RunnableTask.adapt((Task<Boolean, Object>) previous -> {
|
|
||||||
if (Objects.equals(previous, other)) run.run();
|
|
||||||
return Objects.equals(previous, other);
|
|
||||||
}, TaskType.ABORT));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TaskBuilder abortIfNotEqual(final Runnable run, final Object other) {
|
|
||||||
tasks.add(RunnableTask.adapt((Task<Boolean, Object>) previous -> {
|
|
||||||
if (!Objects.equals(previous, other)) run.run();
|
|
||||||
return !Objects.equals(previous, other);
|
|
||||||
}, TaskType.ABORT));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Have all async tasks run on a new thread<br>
|
|
||||||
* - As opposed to trying to use the current thread
|
|
||||||
*/
|
|
||||||
public void buildAsync() {
|
|
||||||
TaskManager.IMP.async(this::build);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Begins execution of the tasks<br>
|
|
||||||
* - The builder will attempt to run on the current thread if possible
|
|
||||||
*/
|
|
||||||
public void build() {
|
|
||||||
RunnableTask peek;
|
|
||||||
while ((peek = tasks.peek()) != null) {
|
|
||||||
try {
|
|
||||||
switch (peek.type) {
|
|
||||||
case DELAY:
|
|
||||||
DelayedTask task = (DelayedTask) tasks.poll();
|
|
||||||
RunnableTask next = tasks.peek();
|
|
||||||
if (next != null) {
|
|
||||||
switch (next.type) {
|
|
||||||
case SYNC:
|
|
||||||
case ABORT:
|
|
||||||
case SYNC_PARALLEL:
|
|
||||||
TaskManager.IMP.later(this::build, task.getDelay(result));
|
|
||||||
return;
|
|
||||||
default:
|
|
||||||
TaskManager.IMP.laterAsync(this::build, task.getDelay(result));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
case SYNC:
|
|
||||||
case SYNC_PARALLEL:
|
|
||||||
if (!Fawe.isMainThread()) {
|
|
||||||
TaskManager.IMP.sync(new RunnableVal() {
|
|
||||||
@Override
|
|
||||||
public void run(Object value) {
|
|
||||||
build();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SYNC_WHEN_FREE:
|
|
||||||
case ASYNC:
|
|
||||||
case ASYNC_PARALLEL:
|
|
||||||
if (Fawe.isMainThread()) {
|
|
||||||
TaskManager.IMP.async(this::build);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
RunnableTask task = tasks.poll();
|
|
||||||
task.value = result;
|
|
||||||
switch (task.type) {
|
|
||||||
case ABORT:
|
|
||||||
if (((Task<Boolean, Object>) task).run(result)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SYNC:
|
|
||||||
result = task.exec(result);
|
|
||||||
break;
|
|
||||||
case SYNC_WHEN_FREE:
|
|
||||||
if (task instanceof SplitTask) {
|
|
||||||
SplitTask splitTask = (SplitTask) task;
|
|
||||||
result = splitTask.execSplit(result);
|
|
||||||
} else {
|
|
||||||
result = TaskManager.IMP.syncWhenFree(task);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ASYNC:
|
|
||||||
result = task.exec(result);
|
|
||||||
continue;
|
|
||||||
case SYNC_PARALLEL:
|
|
||||||
case ASYNC_PARALLEL:
|
|
||||||
final ArrayList<RunnableTask> parallel = new ArrayList<>();
|
|
||||||
parallel.add(task);
|
|
||||||
RunnableTask next = tasks.peek();
|
|
||||||
while (next != null && next.type == task.type) {
|
|
||||||
parallel.add(next);
|
|
||||||
tasks.poll();
|
|
||||||
next = tasks.peek();
|
|
||||||
}
|
|
||||||
for (RunnableTask current : parallel) {
|
|
||||||
pool.submit(current);
|
|
||||||
}
|
|
||||||
pool.awaitQuiescence(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
|
|
||||||
result = null;
|
|
||||||
for (RunnableTask current : parallel) {
|
|
||||||
if (current.value != null) {
|
|
||||||
result = current.value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (task.isAborted()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} catch (TaskAbortException abort) {
|
|
||||||
return;
|
|
||||||
} catch (Throwable e1) {
|
|
||||||
if (handler != null) {
|
|
||||||
try {
|
|
||||||
handler.uncaughtException(Thread.currentThread(), e1);
|
|
||||||
} catch (Throwable e2) {
|
|
||||||
e1.printStackTrace();
|
|
||||||
e2.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final class TaskAbortException extends RuntimeException {
|
|
||||||
@Override
|
|
||||||
public Throwable fillInStackTrace() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private IQueueExtent queue;
|
|
||||||
private long last;
|
|
||||||
private long start;
|
|
||||||
private Object asyncWaitLock = new Object();
|
|
||||||
private Object syncWaitLock = new Object();
|
|
||||||
private boolean finished;
|
|
||||||
|
|
||||||
private static abstract class RunnableTask<T> extends RunnableVal<T> {
|
|
||||||
public final TaskType type;
|
|
||||||
private boolean aborted;
|
|
||||||
|
|
||||||
public RunnableTask(TaskType type) {
|
|
||||||
this.type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void abortNextTasks() {
|
|
||||||
this.aborted = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isAborted() {
|
|
||||||
return aborted;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static RunnableTask adapt(final Task task, TaskType type) {
|
|
||||||
return new RunnableTask(type) {
|
|
||||||
@Override
|
|
||||||
public Object exec(Object previous) {
|
|
||||||
return task.run(previous);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static RunnableTask adapt(final ReturnTask task, TaskType type) {
|
|
||||||
return new RunnableTask(type) {
|
|
||||||
@Override
|
|
||||||
public Object exec(Object previous) {
|
|
||||||
return task.run();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static RunnableTask adapt(final ReceiveTask<Object> task, TaskType type) {
|
|
||||||
return new RunnableTask(type) {
|
|
||||||
@Override
|
|
||||||
public Object exec(Object previous) {
|
|
||||||
task.run(previous);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static RunnableTask adapt(final Runnable run, TaskType type) {
|
|
||||||
return new RunnableTask(type) {
|
|
||||||
@Override
|
|
||||||
public Object exec(Object previous) {
|
|
||||||
if (run instanceof RunnableVal) {
|
|
||||||
((RunnableVal) run).value = this.value;
|
|
||||||
return this.value = ((RunnableVal) run).runAndGet();
|
|
||||||
}
|
|
||||||
run.run();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract T exec(Object previous);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final void run(T value) {
|
|
||||||
this.value = exec(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static abstract class RunnableDelayedTask extends RunnableTask {
|
|
||||||
|
|
||||||
public RunnableDelayedTask(TaskType type) {
|
|
||||||
super(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object exec(Object previous) {
|
|
||||||
return previous;
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract int delay(Object previous);
|
|
||||||
|
|
||||||
public static RunnableDelayedTask adapt(final DelayedTask task) {
|
|
||||||
return new RunnableDelayedTask(TaskType.DELAY) {
|
|
||||||
@Override
|
|
||||||
public int delay(Object previous) {
|
|
||||||
return task.getDelay(previous);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static RunnableDelayedTask adapt(final int time) {
|
|
||||||
return new RunnableDelayedTask(TaskType.DELAY) {
|
|
||||||
@Override
|
|
||||||
public int delay(Object previous) {
|
|
||||||
return time;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static abstract class SplitTask<T> extends RunnableTask<T> {
|
|
||||||
|
|
||||||
private final long allocation;
|
|
||||||
private final QueueHandler queue;
|
|
||||||
private long last;
|
|
||||||
private long start;
|
|
||||||
private Object asyncWaitLock = new Object();
|
|
||||||
private Object syncWaitLock = new Object();
|
|
||||||
|
|
||||||
private boolean finished;
|
|
||||||
private boolean waitingAsync = true;
|
|
||||||
private boolean waitingSync = false;
|
|
||||||
|
|
||||||
public SplitTask() {
|
|
||||||
this(20);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SplitTask(long allocation) {
|
|
||||||
super(TaskType.SYNC_WHEN_FREE);
|
|
||||||
this.allocation = allocation;
|
|
||||||
this.queue = Fawe.get().getQueueHandler();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object execSplit(final T previous) {
|
|
||||||
this.value = previous;
|
|
||||||
final Thread thread = new Thread(() -> {
|
|
||||||
try {
|
|
||||||
synchronized (asyncWaitLock) {
|
|
||||||
asyncWaitLock.notifyAll();
|
|
||||||
asyncWaitLock.wait(Long.MAX_VALUE);
|
|
||||||
}
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
exec(previous);
|
|
||||||
finished = true;
|
|
||||||
waitingAsync = true;
|
|
||||||
waitingSync = false;
|
|
||||||
synchronized (syncWaitLock) {
|
|
||||||
syncWaitLock.notifyAll();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
try {
|
|
||||||
synchronized (asyncWaitLock) {
|
|
||||||
thread.start();
|
|
||||||
asyncWaitLock.wait();
|
|
||||||
}
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
while (thread.isAlive()) {
|
|
||||||
TaskManager.IMP.syncWhenFree(new RunnableVal<T>() {
|
|
||||||
@Override
|
|
||||||
public void run(Object ignore) {
|
|
||||||
queue.startSet(true);
|
|
||||||
start = System.currentTimeMillis();
|
|
||||||
try {
|
|
||||||
if (!finished) {
|
|
||||||
synchronized (asyncWaitLock) {
|
|
||||||
while (!waitingAsync) asyncWaitLock.wait(1);
|
|
||||||
asyncWaitLock.notifyAll();
|
|
||||||
}
|
|
||||||
waitingSync = true;
|
|
||||||
synchronized (syncWaitLock) {
|
|
||||||
syncWaitLock.notifyAll();
|
|
||||||
syncWaitLock.wait();
|
|
||||||
}
|
|
||||||
waitingSync = false;
|
|
||||||
}
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
queue.endSet(true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return this.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void split() {
|
|
||||||
long now = System.currentTimeMillis();
|
|
||||||
if (now - start > allocation) {
|
|
||||||
try {
|
|
||||||
synchronized (syncWaitLock) {
|
|
||||||
while (!waitingSync) syncWaitLock.wait(1);
|
|
||||||
syncWaitLock.notifyAll();
|
|
||||||
}
|
|
||||||
waitingAsync = true;
|
|
||||||
synchronized (asyncWaitLock) {
|
|
||||||
asyncWaitLock.notifyAll();
|
|
||||||
asyncWaitLock.wait();
|
|
||||||
}
|
|
||||||
waitingAsync = false;
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private enum TaskType {
|
|
||||||
SYNC,
|
|
||||||
ASYNC,
|
|
||||||
SYNC_PARALLEL,
|
|
||||||
ASYNC_PARALLEL,
|
|
||||||
SYNC_WHEN_FREE,
|
|
||||||
DELAY,
|
|
||||||
ABORT
|
|
||||||
}
|
|
||||||
}
|
|
@ -42,6 +42,8 @@ import com.boydti.fawe.util.MathMan;
|
|||||||
import com.boydti.fawe.util.TaskManager;
|
import com.boydti.fawe.util.TaskManager;
|
||||||
import com.sk89q.worldedit.entity.Player;
|
import com.sk89q.worldedit.entity.Player;
|
||||||
import com.sk89q.worldedit.event.extent.EditSessionEvent;
|
import com.sk89q.worldedit.event.extent.EditSessionEvent;
|
||||||
|
import com.sk89q.worldedit.extension.platform.Capability;
|
||||||
|
import com.sk89q.worldedit.extension.platform.Watchdog;
|
||||||
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
||||||
import com.sk89q.worldedit.extent.ChangeSetExtent;
|
import com.sk89q.worldedit.extent.ChangeSetExtent;
|
||||||
import com.sk89q.worldedit.extent.Extent;
|
import com.sk89q.worldedit.extent.Extent;
|
||||||
@ -195,8 +197,6 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
|
|||||||
|
|
||||||
@SuppressWarnings("ProtectedField")
|
@SuppressWarnings("ProtectedField")
|
||||||
protected final World world;
|
protected final World world;
|
||||||
private final String worldName;
|
|
||||||
private boolean wrapped;
|
|
||||||
private final FaweLimit originalLimit;
|
private final FaweLimit originalLimit;
|
||||||
private final FaweLimit limit;
|
private final FaweLimit limit;
|
||||||
private final Player player;
|
private final Player player;
|
||||||
@ -212,6 +212,8 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
|
|||||||
private Extent bypassAll;
|
private Extent bypassAll;
|
||||||
|
|
||||||
private final int maxY;
|
private final int maxY;
|
||||||
|
private final List<WatchdogTickingExtent> watchdogExtents = new ArrayList<>(2);
|
||||||
|
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public EditSession(EventBus bus, World world, @Nullable Player player,
|
public EditSession(EventBus bus, World world, @Nullable Player player,
|
||||||
@ -247,8 +249,6 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
|
|||||||
public EditSession(EditSessionBuilder builder) {
|
public EditSession(EditSessionBuilder builder) {
|
||||||
super(builder.compile().getExtent());
|
super(builder.compile().getExtent());
|
||||||
this.world = builder.getWorld();
|
this.world = builder.getWorld();
|
||||||
this.worldName = world.getName();
|
|
||||||
this.wrapped = builder.isWrapped();
|
|
||||||
this.bypassHistory = builder.getBypassHistory();
|
this.bypassHistory = builder.getBypassHistory();
|
||||||
this.bypassAll = builder.getBypassAll();
|
this.bypassAll = builder.getBypassAll();
|
||||||
this.originalLimit = builder.getLimit();
|
this.originalLimit = builder.getLimit();
|
||||||
@ -317,11 +317,9 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
|
|||||||
public Extent getBypassAll() {
|
public Extent getBypassAll() {
|
||||||
return bypassAll;
|
return bypassAll;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Extent getBypassHistory() {
|
public Extent getBypassHistory() {
|
||||||
return bypassHistory;
|
return bypassHistory;
|
||||||
}
|
}
|
||||||
private final List<WatchdogTickingExtent> watchdogExtents = new ArrayList<>(2);
|
|
||||||
|
|
||||||
public void setExtent(AbstractDelegateExtent extent) {
|
public void setExtent(AbstractDelegateExtent extent) {
|
||||||
new ExtentTraverser(this).setNext(extent);
|
new ExtentTraverser(this).setNext(extent);
|
||||||
@ -483,7 +481,6 @@ public class EditSession extends PassthroughExtent implements AutoCloseable {
|
|||||||
|
|
||||||
public void addTransform(ResettableExtent transform) {
|
public void addTransform(ResettableExtent transform) {
|
||||||
checkNotNull(transform);
|
checkNotNull(transform);
|
||||||
wrapped = true;
|
|
||||||
transform.setExtent(getExtent());
|
transform.setExtent(getExtent());
|
||||||
new ExtentTraverser(this).setNext(transform);
|
new ExtentTraverser(this).setNext(transform);
|
||||||
}
|
}
|
||||||
|
@ -450,69 +450,6 @@ public class SchematicCommands {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
@Command(
|
|
||||||
name = "show",
|
|
||||||
desc = "Show a schematic",
|
|
||||||
descFooter = "List all schematics in the schematics directory\n" +
|
|
||||||
" -f <format> restricts by format\n"
|
|
||||||
)
|
|
||||||
@CommandPermissions("worldedit.schematic.show")
|
|
||||||
public void show(Player player, InjectedValueAccess args, @Switch(name='f', desc = "") String formatName) {
|
|
||||||
FawePlayer fp = FawePlayer.wrap(player);
|
|
||||||
if (args.argsLength() == 0) {
|
|
||||||
if (fp.getSession().getVirtualWorld() != null) fp.setVirtualWorld(null);
|
|
||||||
else {
|
|
||||||
player.print(TranslatableComponent.of("fawe.error.command.syntax" , "/" + Commands.getAlias(SchematicCommands.class, "schematic") + " " + getCommand().aliases()[0] + " " + getCommand().usage()));
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
LocalConfiguration config = worldEdit.getConfiguration();
|
|
||||||
File dir = worldEdit.getWorkingDirectoryFile(config.saveDir);
|
|
||||||
try {
|
|
||||||
SchemVis visExtent = new SchemVis(fp);
|
|
||||||
LongAdder count = new LongAdder();
|
|
||||||
UtilityCommands.getFiles(dir, player, args, 0, Character.MAX_VALUE, formatName, Settings.IMP.PATHS.PER_PLAYER_SCHEMATICS, file -> {
|
|
||||||
if (file.isFile()) {
|
|
||||||
try {
|
|
||||||
visExtent.add(file);
|
|
||||||
count.add(1);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
long total = count.longValue();
|
|
||||||
if (total == 0) {
|
|
||||||
if (args.getJoinedStrings(0).toLowerCase().startsWith("all")) {
|
|
||||||
player.print(TranslatableComponent.of("fawe.worldedit.schematic.schematic.none"))
|
|
||||||
} else {
|
|
||||||
String joined = args.getJoinedStrings(0);
|
|
||||||
String cmd = "/" + Commands.getAlias(SchematicCommands.class, "schematic") + " " + getCommand().aliases()[0] + " all " + joined;
|
|
||||||
player.print(TranslatableComponent.of("fawe.worldedit.help.help.suggest" , joined, cmd));
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
visExtent.bind();
|
|
||||||
visExtent.update();
|
|
||||||
|
|
||||||
String cmdPrefix = "/" + (config.noDoubleSlash ? "" : "/");
|
|
||||||
String cmdShow = Commands.getAlias(ClipboardCommands.class, "schematic") + " " + Commands.getAlias(ClipboardCommands.class, "show");
|
|
||||||
fp.print(TranslatableComponent.of("fawe.worldedit.schematic.schematic.show" , count.longValue(), args.getJoinedStrings(0), cmdShow));
|
|
||||||
|
|
||||||
if (fp.getSession().getExistingClipboard() != null) {
|
|
||||||
String cmd = cmdPrefix + Commands.getAlias(ClipboardCommands.class, "clearclipboard");
|
|
||||||
fp.print(TranslatableComponent.of("fawe.worldedit.schematic.schematic.prompt.clear" , cmd));
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (Throwable e) {
|
|
||||||
fp.setVirtualWorld(null);
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
name = "list",
|
name = "list",
|
||||||
aliases = {"all", "ls"},
|
aliases = {"all", "ls"},
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren