Skip to content

Commit

Permalink
Support multiple PIDS
Browse files Browse the repository at this point in the history
  • Loading branch information
Kenny-Hui committed Oct 19, 2024
1 parent 491a3d8 commit 22592ff
Show file tree
Hide file tree
Showing 7 changed files with 104 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
import com.lx862.jcm.mod.block.entity.PIDSBlockEntity;
import com.lx862.jcm.mod.data.pids.preset.components.base.PIDSComponent;
import com.lx862.jcm.mod.data.scripting.PIDSScriptInstance;
import com.lx862.jcm.mod.data.scripting.PIDSScriptObject;
import com.lx862.jcm.mod.data.scripting.ScriptInstanceManager;
import com.lx862.jcm.mod.data.scripting.base.ScriptInstance;
import com.lx862.jcm.mod.data.scripting.util.*;
import com.lx862.jcm.mod.util.JCMLogger;
import org.mozilla.javascript.Context;
Expand All @@ -26,12 +29,12 @@
import java.util.List;

public class ScriptPIDSPreset extends PIDSPresetBase {
private final PIDSScriptInstance scriptInstance;
public final Scriptable scope;
private static final Identifier PLACEHOLDER_BACKGROUND = Constants.id("textures/block/pids/rv_default.png");

public ScriptPIDSPreset(String id, @Nullable String name, PIDSScriptInstance scriptInstance) {
public ScriptPIDSPreset(String id, @Nullable String name, Scriptable scope) {
super(id, name, false);
this.scriptInstance = scriptInstance;
this.scope = scope;
}

public static ScriptPIDSPreset parse(JsonObject rootJsonObject) {
Expand Down Expand Up @@ -62,7 +65,7 @@ public static ScriptPIDSPreset parse(JsonObject rootJsonObject) {

cx.evaluateString(scope, "\"use strict\"", "", 1, null);
cx.evaluateString(scope, scriptText, scriptLocation.getNamespace() + ":" + scriptLocation.getPath(), 1, null);
ScriptPIDSPreset preset = new ScriptPIDSPreset(id, name, new PIDSScriptInstance(scope));
ScriptPIDSPreset preset = new ScriptPIDSPreset(id, name, scope);
JCMLogger.info("Script for " + scriptLocation.getNamespace() + ":" + scriptLocation.getPath() + " has been parsed!");
return preset;
} catch (Exception e) {
Expand All @@ -74,21 +77,30 @@ public static ScriptPIDSPreset parse(JsonObject rootJsonObject) {

@Override
public void render(PIDSBlockEntity be, GraphicsHolder graphicsHolder, World world, BlockPos pos, Direction facing, ObjectArrayList<ArrivalResponse> arrivals, boolean[] rowHidden, float tickDelta, int x, int y, int width, int height) {
this.scriptInstance.execute(graphicsHolder, be);

graphicsHolder.translate(0, 0, -0.5);
PIDSContext pidsContext = new PIDSContext(world, pos, be.getCustomMessages(), arrivals, tickDelta);
for(PIDSComponent component : new ArrayList<>(this.scriptInstance.components)) {
graphicsHolder.translate(0, 0, -0.02);
graphicsHolder.push();
component.render(graphicsHolder, null, facing, pidsContext);
graphicsHolder.pop();
ScriptInstance scriptInstance = ScriptInstanceManager.getInstance(pos.asLong(), () -> new PIDSScriptInstance(pos, scope));
PIDSScriptObject obj = new PIDSScriptObject(graphicsHolder, be.getCustomMessages(), be.getRowHidden(), be.platformNumberHidden());

if(scriptInstance instanceof PIDSScriptInstance) {
PIDSScriptInstance pidsScriptInstance = (PIDSScriptInstance)scriptInstance;
scriptInstance.execute(obj, () -> {
pidsScriptInstance.components.clear();
pidsScriptInstance.components.addAll(obj.getDrawCalls());
});

graphicsHolder.translate(0, 0, -0.5);
PIDSContext pidsContext = new PIDSContext(world, pos, be.getCustomMessages(), arrivals, tickDelta);
for(PIDSComponent component : new ArrayList<>(pidsScriptInstance.components)) {
graphicsHolder.translate(0, 0, -0.02);
graphicsHolder.push();
component.render(graphicsHolder, null, facing, pidsContext);
graphicsHolder.pop();
}
}
}

@Override
public List<PIDSComponent> getComponents(ObjectArrayList<ArrivalResponse> arrivals, String[] customMessages, boolean[] rowHidden, int x, int y, int screenWidth, int screenHeight, int rows, boolean hidePlatform) {
return this.scriptInstance.components;
return new ArrayList<>();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,42 +1,26 @@
package com.lx862.jcm.mod.data.scripting;

import com.lx862.jcm.mod.block.entity.PIDSBlockEntity;
import com.lx862.jcm.mod.data.pids.preset.components.base.PIDSComponent;
import com.lx862.jcm.mod.data.scripting.base.ScriptInstance;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.Function;
import org.mozilla.javascript.Scriptable;
import org.mtr.mapping.mapper.GraphicsHolder;
import org.mtr.mapping.holder.BlockEntity;
import org.mtr.mapping.holder.BlockPos;
import org.mtr.mapping.holder.MinecraftClient;

import java.util.ArrayList;
import java.util.List;

public class PIDSScriptInstance extends ScriptInstance {
public List<PIDSComponent> components;
private final BlockEntity be;

public PIDSScriptInstance(Scriptable scope) {
public PIDSScriptInstance(BlockPos pos, Scriptable scope) {
super(scope);
this.be = MinecraftClient.getInstance().getWorldMapped().getBlockEntity(pos);
this.components = new ArrayList<>();
}

public void execute(GraphicsHolder graphicsHolder, PIDSBlockEntity be) {
execute(() -> {
try {
Context cx = Context.enter();
cx.setLanguageVersion(Context.VERSION_ES6);
ScriptContext ctx = new ScriptContext();
PIDSScriptObject pidsContext = new PIDSScriptObject(graphicsHolder, be.getCustomMessages(), be.getRowHidden(), be.platformNumberHidden());
Object renderFunction = scope.get("render", scope);
Object[] renderParams = new Object[]{ctx, null, pidsContext};

if(renderFunction instanceof Scriptable && renderFunction != Scriptable.NOT_FOUND) {
((Function)renderFunction).call(cx, scope, scope, renderParams);
}
components.clear();
components.addAll(pidsContext.getDrawCalls());
} finally {
Context.exit();
}
});
public boolean isDead() {
return be.isRemoved();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.lx862.jcm.mod.data.scripting;

import com.lx862.jcm.mod.data.scripting.base.ScriptInstance;
import com.lx862.jcm.mod.util.JCMLogger;

import java.util.HashMap;
import java.util.Map;
import java.util.function.Supplier;

public class ScriptInstanceManager {
private final static Map<Long, ScriptInstance> instances = new HashMap<>();

public static ScriptInstance getInstance(long uuid, Supplier<ScriptInstance> getInstance) {
if(instances.containsKey(uuid)) {
return instances.get(uuid);
} else {
ScriptInstance instance = getInstance.get();
instances.put(uuid, instance);
return instance;
}
}

public static void clearDeadInstance() {
int count = 0;
for(Map.Entry<Long, ScriptInstance> entry : new HashMap<>(instances).entrySet()) {
if(entry.getValue().isDead()) {
count++;
instances.remove(entry.getKey());
}
}
if(count > 0) {
JCMLogger.info("[Scripting] Removed {} dead instance", count);
}
}

public static void reset() {
instances.clear();
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
package com.lx862.jcm.mod.data.scripting.base;

import com.lx862.jcm.mod.data.scripting.PIDSScriptObject;
import com.lx862.jcm.mod.data.scripting.ScriptContext;
import com.lx862.jcm.mod.data.scripting.ScriptManager;
import com.lx862.jcm.mod.data.scripting.util.TimingUtil;
import com.lx862.jcm.mod.util.JCMLogger;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.Function;
import org.mozilla.javascript.Scriptable;

import java.util.concurrent.Future;

public abstract class ScriptInstance {
private static final int SCRIPT_RESET_TIME = 4000;
private long lastFailedTime = -1;
protected Scriptable state;
protected Future<?> scriptTask;
protected final Scriptable scope;
public double lastExecuteTime = 0;
Expand All @@ -18,20 +23,36 @@ public ScriptInstance(Scriptable scope) {
this.scope = scope;
}

public void execute(Runnable runScript) {
public void execute(Object targetObject, Runnable callback) {
if(scriptTask == null || scriptTask.isDone()) {
if(lastFailedTime == -1 || System.currentTimeMillis() - lastFailedTime > SCRIPT_RESET_TIME) {
scriptTask = ScriptManager.submitScript(() -> {
TimingUtil.prepareForScript(this);
try {
runScript.run();
try {
Context cx = Context.enter();
cx.setLanguageVersion(Context.VERSION_ES6);
if(state == null) state = cx.newObject(scope);
ScriptContext ctx = new ScriptContext();
Object renderFunction = scope.get("render", scope);
Object[] renderParams = new Object[]{ctx, state, targetObject};

if(renderFunction instanceof Scriptable && renderFunction != Scriptable.NOT_FOUND) {
((Function)renderFunction).call(cx, scope, scope, renderParams);
}
} finally {
Context.exit();
}
} catch (Exception e) {
e.printStackTrace();
JCMLogger.error("[PIDS] Error executing script!");
e.printStackTrace();
lastFailedTime = System.currentTimeMillis();
}
callback.run();
});
}
}
}

public abstract boolean isDead();
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public static void print(Object... objs) {
for(Object obj : objs) {
sb.append(obj.toString());
}
JCMLogger.info("[PIDS] {}", sb.toString().trim());
JCMLogger.info("[Scripting] {}", sb.toString().trim());
}

public static Identifier identifier(String textForm) {
Expand Down
2 changes: 2 additions & 0 deletions fabric/src/main/java/com/lx862/jcm/mod/registry/Events.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.lx862.jcm.mod.data.JCMClientStats;
import com.lx862.jcm.mod.data.JCMServerStats;
import com.lx862.jcm.mod.data.scripting.ScriptInstanceManager;
import com.lx862.jcm.mod.resources.JCMResourceManager;
import com.lx862.jcm.mod.resources.mcmeta.McMetaManager;

Expand All @@ -19,6 +20,7 @@ public static void registerClient() {
JCMRegistryClient.REGISTRY_CLIENT.eventRegistryClient.registerStartClientTick(() -> {
JCMClientStats.incrementGameTick();
McMetaManager.tick();
ScriptInstanceManager.clearDeadInstance();
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import com.google.gson.JsonParser;
import com.lx862.jcm.mod.Constants;
import com.lx862.jcm.mod.data.pids.PIDSManager;
import com.lx862.jcm.mod.data.scripting.ScriptInstanceManager;
import com.lx862.jcm.mod.data.scripting.ScriptManager;
import com.lx862.jcm.mod.render.text.TextRenderingManager;
import com.lx862.jcm.mod.resources.mcmeta.McMetaManager;
import com.lx862.jcm.mod.util.JCMLogger;
Expand All @@ -19,6 +21,8 @@ public static void reload() {
TextRenderingManager.initialize();
McMetaManager.reset();
PIDSManager.reset();
ScriptManager.reset();
ScriptInstanceManager.reset();

parseCustomResources();
}
Expand Down

0 comments on commit 22592ff

Please sign in to comment.