Add wasm
This commit is contained in:
parent
e0e75d0344
commit
88fad02b96
6 changed files with 136 additions and 45 deletions
91
build.gradle
91
build.gradle
|
@ -32,8 +32,50 @@ java.toolchain.languageVersion = JavaLanguageVersion.of(21)
|
|||
//minecraft.accessTransformers.file rootProject.file('src/main/resources/META-INF/accesstransformer.cfg')
|
||||
//minecraft.accessTransformers.entry public net.minecraft.client.Minecraft textureManager # textureManager
|
||||
|
||||
// Default run configurations.
|
||||
// These can be tweaked, removed, or duplicated as needed.
|
||||
// Include resources generated by data generators.
|
||||
sourceSets.main.resources { srcDir 'src/generated/resources' }
|
||||
|
||||
// Sets up a dependency configuration called 'localRuntime'.
|
||||
// This configuration should be used instead of 'runtimeOnly' to declare
|
||||
// a dependency that will be present for runtime testing but that is
|
||||
// "optional", meaning it will not be pulled by dependents of this mod.
|
||||
configurations {
|
||||
runtimeClasspath.extendsFrom localRuntime
|
||||
implementation.extendsFrom libraries
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// Specify the version of Minecraft to use.
|
||||
// Depending on the plugin applied there are several options. We will assume you applied the userdev plugin as shown above.
|
||||
// The group for userdev is net.neoforged, the module name is neoforge, and the version is the same as the neoforge version.
|
||||
// You can however also use the vanilla plugin (net.neoforged.gradle.vanilla) to use a version of Minecraft without the neoforge loader.
|
||||
// And its provides the option to then use net.minecraft as the group, and one of; client, server or joined as the module name, plus the game version as version.
|
||||
// For all intends and purposes: You can treat this dependency as if it is a normal library you would use.
|
||||
implementation "net.neoforged:neoforge:${neo_version}"
|
||||
libraries 'com.dylibso.chicory:runtime:0.0.12'
|
||||
// Example optional mod dependency with JEI
|
||||
// The JEI API is declared for compile time use, while the full JEI artifact is used at runtime
|
||||
// compileOnly "mezz.jei:jei-${mc_version}-common-api:${jei_version}"
|
||||
// compileOnly "mezz.jei:jei-${mc_version}-neoforge-api:${jei_version}"
|
||||
// We add the full version to localRuntime, not runtimeOnly, so that we do not publish a dependency on it
|
||||
// localRuntime "mezz.jei:jei-${mc_version}-neoforge:${jei_version}"
|
||||
|
||||
// Example mod dependency using a mod jar from ./libs with a flat dir repository
|
||||
// This maps to ./libs/coolmod-${mc_version}-${coolmod_version}.jar
|
||||
// The group id is ignored when searching -- in this case, it is "blank"
|
||||
// implementation "blank:coolmod-${mc_version}:${coolmod_version}"
|
||||
|
||||
// Example mod dependency using a file as dependency
|
||||
// implementation files("libs/coolmod-${mc_version}-${coolmod_version}.jar")
|
||||
|
||||
// Example project dependency using a sister or child project:
|
||||
// implementation project(":myproject")
|
||||
|
||||
// For more info:
|
||||
// http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html
|
||||
// http://www.gradle.org/docs/current/userguide/dependency_management.html
|
||||
}
|
||||
|
||||
runs {
|
||||
// applies to all the run configs below
|
||||
configureEach {
|
||||
|
@ -50,6 +92,9 @@ runs {
|
|||
systemProperty 'forge.logging.console.level', 'debug'
|
||||
|
||||
modSource project.sourceSets.main
|
||||
dependencies {
|
||||
runtime project.configurations.libraries
|
||||
}
|
||||
}
|
||||
|
||||
client {
|
||||
|
@ -77,49 +122,7 @@ runs {
|
|||
programArguments.addAll '--mod', project.mod_id, '--all', '--output', file('src/generated/resources/').getAbsolutePath(),
|
||||
'--existing', file('src/main/resources/').getAbsolutePath()
|
||||
}
|
||||
}
|
||||
|
||||
// Include resources generated by data generators.
|
||||
sourceSets.main.resources { srcDir 'src/generated/resources' }
|
||||
|
||||
// Sets up a dependency configuration called 'localRuntime'.
|
||||
// This configuration should be used instead of 'runtimeOnly' to declare
|
||||
// a dependency that will be present for runtime testing but that is
|
||||
// "optional", meaning it will not be pulled by dependents of this mod.
|
||||
configurations {
|
||||
runtimeClasspath.extendsFrom localRuntime
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// Specify the version of Minecraft to use.
|
||||
// Depending on the plugin applied there are several options. We will assume you applied the userdev plugin as shown above.
|
||||
// The group for userdev is net.neoforged, the module name is neoforge, and the version is the same as the neoforge version.
|
||||
// You can however also use the vanilla plugin (net.neoforged.gradle.vanilla) to use a version of Minecraft without the neoforge loader.
|
||||
// And its provides the option to then use net.minecraft as the group, and one of; client, server or joined as the module name, plus the game version as version.
|
||||
// For all intends and purposes: You can treat this dependency as if it is a normal library you would use.
|
||||
implementation "net.neoforged:neoforge:${neo_version}"
|
||||
implementation 'com.dylibso.chicory:runtime:0.0.12'
|
||||
// Example optional mod dependency with JEI
|
||||
// The JEI API is declared for compile time use, while the full JEI artifact is used at runtime
|
||||
// compileOnly "mezz.jei:jei-${mc_version}-common-api:${jei_version}"
|
||||
// compileOnly "mezz.jei:jei-${mc_version}-neoforge-api:${jei_version}"
|
||||
// We add the full version to localRuntime, not runtimeOnly, so that we do not publish a dependency on it
|
||||
// localRuntime "mezz.jei:jei-${mc_version}-neoforge:${jei_version}"
|
||||
|
||||
// Example mod dependency using a mod jar from ./libs with a flat dir repository
|
||||
// This maps to ./libs/coolmod-${mc_version}-${coolmod_version}.jar
|
||||
// The group id is ignored when searching -- in this case, it is "blank"
|
||||
// implementation "blank:coolmod-${mc_version}:${coolmod_version}"
|
||||
|
||||
// Example mod dependency using a file as dependency
|
||||
// implementation files("libs/coolmod-${mc_version}-${coolmod_version}.jar")
|
||||
|
||||
// Example project dependency using a sister or child project:
|
||||
// implementation project(":myproject")
|
||||
|
||||
// For more info:
|
||||
// http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html
|
||||
// http://www.gradle.org/docs/current/userguide/dependency_management.html
|
||||
}
|
||||
|
||||
// This block of code expands all declared replace properties in the specified resource targets.
|
||||
|
|
|
@ -4,6 +4,7 @@ import com.mojang.serialization.MapCodec;
|
|||
import dev.exhq.ajarc.Ajar;
|
||||
import dev.exhq.ajarc.network.ComputerScreenUpdate;
|
||||
import dev.exhq.ajarc.register.Register;
|
||||
import dev.exhq.ajarc.vm.WasmVm;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
|
@ -33,7 +34,7 @@ public class ComputerBlockEntity extends BlockEntity {
|
|||
private static final MapCodec<ComputerTerminal> screenCodec = ComputerTerminal.CODEC
|
||||
.fieldOf("screen")
|
||||
.setPartial(() -> ComputerTerminal.ofSize(20, 30));
|
||||
|
||||
private WasmVm vm = new WasmVm(this);
|
||||
private List<String> lines = new ArrayList<>();
|
||||
|
||||
@Override
|
||||
|
@ -69,6 +70,10 @@ public class ComputerBlockEntity extends BlockEntity {
|
|||
return screen;
|
||||
}
|
||||
|
||||
public void setTerminal(ComputerTerminal terminal) {
|
||||
this.screen = terminal;
|
||||
}
|
||||
|
||||
public void executeCommand(String line) {
|
||||
lines.add("$ " + line);
|
||||
if (line.equals("small")) {
|
||||
|
@ -77,6 +82,10 @@ public class ComputerBlockEntity extends BlockEntity {
|
|||
} else if (line.equals("big")) {
|
||||
screen = ComputerTerminal.ofSize(20, 30);
|
||||
lines.add("Made big!");
|
||||
} else if (line.equals("add")) {
|
||||
int left = 42, right = 69;
|
||||
int result = vm.add(left, right);
|
||||
lines.add(left + " + " + right + " = " + result);
|
||||
} else {
|
||||
lines.add("Made unknown!");
|
||||
}
|
||||
|
|
65
src/main/java/dev/exhq/ajarc/vm/WasmVm.java
Normal file
65
src/main/java/dev/exhq/ajarc/vm/WasmVm.java
Normal file
|
@ -0,0 +1,65 @@
|
|||
package dev.exhq.ajarc.vm;
|
||||
|
||||
import com.dylibso.chicory.runtime.HostFunction;
|
||||
import com.dylibso.chicory.runtime.HostImports;
|
||||
import com.dylibso.chicory.runtime.Instance;
|
||||
import com.dylibso.chicory.runtime.Module;
|
||||
import com.dylibso.chicory.wasm.types.Value;
|
||||
import com.dylibso.chicory.wasm.types.ValueType;
|
||||
import dev.exhq.ajarc.Ajar;
|
||||
import dev.exhq.ajarc.computer.ComputerBlockEntity;
|
||||
import dev.exhq.ajarc.computer.ComputerTerminal;
|
||||
import net.minecraft.client.Minecraft;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
public class WasmVm {
|
||||
|
||||
private final Instance instance;
|
||||
|
||||
public WasmVm(ComputerBlockEntity entity) {
|
||||
try {
|
||||
var setSize = new HostFunction(
|
||||
(instance1, args) -> {
|
||||
int rows = args[0].asInt();
|
||||
int cols = args[1].asInt();
|
||||
entity.setTerminal(ComputerTerminal.ofSize(rows, cols));
|
||||
return new Value[0];
|
||||
},
|
||||
"env",
|
||||
"setSize",
|
||||
List.of(ValueType.I32, ValueType.I32),
|
||||
List.of());
|
||||
var inputStream = Minecraft.getInstance()
|
||||
.getResourceManager()
|
||||
.getResourceOrThrow(Ajar.identifier("test.wasm"))
|
||||
.open();
|
||||
var module = Module.builder(inputStream)
|
||||
.withHostImports(new HostImports(
|
||||
new HostFunction[]{
|
||||
setSize
|
||||
}
|
||||
))
|
||||
.build();
|
||||
this.instance = module.instantiate();
|
||||
} catch (IOException e) {
|
||||
Ajar.LOGGER.error("Could not load wasm module", e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public int add(int left, int right) {
|
||||
var export = instance.export("add");
|
||||
var timer = System.nanoTime();
|
||||
for (int i = 0; i < 10000; i++) {
|
||||
export.apply(Value.i32(left), Value.i32(right));
|
||||
}
|
||||
System.out.println("Took " + ((System.nanoTime() - timer) / 1_000_000) + "ms to add 1000*2 numbers");
|
||||
var result = export.apply(Value.i32(left), Value.i32(right));
|
||||
assert result.length == 1;
|
||||
return result[0].asInt();
|
||||
}
|
||||
|
||||
|
||||
}
|
BIN
src/main/resources/assets/ajarc/test.wasm
Normal file
BIN
src/main/resources/assets/ajarc/test.wasm
Normal file
Binary file not shown.
BIN
test.wasm
Normal file
BIN
test.wasm
Normal file
Binary file not shown.
14
test.wat
Normal file
14
test.wat
Normal file
|
@ -0,0 +1,14 @@
|
|||
(module
|
||||
(import "computer" "setSize" (func $setSize (param $rows i32) (param $cols i32)))
|
||||
(func $add (param $left i32) (param $right i32) (result i32)
|
||||
i32.const 10
|
||||
i32.const 12
|
||||
call $setSize
|
||||
local.get $left
|
||||
local.get $right
|
||||
i32.add
|
||||
i32.const 10
|
||||
i32.add
|
||||
)
|
||||
(export "add" (func $add))
|
||||
)
|
Loading…
Reference in a new issue