Add better control over expression timeouts. (#451)

Add better control over expression timeouts.
* //timeout command can be used to change player's current timeout.
* Config now also has a max timeout, can be bypassed with permission
* Timeout of < 0 will let expressions run indefinitely.
* Said expressions won't run on a separate thread, slightly reducing the
  overhead from context switching. For large //gen commands, for example,
  this can actually increase speed.
This commit is contained in:
wizjany
2019-03-06 19:58:32 -05:00
committed by GitHub
parent f84f3c6f85
commit de08c8b8c7
21 changed files with 301 additions and 76 deletions

View File

@ -23,6 +23,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
import static com.sk89q.worldedit.util.GuavaUtil.firstNonNull;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.extent.NullExtent;
@ -147,7 +149,9 @@ public class Deform implements Contextual<Operation> {
unit = Vector3.ONE;
}
return new DeformOperation(context.getDestination(), region, zero, unit, expression);
LocalSession session = context.getSession();
return new DeformOperation(context.getDestination(), region, zero, unit, expression,
session == null ? WorldEdit.getInstance().getConfiguration().calculationTimeout : session.getTimeout());
}
private static final class DeformOperation implements Operation {
@ -156,20 +160,22 @@ public class Deform implements Contextual<Operation> {
private final Vector3 zero;
private final Vector3 unit;
private final String expression;
private final int timeout;
private DeformOperation(Extent destination, Region region, Vector3 zero, Vector3 unit, String expression) {
private DeformOperation(Extent destination, Region region, Vector3 zero, Vector3 unit, String expression, int timeout) {
this.destination = destination;
this.region = region;
this.zero = zero;
this.unit = unit;
this.expression = expression;
this.timeout = timeout;
}
@Override
public Operation resume(RunContext run) throws WorldEditException {
try {
// TODO: Move deformation code
((EditSession) destination).deformRegion(region, zero, unit, expression);
((EditSession) destination).deformRegion(region, zero, unit, expression, timeout);
return null;
} catch (ExpressionException e) {
throw new RuntimeException("Failed to execute expression", e); // TODO: Better exception to throw here?