Restructure
ScriptCraft/pipeline/head There was a failure building this commit Details

This commit is contained in:
TheBrokenRail 2020-06-07 17:58:49 -04:00
parent 96bc39c035
commit 1c1563bbbf
22 changed files with 77 additions and 61 deletions

View File

@ -6,7 +6,7 @@ To communicate between Java and JS code, ScriptCraft utilizes a system called br
### Define The Bridge
```java
import com.thebrokenrail.scriptcraft.core.ScriptCraftCore;
import com.thebrokenrail.scriptcraft.core.ScriptCraftEntryPoint;
import com.thebrokenrail.scriptcraft.core.util.ScriptCraftEntryPoint;
public class ExampleBridges implements ScriptCraftEntryPoint {
@Override

View File

@ -3,7 +3,7 @@ To add an entry-point to your mod create a class implementing ```ScriptCraftEntr
## Example
```java
import com.thebrokenrail.scriptcraft.core.ScriptCraftEntryPoint;
import com.thebrokenrail.scriptcraft.core.util.ScriptCraftEntryPoint;
public class ExampleMod implements ScriptCraftEntryPoint {
@Override

View File

@ -98,11 +98,11 @@ class ScriptCraftPlugin : Plugin<Project> {
}
val npmInstallTask = tasks.register<NPMInstallTask>("npmInstall") {
group = "typescript"
group = "scriptcraft"
}
val extractTypescriptDependenciesTask = tasks.register<Sync>("extractTypescriptDependencies") {
group = "typescript"
group = "scriptcraft"
dependsOn(typescript)
@ -127,14 +127,14 @@ class ScriptCraftPlugin : Plugin<Project> {
}
val typescriptTask = tasks.register<NPMTask>("typescript") {
group = "typescript"
group = "scriptcraft"
taskName = "build"
outputDir = "build/ts"
}
val apiJarTask = tasks.register<Jar>("apiJar") {
group = "typescript"
group = "scriptcraft"
into("/types") {
from(Callable {

View File

@ -9,6 +9,12 @@
#include "com_thebrokenrail_scriptcraft_core_quickjs_QuickJSNative.h"
#include "console.h"
typedef struct {
JSContext *ctx;
JSRuntime *rt;
JSValue bridges;
} scriptcraft_ctx;
static JavaVM *jvm;
static const jint JNI_VERSION = JNI_VERSION_1_6;
@ -287,16 +293,13 @@ static jobject js_object_to_java_object(JNIEnv *env, JSContext *ctx, JSValue inp
}
static JSValue js_add_bridge(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
JSValue global_obj = JS_GetGlobalObject(ctx);
JSValue scriptcraft_obj = JS_GetPropertyStr(ctx, global_obj, "__scriptcraft_bridges__");
scriptcraft_ctx *data = JS_GetContextOpaque(ctx);
JSValue scriptcraft_obj = data->bridges;
const char *name = JS_ToCString(ctx, argv[0]);
JS_SetPropertyStr(ctx, scriptcraft_obj, name, JS_DupValue(ctx, argv[1]));
JS_FreeCString(ctx, name);
JS_FreeValue(ctx, scriptcraft_obj);
JS_FreeValue(ctx, global_obj);
return JS_UNDEFINED;
}
@ -331,7 +334,8 @@ static JSValue js_use_bridge(JSContext *ctx, JSValueConst this_val, int argc, JS
} else {
jthrowable err = (*env)->ExceptionOccurred(env);
if (err) {
jmethodID to_string = (*env)->GetMethodID(env, (*env)->FindClass(env, "java/lang/Object"), "toString", "()Ljava/lang/String;");
jclass exception_clazz = (*env)->FindClass(env, "com/thebrokenrail/scriptcraft/core/quickjs/JSException");
jmethodID to_string = (*env)->GetMethodID(env, exception_clazz, "getStackTrace", "(Ljava/lang/Throwable;)Ljava/lang/String;");
jstring java_string = (jstring) (*env)->CallObjectMethod(env, err, to_string);
const char *str = (*env)->GetStringUTFChars(env, java_string, 0);
@ -350,7 +354,9 @@ static JSValue js_use_bridge(JSContext *ctx, JSValueConst this_val, int argc, JS
}
JNIEXPORT jobject JNICALL Java_com_thebrokenrail_scriptcraft_core_quickjs_QuickJSNative_bridge(JNIEnv *env, jobject this_val, jstring bridge_name, jobjectArray arr) {
JSContext *ctx = (JSContext *) get_pointer(env, this_val, "ctx");
scriptcraft_ctx *data = (scriptcraft_ctx *) get_pointer(env, this_val, "data");
JSContext *ctx = data->ctx;
int length = (*env)->GetArrayLength(env, arr);
JSValue args[length];
@ -359,15 +365,16 @@ JNIEXPORT jobject JNICALL Java_com_thebrokenrail_scriptcraft_core_quickjs_QuickJ
args[i] = java_object_to_js_object(env, ctx, (*env)->GetObjectArrayElement(env, arr, i));
}
JSValue global_obj = JS_GetGlobalObject(ctx);
JSValue scriptcraft_obj = JS_GetPropertyStr(ctx, global_obj, "__scriptcraft_bridges__");
JSValue scriptcraft_obj = data->bridges;
const char *native_string = (*env)->GetStringUTFChars(env, bridge_name, 0);
JSValue bridge = JS_GetPropertyStr(ctx, scriptcraft_obj, native_string);
JSValue out;
if (JS_IsFunction(ctx, bridge)) {
JSValue global_obj = JS_GetGlobalObject(ctx);
out = JS_Call(ctx, bridge, global_obj, length, args);
JS_FreeValue(ctx, global_obj);
if (JS_IsException(out)) {
js_std_dump_error(ctx);
out = JS_NULL;
@ -387,8 +394,6 @@ JNIEXPORT jobject JNICALL Java_com_thebrokenrail_scriptcraft_core_quickjs_QuickJ
}
JS_FreeValue(ctx, bridge);
JS_FreeValue(ctx, scriptcraft_obj);
JS_FreeValue(ctx, global_obj);
jobject java_out = js_object_to_java_object(env, ctx, out);
JS_FreeValue(ctx, out);
@ -403,12 +408,6 @@ static int scriptcraft_core_init(JSContext *ctx, JSModuleDef *m) {
}
JNIEXPORT void JNICALL Java_com_thebrokenrail_scriptcraft_core_quickjs_QuickJSNative_init(JNIEnv *env, jobject this_val) {
jint rc = (*env)->GetJavaVM(env, &jvm);
if (rc != JNI_OK) {
throw_exception(env, "Unable To Cache JavaVM");
return;
}
JSRuntime *rt = JS_NewRuntime();
if (!rt) {
throw_exception(env, "Cannot Allocate JS Runtime");
@ -417,6 +416,7 @@ JNIEXPORT void JNICALL Java_com_thebrokenrail_scriptcraft_core_quickjs_QuickJSNa
JSContext *ctx = JS_NewContext(rt);
if (!ctx) {
throw_exception(env, "Cannot Allocate JS Context");
JS_FreeRuntime(rt);
return;
}
@ -431,26 +431,33 @@ JNIEXPORT void JNICALL Java_com_thebrokenrail_scriptcraft_core_quickjs_QuickJSNa
JSModuleDef *m = JS_NewCModule(ctx, "scriptcraft-core", scriptcraft_core_init);
if (!m) {
throw_exception(env, "Unable To Allocate C Module");
JS_FreeContext(ctx);
JS_FreeRuntime(rt);
return;
}
JS_AddModuleExport(ctx, m, "useBridge");
JS_AddModuleExport(ctx, m, "addBridge");
JSValue global_obj = JS_GetGlobalObject(ctx);
JS_SetPropertyStr(ctx, global_obj, "__scriptcraft_bridges__", JS_NewObject(ctx));
JS_FreeValue(ctx, global_obj);
scriptcraft_ctx *data = malloc(sizeof (scriptcraft_ctx));
data->ctx = ctx;
data->rt = rt;
data->bridges = JS_NewObject(ctx);
set_pointer(env, this_val, "rt", rt);
set_pointer(env, this_val, "ctx", ctx);
set_pointer(env, this_val, "data", data);
JS_SetContextOpaque(ctx, data);
}
JNIEXPORT void JNICALL Java_com_thebrokenrail_scriptcraft_core_quickjs_QuickJSNative_free(JNIEnv *env, jobject this_val) {
JSContext *ctx = (JSContext *) get_pointer(env, this_val, "ctx");
JSRuntime *rt = (JSRuntime *) get_pointer(env, this_val, "rt");
scriptcraft_ctx *data = (scriptcraft_ctx *) get_pointer(env, this_val, "data");
JS_FreeContext(ctx);
JS_FreeRuntime(rt);
JS_FreeValue(data->ctx, data->bridges);
JS_FreeContext(data->ctx);
JS_FreeRuntime(data->rt);
free(data);
}
static int eval_buf(JNIEnv *env, JSContext *ctx, const void *buf, int buf_len, const char *filename, int eval_flags) {
@ -479,7 +486,7 @@ static int eval_buf(JNIEnv *env, JSContext *ctx, const void *buf, int buf_len, c
}
JNIEXPORT void JNICALL Java_com_thebrokenrail_scriptcraft_core_quickjs_QuickJSNative_run(JNIEnv *env, jobject this_val, jstring data) {
JSContext *ctx = (JSContext *) get_pointer(env, this_val, "ctx");
JSContext *ctx = ((scriptcraft_ctx *) get_pointer(env, this_val, "data"))->ctx;
JSValue module_name, json_str;
char *init_js;

View File

@ -1,7 +1,7 @@
package com.thebrokenrail.scriptcraft.api;
import com.thebrokenrail.scriptcraft.api.bridge.Bridges;
import com.thebrokenrail.scriptcraft.core.ScriptCraftEntryPoint;
import com.thebrokenrail.scriptcraft.core.util.ScriptCraftEntryPoint;
@SuppressWarnings("unused")
public class ScriptCraftAPI implements ScriptCraftEntryPoint {

View File

@ -1,7 +1,7 @@
package com.thebrokenrail.scriptcraft.api.block;
import com.thebrokenrail.scriptcraft.core.ScriptCraftCore;
import com.thebrokenrail.scriptcraft.core.ValueUtil;
import com.thebrokenrail.scriptcraft.api.util.ValueUtil;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;

View File

@ -1,7 +1,7 @@
package com.thebrokenrail.scriptcraft.api.bridge;
import com.thebrokenrail.scriptcraft.core.ScriptCraftCore;
import com.thebrokenrail.scriptcraft.core.ValueUtil;
import com.thebrokenrail.scriptcraft.api.util.ValueUtil;
import net.minecraft.entity.Entity;
import net.minecraft.entity.damage.DamageSource;
import net.minecraft.nbt.CompoundTag;

View File

@ -1,7 +1,7 @@
package com.thebrokenrail.scriptcraft.api.bridge;
import com.thebrokenrail.scriptcraft.core.ScriptCraftCore;
import com.thebrokenrail.scriptcraft.core.ValueUtil;
import com.thebrokenrail.scriptcraft.api.util.ValueUtil;
import net.fabricmc.fabric.api.event.player.AttackBlockCallback;
import net.fabricmc.fabric.api.event.player.UseBlockCallback;
import net.fabricmc.fabric.api.event.player.UseItemCallback;

View File

@ -1,7 +1,7 @@
package com.thebrokenrail.scriptcraft.api.bridge;
import com.thebrokenrail.scriptcraft.core.ScriptCraftCore;
import com.thebrokenrail.scriptcraft.core.ValueUtil;
import com.thebrokenrail.scriptcraft.api.util.ValueUtil;
import net.minecraft.inventory.Inventory;
import net.minecraft.item.ItemStack;

View File

@ -1,7 +1,7 @@
package com.thebrokenrail.scriptcraft.api.bridge;
import com.thebrokenrail.scriptcraft.core.ScriptCraftCore;
import com.thebrokenrail.scriptcraft.core.ValueUtil;
import com.thebrokenrail.scriptcraft.api.util.ValueUtil;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.util.Identifier;

View File

@ -1,7 +1,7 @@
package com.thebrokenrail.scriptcraft.api.bridge;
import com.thebrokenrail.scriptcraft.core.ScriptCraftCore;
import com.thebrokenrail.scriptcraft.core.ValueUtil;
import com.thebrokenrail.scriptcraft.api.util.ValueUtil;
import net.minecraft.nbt.AbstractListTag;
import net.minecraft.nbt.AbstractNumberTag;
import net.minecraft.nbt.ByteTag;

View File

@ -2,7 +2,7 @@ package com.thebrokenrail.scriptcraft.api.bridge;
import com.thebrokenrail.scriptcraft.api.block.CustomBlockEntity;
import com.thebrokenrail.scriptcraft.core.ScriptCraftCore;
import com.thebrokenrail.scriptcraft.core.ValueUtil;
import com.thebrokenrail.scriptcraft.api.util.ValueUtil;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.entity.Entity;

View File

@ -1,7 +1,7 @@
package com.thebrokenrail.scriptcraft.api.item;
import com.thebrokenrail.scriptcraft.core.ScriptCraftCore;
import com.thebrokenrail.scriptcraft.core.ValueUtil;
import com.thebrokenrail.scriptcraft.api.util.ValueUtil;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item;

View File

@ -1,4 +1,4 @@
package com.thebrokenrail.scriptcraft.core;
package com.thebrokenrail.scriptcraft.api.util;
import java.util.Locale;

View File

@ -3,12 +3,13 @@ package com.thebrokenrail.scriptcraft.core;
import com.thebrokenrail.scriptcraft.core.quickjs.JSException;
import com.thebrokenrail.scriptcraft.core.quickjs.QuickJSNative;
import com.thebrokenrail.scriptcraft.core.quickjs.QuickJSManager;
import com.thebrokenrail.scriptcraft.core.util.Bridge;
import com.thebrokenrail.scriptcraft.core.util.ScriptCraftEntryPoint;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.loader.api.FabricLoader;
import java.util.HashMap;
import java.util.List;
import java.util.regex.Pattern;
@SuppressWarnings("unused")
public class ScriptCraftCore implements ModInitializer {
@ -43,7 +44,6 @@ public class ScriptCraftCore implements ModInitializer {
}
public static final String NAMESPACE = "scriptcraft";
public static final Pattern MOD_ID_PATTERN = Pattern.compile("[a-z][a-z0-9-_]{1,63}");
@Override
public void onInitialize() {

View File

@ -1,7 +1,17 @@
package com.thebrokenrail.scriptcraft.core.quickjs;
import java.io.PrintWriter;
import java.io.StringWriter;
public class JSException extends Exception {
public JSException(String message) {
super(message);
}
@SuppressWarnings("unused")
public String getStackTrace(Throwable e) {
StringWriter writer = new StringWriter();
e.printStackTrace(new PrintWriter(writer));
return writer.toString();
}
}

View File

@ -1,5 +1,7 @@
package com.thebrokenrail.scriptcraft.core.quickjs;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
@ -39,7 +41,7 @@ public class QuickJSManager {
}
}
if (task.err) {
throw new RuntimeException("Java Exception While Executing Task");
throw new RuntimeException("Java Exception While Executing Task: " + task.obj);
} else {
return task.obj;
}
@ -153,7 +155,7 @@ public class QuickJSManager {
if (task.lastTask) {
return null;
} else {
while (true) {
do {
try {
lock.wait();
} catch (InterruptedException e) {
@ -165,18 +167,16 @@ public class QuickJSManager {
outputTask.obj = outputTask.run(null);
outputTask.err = false;
} catch (Throwable e) {
e.printStackTrace();
outputTask.obj = null;
StringWriter writer = new StringWriter();
e.printStackTrace(new PrintWriter(writer));
outputTask.obj = writer.toString();
outputTask.err = true;
}
outputTask.done = true;
quickJSOutputTask.set(outputTask);
}
lock.notifyAll();
if (task.done) {
break;
}
}
} while (!task.done);
}
lock.set(false);
return task.obj;

View File

@ -1,7 +1,7 @@
package com.thebrokenrail.scriptcraft.core.quickjs;
import com.thebrokenrail.scriptcraft.core.ScriptCraftCore;
import com.thebrokenrail.scriptcraft.core.ScriptCraftEntryPoint;
import com.thebrokenrail.scriptcraft.core.util.ScriptCraftEntryPoint;
import net.fabricmc.loader.api.FabricLoader;
import java.io.BufferedReader;

View File

@ -1,6 +1,6 @@
package com.thebrokenrail.scriptcraft.core.quickjs;
import com.thebrokenrail.scriptcraft.core.OSUtil;
import com.thebrokenrail.scriptcraft.core.util.OSUtil;
import com.thebrokenrail.scriptcraft.core.ScriptCraftCore;
import java.io.File;
@ -9,14 +9,13 @@ import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
@SuppressWarnings("unused")
public class QuickJSNative {
public QuickJSNative() throws JSException {
init();
}
private long ctx;
private long rt;
@SuppressWarnings("unused")
private long data;
public native void init() throws JSException;

View File

@ -1,4 +1,4 @@
package com.thebrokenrail.scriptcraft.core;
package com.thebrokenrail.scriptcraft.core.util;
public interface Bridge {
Object use(Object... args);

View File

@ -1,4 +1,4 @@
package com.thebrokenrail.scriptcraft.core;
package com.thebrokenrail.scriptcraft.core.util;
import java.util.Locale;

View File

@ -1,4 +1,4 @@
package com.thebrokenrail.scriptcraft.core;
package com.thebrokenrail.scriptcraft.core.util;
public interface ScriptCraftEntryPoint {
String getEntryPoint();