Skip to content

Commit

Permalink
Try another method of queueing it up, and write a test implementation…
Browse files Browse the repository at this point in the history
… for Drain.
  • Loading branch information
me4502 committed Aug 29, 2018
1 parent ed313f2 commit 0aa386e
Show file tree
Hide file tree
Showing 14 changed files with 259 additions and 94 deletions.
Expand Up @@ -49,11 +49,13 @@ public class BukkitServerInterface implements MultiUserPlatform {
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() {
Expand Down Expand Up @@ -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
Expand Down
Expand Up @@ -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() {
Expand Down
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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");

Expand All @@ -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;
}

/**
Expand Down
46 changes: 0 additions & 46 deletions worldedit-core/src/main/java/com/sk89q/worldedit/LocalSession.java
Expand Up @@ -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;
Expand Down Expand Up @@ -94,8 +92,6 @@ public class LocalSession {
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;
Expand Down Expand Up @@ -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();
}
}
29 changes: 28 additions & 1 deletion worldedit-core/src/main/java/com/sk89q/worldedit/WorldEdit.java
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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;

Expand Down Expand Up @@ -100,6 +103,8 @@ public class WorldEdit {
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();
Expand Down Expand Up @@ -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.
*/
Expand Down
Expand Up @@ -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(
Expand Down
@@ -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) {

}
}

0 comments on commit 0aa386e

Please sign in to comment.