Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error Catcher rewrite #764

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 16 additions & 38 deletions src/main/java/vazkii/psi/api/spell/CompiledSpell.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

import vazkii.psi.api.PsiAPI;
import vazkii.psi.api.internal.IPlayerData;
import vazkii.psi.api.spell.param.ParamError;
import vazkii.psi.common.network.MessageRegister;
import vazkii.psi.common.network.message.MessageSpellError;

Expand All @@ -31,10 +32,8 @@ public class CompiledSpell {
public final SpellMetadata metadata = new SpellMetadata();

public final Stack<Action> actions = new Stack<>();
public final Map<SpellPiece, CatchHandler> errorHandlers = new HashMap<>();
public final Map<SpellPiece, Action> actionMap = new HashMap<>();

public Action currentAction;
public final boolean[][] spotsEvaluated;

public CompiledSpell(Spell source) {
Expand All @@ -52,14 +51,11 @@ public boolean execute(SpellContext context) throws SpellRuntimeException {
IPlayerData data = PsiAPI.internalHandler.getDataForPlayer(context.caster);
while (!context.actions.isEmpty()) {
Action a = context.actions.pop();
currentAction = a;

PsiAPI.internalHandler.setCrashData(this, a.piece);
a.execute(data, context);
PsiAPI.internalHandler.setCrashData(null, null);

currentAction = null;

if (context.stopped) {
return false;
}
Expand Down Expand Up @@ -93,9 +89,7 @@ public void safeExecute(SpellContext context) {
if (!context.shouldSuppressErrors()) {
context.caster.sendMessage(new TranslationTextComponent(e.getMessage()).setStyle(Style.EMPTY.setFormatting(TextFormatting.RED)), Util.DUMMY_UUID);

int x = context.cspell.currentAction.piece.x + 1;
int y = context.cspell.currentAction.piece.y + 1;
MessageSpellError message = new MessageSpellError("psi.spellerror.position", x, y);
MessageSpellError message = new MessageSpellError("psi.spellerror.position", e.x + 1, e.y + 1);
MessageRegister.sendToPlayer(message, context.caster);
}
}
Expand All @@ -118,6 +112,14 @@ public Action(SpellPiece piece) {
}

public void execute(IPlayerData data, SpellContext context) throws SpellRuntimeException {
for (SpellParam<?> param : piece.paramSides.keySet()) {
if (!(param instanceof ParamError)) {
Object v = piece.getRawParamValue(context, param);
if (v instanceof SpellRuntimeException) {
throw (SpellRuntimeException) v;
}
}
}
try {
data.markPieceExecuted(piece);
Object o = piece.execute(context);
Expand All @@ -127,40 +129,16 @@ public void execute(IPlayerData data, SpellContext context) throws SpellRuntimeE
context.evaluatedObjects[piece.x][piece.y] = o;
}
} catch (SpellRuntimeException exception) {
if (errorHandlers.containsKey(piece)) {
if (!errorHandlers.get(piece).suppress(piece, context, exception)) {
throw exception;
}
return;
exception.x = piece.x;
exception.y = piece.y;
if (metadata.errorSuppressed[piece.x][piece.y]) {
context.evaluatedObjects[piece.x][piece.y] = exception;
} else {
throw exception;
}
throw exception;
}
}

}

public class CatchHandler {

public final SpellPiece handlerPiece;
public final IErrorCatcher handler;

public CatchHandler(SpellPiece handlerPiece) {
this.handlerPiece = handlerPiece;
this.handler = (IErrorCatcher) handlerPiece;
}

public boolean suppress(SpellPiece piece, SpellContext context, SpellRuntimeException exception) {
boolean handled = handler.catchException(piece, context, exception);
if (handled) {
Class<?> eval = piece.getEvaluationType();
if (eval != null && eval != Void.class) {
context.evaluatedObjects[piece.x][piece.y] =
handler.supplyReplacementValue(piece, context, exception);
}
}

return handled;
}
}

}
3 changes: 1 addition & 2 deletions src/main/java/vazkii/psi/api/spell/EnumPieceType.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ public enum EnumPieceType {
CONSTANT,
CONNECTOR,
MODIFIER, // eg: Error Suppressor
TRICK,
ERROR_HANDLER;
TRICK;

public boolean isTrick() {
return this == TRICK || this == MODIFIER;
Expand Down
57 changes: 0 additions & 57 deletions src/main/java/vazkii/psi/api/spell/IErrorCatcher.java

This file was deleted.

3 changes: 3 additions & 0 deletions src/main/java/vazkii/psi/api/spell/SpellMetadata.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,15 @@ public final class SpellMetadata {
* Should errors from this spell not be sent to the player's chat?
*/
public boolean errorsSuppressed = false;
public final boolean[][] errorSuppressed;

public SpellMetadata() {
for (EnumSpellStat stat : EnumSpellStat.class.getEnumConstants()) {
stats.put(stat, 0);
statMultipliers.put(stat, 1.0);
}

errorSuppressed = new boolean[SpellGrid.GRID_SIZE][SpellGrid.GRID_SIZE];
}

/**
Expand Down
16 changes: 16 additions & 0 deletions src/main/java/vazkii/psi/api/spell/SpellPiece.java
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,14 @@ public void initParams() {
*/
public abstract Class<?> getEvaluationType();

/**
* Gets what type this piece evaluates as. Use for parameter dependent evaluation
* types to avoid infinite loops. Only called for pieces in a spell grid.
*/
public Class<?> getEvaluationType(Set<SpellPiece> visited) {
return getEvaluationType();
}

/**
* Evaluates this piece for the purpose of spell metadata calculation. If the piece
* is not a constant, you can safely return null.
Expand Down Expand Up @@ -135,6 +143,14 @@ public void addToMetadata(SpellMetadata meta) throws SpellCompilationException {
// NO-OP
}

/**
* Adds this piece's stats to the Spell's metadata.
* Also called on pieces not referenced anywhere in the spell.
*/
public void addModifierToMetadata(SpellMetadata meta) throws SpellCompilationException {
// NO-OP
}

/**
* Adds a {@link SpellParam} to this piece.
*/
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/vazkii/psi/api/spell/SpellRuntimeException.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ public class SpellRuntimeException extends Exception {
public static final String COMPARATOR = "psi.spellerror.comparator";
public static final String NAN = "psi.spellerror.nan";

public int x, y;

public SpellRuntimeException(String s) {
super(s);
}
Expand Down
28 changes: 28 additions & 0 deletions src/main/java/vazkii/psi/api/spell/param/ParamError.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* This class is distributed as part of the Psi Mod.
* Get the Source Code in github:
* https://github.com/Vazkii/Psi
*
* Psi is Open Source and distributed under the
* Psi License: https://psi.vazkii.net/license.php
*/
package vazkii.psi.api.spell.param;

import vazkii.psi.api.spell.SpellParam;

public class ParamError extends SpellParam<SpellParam.Any> {

public ParamError(String name, int color, boolean canDisable) {
super(name, color, canDisable);
}

public ParamError(String name, int color, boolean canDisable, ArrowType arrowType) {
super(name, color, canDisable, arrowType);
}

@Override
public Class<Any> getRequiredType() {
return Any.class;
}

}
66 changes: 0 additions & 66 deletions src/main/java/vazkii/psi/api/spell/piece/PieceErrorHandler.java

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public PieceOperator(Spell spell) {

@Override
public EnumPieceType getPieceType() {
return EnumPieceType.SELECTOR;
return EnumPieceType.OPERATOR;
}

@Override
Expand Down
Loading