Permalink
Browse files

Try another method of queueing it up, and write a test implementation…

… for Drain.
  • Loading branch information...
me4502 committed Aug 23, 2018
1 parent ed313f2 commit 0aa386ec0fad7775a053d6d3628a7099c9c0d5ca
@@ -49,11 +49,13 @@
public WorldEditPlugin plugin;
private CommandRegistration dynamicCommands;
private boolean hookingEvents;
private Actor consoleSender;
public BukkitServerInterface(WorldEditPlugin plugin, Server server) {
this.plugin = plugin;
this.server = server;
dynamicCommands = new CommandRegistration(plugin);
this.consoleSender = plugin.wrapCommandSender(server.getConsoleSender());
}
boolean isHookingEvents() {
@@ -117,7 +119,7 @@ public BukkitWorld matchWorld(com.sk89q.worldedit.world.World world) {
@Override
public Actor getConsoleCommandSender() {
return plugin.wrapCommandSender(Bukkit.getConsoleSender());
return consoleSender;
}
@Override
@@ -104,7 +104,7 @@ public void onEnable() {
// platforms to be worried about... at the current time of writing
WorldEdit.getInstance().getEventBus().post(new PlatformReadyEvent());
Bukkit.getScheduler().runTaskTimer(this, () -> WorldEdit.getInstance().getSessionManager().tickQueues(), 1, 1);
Bukkit.getScheduler().runTaskTimer(this, () -> WorldEdit.getInstance().tickOperationQueues(), 1, 1);
}
private void loadConfig() {
@@ -28,6 +28,7 @@
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.event.extent.EditSessionEvent;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extent.ChangeSetExtent;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.extent.MaskingExtent;
@@ -60,6 +61,7 @@
import com.sk89q.worldedit.function.mask.Masks;
import com.sk89q.worldedit.function.mask.NoiseFilter2D;
import com.sk89q.worldedit.function.mask.RegionMask;
import com.sk89q.worldedit.function.operation.AffectedFutureOperation;
import com.sk89q.worldedit.function.operation.ChangeSetExecutor;
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
import com.sk89q.worldedit.function.operation.Operation;
@@ -116,6 +118,7 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -1097,12 +1100,12 @@ public int moveCuboidRegion(Region region, Vector dir, int distance, boolean cop
/**
* Drain nearby pools of water or lava.
*
* @param actor The actor to run this action with, if applicable
* @param origin the origin to drain from, which will search a 3x3 area
* @param radius the radius of the removal, where a value should be 0 or greater
* @return number of blocks affected
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
public int drainArea(Vector origin, double radius) throws MaxChangedBlocksException {
public CompletableFuture<Integer> drainArea(@Nullable Actor actor, Vector origin, double radius) {
checkNotNull(origin);
checkArgument(radius >= 0, "radius >= 0 required");
@@ -1121,9 +1124,11 @@ public int drainArea(Vector origin, double radius) throws MaxChangedBlocksExcept
}
}
Operations.completeLegacy(visitor);
CompletableFuture<Integer> future = new CompletableFuture<>();
return visitor.getAffected();
Operations.completeQueued(new AffectedFutureOperation(visitor, future), actor, this);
return future;
}
/**
@@ -36,8 +36,6 @@
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extent.inventory.BlockBag;
import com.sk89q.worldedit.function.mask.Mask;
import com.sk89q.worldedit.function.operation.Operation;
import com.sk89q.worldedit.function.operation.RunContext;
import com.sk89q.worldedit.internal.cui.CUIEvent;
import com.sk89q.worldedit.internal.cui.CUIRegion;
import com.sk89q.worldedit.internal.cui.SelectionShapeEvent;
@@ -94,8 +92,6 @@
private transient Mask mask;
private transient TimeZone timezone = TimeZone.getDefault();
private transient Vector cuiTemporaryBlock;
private transient LinkedList<Operation> operationQueue = new LinkedList<>();
private transient boolean operationQueuePaused = false;
// Saved properties
private String lastScript;
@@ -897,46 +893,4 @@ public Mask getMask() {
public void setMask(Mask mask) {
this.mask = mask;
}
/**
* Add a {@link Operation} to the queue.
*
* @param actor The actor, if present
* @param operation The operation
*/
public void enqeueOperation(@Nullable Actor actor, Operation operation) {
checkNotNull(operation);
operationQueue.addLast(operation);
if (actor != null) {
actor.print("Queued Operation");
}
}
/**
* Run the next item in the operation queue.
*
* @param actor The actor for feedback, if present
*/
public void runQueue(@Nullable Actor actor) {
if (isRunningOperations()) {
Operation op = operationQueue.poll();
try {
op = op.resume(new RunContext());
if (op != null) {
operationQueue.addFirst(op);
}
} catch (WorldEditException e) {
throw new RuntimeException(e);
}
}
}
/**
* Checks if the operation queue is running
*
* @return If the session is performing a queue
*/
public boolean isRunningOperations() {
return !operationQueuePaused && !operationQueue.isEmpty();
}
}
@@ -24,7 +24,6 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.blocks.BaseItem;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.event.platform.BlockInteractEvent;
@@ -39,6 +38,8 @@
import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.extension.platform.PlatformManager;
import com.sk89q.worldedit.extent.inventory.BlockBag;
import com.sk89q.worldedit.function.operation.OperationQueue;
import com.sk89q.worldedit.function.operation.RunContext;
import com.sk89q.worldedit.scripting.CraftScriptContext;
import com.sk89q.worldedit.scripting.CraftScriptEngine;
import com.sk89q.worldedit.scripting.RhinoCraftScriptEngine;
@@ -51,6 +52,7 @@
import com.sk89q.worldedit.util.io.file.FilenameResolutionException;
import com.sk89q.worldedit.util.io.file.InvalidFilenameException;
import com.sk89q.worldedit.util.logging.WorldEditPrefixHandler;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.registry.BundledBlockData;
import com.sk89q.worldedit.world.registry.BundledItemData;
@@ -65,6 +67,7 @@
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -100,6 +103,8 @@
private final MaskFactory maskFactory = new MaskFactory(this);
private final PatternFactory patternFactory = new PatternFactory(this);
private final Map<Actor, OperationQueue> operationQueues = new WeakHashMap<>();
static {
WorldEditPrefixHandler.register("com.sk89q.worldedit");
getVersion();
@@ -309,6 +314,28 @@ private boolean checkFilename(String filename) {
return filename.matches("^[A-Za-z0-9_\\- \\./\\\\'\\$@~!%\\^\\*\\(\\)\\[\\]\\+\\{\\},\\?]+\\.[A-Za-z0-9]+$");
}
/**
* Gets an {@link OperationQueue} for the given actor.
*
* @param actor The actor
*/
public OperationQueue getOperationQueue(Actor actor) {
return operationQueues.computeIfAbsent(actor, x -> new OperationQueue());
}
/**
* Tick all of the operation queues
*/
public void tickOperationQueues() {
for (Map.Entry<Actor, OperationQueue> queueEntry : operationQueues.entrySet()) {
try {
queueEntry.getValue().resume(new RunContext());
} catch (WorldEditException e) {
throw new RuntimeException(e);
}
}
}
/**
* Load the bundled mappings.
*/
@@ -152,9 +152,9 @@ public void drain(Player player, LocalSession session, EditSession editSession,
double radius = Math.max(0, args.getDouble(0));
we.checkMaxRadius(radius);
int affected = editSession.drainArea(
session.getPlacementPosition(player), radius);
player.print(affected + " block(s) have been changed.");
editSession.drainArea(player, session.getPlacementPosition(player), radius).thenAccept(
affected -> player.print(affected + " block(s) have been changed.")
);
}
@Command(
@@ -0,0 +1,65 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.operation;
import com.sk89q.worldedit.WorldEditException;
import java.util.List;
import java.util.concurrent.CompletableFuture;
public class AffectedFutureOperation implements Operation {
private Operation operation;
private CompletableFuture<Integer> future;
private int affected = 0;
public AffectedFutureOperation(Operation operation, CompletableFuture<Integer> future) {
this.operation = operation;
this.future = future;
}
@Override
public Operation resume(RunContext run) throws WorldEditException {
if (operation != null) {
Operation nextOp = operation.resume(run);
if (operation instanceof AffectingOperation) {
affected += ((AffectingOperation) operation).getAffected();
}
operation = nextOp;
}
if (operation != null) {
return this;
}
future.complete(affected);
return null;
}
@Override
public void cancel() {
}
@Override
public void addStatusMessages(List<String> messages) {
messages.add("Affected " + affected);
operation.addStatusMessages(messages);
}
}
@@ -0,0 +1,30 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.operation;
public interface AffectingOperation extends Operation {
/**
* Get the number of affected objects.
*
* @return the number of affected
*/
int getAffected();
}
@@ -0,0 +1,60 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.function.operation;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extension.platform.Actor;
import java.util.List;
public class FlushOperation implements Operation {
private Actor actor;
private EditSession editSession;
public FlushOperation(Actor actor, EditSession editSession) {
this.actor = actor;
this.editSession = editSession;
}
@Override
public Operation resume(RunContext run) throws WorldEditException {
LocalSession session = WorldEdit.getInstance().getSessionManager().get(actor);
session.remember(editSession);
editSession.flushQueue();
WorldEdit.getInstance().flushBlockBag(actor, editSession);
return null;
}
@Override
public void cancel() {
}
@Override
public void addStatusMessages(List<String> messages) {
}
}
Oops, something went wrong.

0 comments on commit 0aa386e

Please sign in to comment.