This commit is contained in:
Linnea Gräf 2024-07-21 04:42:02 +02:00
parent e0e75d0344
commit 88fad02b96
No known key found for this signature in database
GPG key ID: AA563E93EB628D91
6 changed files with 136 additions and 45 deletions

View file

@ -32,8 +32,50 @@ java.toolchain.languageVersion = JavaLanguageVersion.of(21)
//minecraft.accessTransformers.file rootProject.file('src/main/resources/META-INF/accesstransformer.cfg') //minecraft.accessTransformers.file rootProject.file('src/main/resources/META-INF/accesstransformer.cfg')
//minecraft.accessTransformers.entry public net.minecraft.client.Minecraft textureManager # textureManager //minecraft.accessTransformers.entry public net.minecraft.client.Minecraft textureManager # textureManager
// Default run configurations. // Include resources generated by data generators.
// These can be tweaked, removed, or duplicated as needed. 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 { runs {
// applies to all the run configs below // applies to all the run configs below
configureEach { configureEach {
@ -50,6 +92,9 @@ runs {
systemProperty 'forge.logging.console.level', 'debug' systemProperty 'forge.logging.console.level', 'debug'
modSource project.sourceSets.main modSource project.sourceSets.main
dependencies {
runtime project.configurations.libraries
}
} }
client { client {
@ -77,49 +122,7 @@ runs {
programArguments.addAll '--mod', project.mod_id, '--all', '--output', file('src/generated/resources/').getAbsolutePath(), programArguments.addAll '--mod', project.mod_id, '--all', '--output', file('src/generated/resources/').getAbsolutePath(),
'--existing', file('src/main/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. // This block of code expands all declared replace properties in the specified resource targets.

View file

@ -4,6 +4,7 @@ import com.mojang.serialization.MapCodec;
import dev.exhq.ajarc.Ajar; import dev.exhq.ajarc.Ajar;
import dev.exhq.ajarc.network.ComputerScreenUpdate; import dev.exhq.ajarc.network.ComputerScreenUpdate;
import dev.exhq.ajarc.register.Register; import dev.exhq.ajarc.register.Register;
import dev.exhq.ajarc.vm.WasmVm;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.HolderLookup; import net.minecraft.core.HolderLookup;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
@ -33,7 +34,7 @@ public class ComputerBlockEntity extends BlockEntity {
private static final MapCodec<ComputerTerminal> screenCodec = ComputerTerminal.CODEC private static final MapCodec<ComputerTerminal> screenCodec = ComputerTerminal.CODEC
.fieldOf("screen") .fieldOf("screen")
.setPartial(() -> ComputerTerminal.ofSize(20, 30)); .setPartial(() -> ComputerTerminal.ofSize(20, 30));
private WasmVm vm = new WasmVm(this);
private List<String> lines = new ArrayList<>(); private List<String> lines = new ArrayList<>();
@Override @Override
@ -69,6 +70,10 @@ public class ComputerBlockEntity extends BlockEntity {
return screen; return screen;
} }
public void setTerminal(ComputerTerminal terminal) {
this.screen = terminal;
}
public void executeCommand(String line) { public void executeCommand(String line) {
lines.add("$ " + line); lines.add("$ " + line);
if (line.equals("small")) { if (line.equals("small")) {
@ -77,6 +82,10 @@ public class ComputerBlockEntity extends BlockEntity {
} else if (line.equals("big")) { } else if (line.equals("big")) {
screen = ComputerTerminal.ofSize(20, 30); screen = ComputerTerminal.ofSize(20, 30);
lines.add("Made big!"); 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 { } else {
lines.add("Made unknown!"); lines.add("Made unknown!");
} }

View 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();
}
}

Binary file not shown.

BIN
test.wasm Normal file

Binary file not shown.

14
test.wat Normal file
View 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))
)