Skip to content

Commit

Permalink
Support multiple script functions
Browse files Browse the repository at this point in the history
  • Loading branch information
zbx1425 committed Jan 31, 2024
1 parent e82886b commit 114517b
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public static void render(PoseStack vdStuff) {
}
for (AbstractScriptContext context : entry.getValue()) {
drawText(vdStuff, font,
String.format("#%08X (%.2f ms)", context.hashCode(), context.lastExecuteDuration / 1000f),
String.format("#%08X (%.2f ms)", context.hashCode(), context.lastExecuteDuration / 1000.0),
10, y, 0xFFCCCCFF);
y += lineHeight;
for (Map.Entry<String, Object> debugInfo : context.debugInfo.entrySet()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
import vendor.cn.zbx1425.mtrsteamloco.org.mozilla.javascript.*;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
Expand All @@ -27,6 +29,9 @@ public class ScriptHolder {
private static ExecutorService SCRIPT_THREAD = Executors.newSingleThreadExecutor();

private Scriptable scope;
private final List<Function> createFunctions = new ArrayList<>();
private final List<Function> renderFunctions = new ArrayList<>();
private final List<Function> disposeFunctions = new ArrayList<>();

public long failTime = 0;
public Exception failException = null;
Expand All @@ -42,6 +47,7 @@ public void load(String name, ResourceManager resourceManager, Map<ResourceLocat
try {
scope = new ImporterTopLevel(rhinoCtx);

// Populate Scope with global functions
scope.put("include", scope, new NativeJavaMethod(
ScriptResourceUtil.class.getMethod("includeScript", Object.class), "includeScript"));
scope.put("print", scope, new NativeJavaMethod(
Expand Down Expand Up @@ -91,12 +97,16 @@ public void load(String name, ResourceManager resourceManager, Map<ResourceLocat

rhinoCtx.evaluateString(scope, "\"use strict\"", "", 1, null);

// Run scripts
ScriptResourceUtil.activeContext = rhinoCtx;
ScriptResourceUtil.activeScope = scope;
for (Map.Entry<ResourceLocation, String> entry : scripts.entrySet()) {
String scriptStr = entry.getValue() == null
? ResourceUtil.readResource(resourceManager, entry.getKey()) : entry.getValue();
ScriptResourceUtil.executeScript(rhinoCtx, scope, entry.getKey(), scriptStr);
acquireFunction("create", createFunctions);
acquireFunction("render", renderFunctions);
acquireFunction("dispose", disposeFunctions);
}
ScriptResourceUtil.activeContext = null;
ScriptResourceUtil.activeScope = null;
Expand All @@ -109,7 +119,17 @@ public void reload(ResourceManager resourceManager) throws Exception {
load(name, resourceManager, scripts);
}

public Future<?> callFunctionAsync(String function, AbstractScriptContext scriptCtx, Runnable finishCallback) {
private void acquireFunction(String functionName, List<Function> target) {
Object jsFunction = scope.get(functionName, scope);
if (jsFunction != Scriptable.NOT_FOUND) {
if (jsFunction instanceof Function) {
target.add((Function)jsFunction);
}
scope.delete(functionName);
}
}

public Future<?> callFunctionAsync(List<Function> functions, AbstractScriptContext scriptCtx, Runnable finishCallback) {
if (duringFailTimeout()) return null;
failTime = 0;
return SCRIPT_THREAD.submit(() -> {
Expand All @@ -118,15 +138,12 @@ public Future<?> callFunctionAsync(String function, AbstractScriptContext script
if (scriptCtx.state == null) scriptCtx.state = rhinoCtx.newObject(scope);
try {
long startTime = System.nanoTime();
Object jsFunction = scope.get(function, scope);
if (!(jsFunction instanceof Function && jsFunction != Scriptable.NOT_FOUND)) {
jsFunction = scope.get(function + scriptCtx.getContextTypeName(), scope);
}
if (!(jsFunction instanceof Function && jsFunction != Scriptable.NOT_FOUND)) return;

TimingUtil.prepareForScript(scriptCtx);
Object[] functionParam = { scriptCtx, scriptCtx.state, scriptCtx.getWrapperObject() };
((Function)jsFunction).call(rhinoCtx, scope, scope, functionParam);
for (Function function : functions) {
function.call(rhinoCtx, scope, scope, functionParam);
}
if (finishCallback != null) finishCallback.run();
scriptCtx.lastExecuteDuration = System.nanoTime() - startTime;
} catch (Exception ex) {
Expand All @@ -144,20 +161,21 @@ public void tryCallRenderFunctionAsync(AbstractScriptContext scriptCtx) {
if (scriptCtx.disposed) return;
if (!scriptCtx.created) {
ScriptContextManager.trackContext(scriptCtx, this);
scriptCtx.scriptStatus = callFunctionAsync("create", scriptCtx, () -> {
scriptCtx.scriptStatus = callFunctionAsync(createFunctions, scriptCtx, () -> {
scriptCtx.created = true;
});
return;
}
if (scriptCtx.scriptStatus == null || scriptCtx.scriptStatus.isDone()) {
scriptCtx.scriptStatus = callFunctionAsync("render", scriptCtx, scriptCtx::renderFunctionFinished);
scriptCtx.scriptStatus = callFunctionAsync(renderFunctions, scriptCtx, scriptCtx::renderFunctionFinished);
}
}

public void tryCallDisposeFunctionAsync(AbstractScriptContext scriptCtx) {
if (!(scriptCtx.scriptStatus == null || scriptCtx.scriptStatus.isDone())) return;
scriptCtx.disposed = true;
if (scriptCtx.created) {
scriptCtx.scriptStatus = callFunctionAsync("dispose", scriptCtx, () -> {
scriptCtx.scriptStatus = callFunctionAsync(disposeFunctions, scriptCtx, () -> {
scriptCtx.created = false;
});
}
Expand Down

0 comments on commit 114517b

Please sign in to comment.