Skip to content

Commit

Permalink
Automatically invalidate network errors on script changes
Browse files Browse the repository at this point in the history
Closes #5
  • Loading branch information
rubensworks committed Apr 13, 2024
1 parent 49ded95 commit 682ce88
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 4 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ mod_version=1.0.1
minecraft_version=1.19.2
forge_version=43.0.8
cyclopscore_version=1.19.0-401
integrateddynamics_version=1.19.2-1.21.0-696
integrateddynamics_version=1.19.2-1.21.2-717
release_type=release
fingerprint=bd0353b3e8a2810d60dd584e256e364bc3bedd44

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.cyclops.integratedscripting.api.network.IScript;
import org.cyclops.integratedscripting.api.network.IScriptFactory;
import org.cyclops.integratedscripting.api.network.IScriptingData;
import org.cyclops.integratedscripting.evaluate.EvaluationExceptionResolutionHelpers;
import org.cyclops.integratedscripting.evaluate.ScriptHelpers;
import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.PolyglotException;
Expand Down Expand Up @@ -48,7 +49,9 @@ public IScript getScript(int disk, Path path) throws EvaluationException {
try {
graalContext.eval(source);
} catch (PolyglotException e) {
throw new EvaluationException(Component.translatable("script.integratedscripting.error.script_read", path.toString(), disk, e.getMessage()));
throw EvaluationExceptionResolutionHelpers.resolveOnScriptChange(
new EvaluationException(Component.translatable("script.integratedscripting.error.script_read", path.toString(), disk, e.getMessage())),
disk, path);
}
Wrapper<IScriptingData.IDiskScriptsChangeListener> diskListener = new Wrapper<>();
return new GraalScript(graalContext, languageBinding, scriptInvalidateListener -> {
Expand All @@ -68,7 +71,9 @@ public IScript getScript(int disk, Path path) throws EvaluationException {
}
}, disk, path, null);
} catch (IOException e) {
throw new EvaluationException(Component.translatable("script.integratedscripting.error.script_read", path.toString(), disk, e.getMessage()));
throw EvaluationExceptionResolutionHelpers.resolveOnScriptChange(
new EvaluationException(Component.translatable("script.integratedscripting.error.script_read", path.toString(), disk, e.getMessage())),
disk, path);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package org.cyclops.integratedscripting.evaluate;

import org.cyclops.cyclopscore.datastructure.Wrapper;
import org.cyclops.integrateddynamics.api.evaluate.EvaluationException;
import org.cyclops.integratedscripting.api.network.IScriptingData;
import org.cyclops.integratedscripting.core.network.ScriptingNetworkHelpers;

import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.nio.file.Path;

/**
* @author rubensworks
*/
public class EvaluationExceptionResolutionHelpers {

// Holds weak references of created EvaluationExceptions
private static final ReferenceQueue<? super EvaluationException> EVALUATION_EXCEPTION_REFERENCE_QUEUE = new ReferenceQueue<>();

/**
* Indicate that the given EvaluationException must be resolved when the given script is changed.
* @param evaluationException An evaluation exception.
* @param disk A script disk.
* @param path A script path.
* @return The given exception.
*/
public static EvaluationException resolveOnScriptChange(EvaluationException evaluationException, int disk, Path path) {
Wrapper<IScriptingData.IDiskScriptsChangeListener> listener = new Wrapper<>();
listener.set(createListener(new EvaluationExceptionReference(evaluationException, EVALUATION_EXCEPTION_REFERENCE_QUEUE, disk, listener), disk, path));
ScriptingNetworkHelpers.getScriptingData().addListener(disk, listener.get());
return evaluationException;
}

/**
* Call this periodically to flush stale entries in
* {@link EvaluationExceptionResolutionHelpers#EVALUATION_EXCEPTION_REFERENCE_QUEUE}.
*/
public static void expungeStaleEvaluationExceptions() {
for (Object x; (x = EVALUATION_EXCEPTION_REFERENCE_QUEUE.poll()) != null; ) {
((EvaluationExceptionReference) x).removeListener();
}
}

protected static IScriptingData.IDiskScriptsChangeListener createListener(EvaluationExceptionReference evaluationExceptionReference, int disk, Path path) {
return scriptPathRelative -> {
if (scriptPathRelative.equals(path)) {
EvaluationException exception = evaluationExceptionReference.get();
if (exception != null) {
exception.resolve();
}
ScriptingNetworkHelpers.getScriptingData().removeListener(disk, evaluationExceptionReference.listener.get());
}
};
}

public static class EvaluationExceptionReference extends WeakReference<EvaluationException> {

private final int disk;
private final Wrapper<IScriptingData.IDiskScriptsChangeListener> listener;

public EvaluationExceptionReference(
EvaluationException referent,
ReferenceQueue<? super EvaluationException> queue,
int disk,
Wrapper<IScriptingData.IDiskScriptsChangeListener> listener
) {
super(referent, queue);
this.disk = disk;
this.listener = listener;
}

public void removeListener() {
ScriptingNetworkHelpers.getScriptingData().removeListener(disk, listener.get());
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,11 @@ public static IEvaluationExceptionFactory getDummyEvaluationExceptionFactory() {
}

public static IEvaluationExceptionFactory getEvaluationExceptionFactory(int disk, Path path, String member) {
return message -> new EvaluationException(Component.translatable("script.integratedscripting.error.script_exec", member, path.toString(), disk, message));
EvaluationExceptionResolutionHelpers.expungeStaleEvaluationExceptions();

return message -> EvaluationExceptionResolutionHelpers.resolveOnScriptChange(
new EvaluationException(Component.translatable("script.integratedscripting.error.script_exec", member, path.toString(), disk, message)),
disk, path);
}

}

0 comments on commit 682ce88

Please sign in to comment.