1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-07-22 20:02:52 +00:00

Support LuaTable arguments in @LuaFunction

This commit is contained in:
Jonathan Coates 2025-07-14 08:11:35 +01:00
parent 018ce7c8a5
commit 00475b9bb0
No known key found for this signature in database
GPG Key ID: B9E431FF07C98D06
3 changed files with 52 additions and 7 deletions

View File

@ -61,4 +61,14 @@ public class ObjectLuaTable implements LuaTable<Object, Object> {
public Set<Entry<Object, Object>> entrySet() {
return map.entrySet();
}
@Override
public boolean equals(Object o) {
return this == o || o instanceof Map<?, ?> otherMap && map.equals(otherMap);
}
@Override
public int hashCode() {
return map.hashCode();
}
}

View File

@ -73,6 +73,22 @@ final class Generator<T> {
addArgType(argMethodMap, Map.class, "Table");
addArgType(argMethodMap, String.class, "String");
addArgType(argMethodMap, ByteBuffer.class, "Bytes");
argMethodMap.put(LuaTable.class, new ArgMethods(
// i -> new ObjectLuaTable(getTable(i))
MethodHandles.filterReturnValue(
LOOKUP.findVirtual(IArguments.class, "getTable", MethodType.methodType(Map.class, int.class)),
LOOKUP.findConstructor(ObjectLuaTable.class, MethodType.methodType(void.class, Map.class))
.asType(MethodType.methodType(LuaTable.class, Map.class))
),
// i -> optTable(i).map(ObjectLuaTable::new)
MethodHandles.filterReturnValue(
LOOKUP.findVirtual(IArguments.class, "optTable", MethodType.methodType(Optional.class, int.class)),
MethodHandles.insertArguments(
LOOKUP.findVirtual(Optional.class, "map", MethodType.methodType(Optional.class, Function.class)),
1, (Function<Map<?, ?>, LuaTable<?, ?>>) ObjectLuaTable::new
)
)
));
argMethods = Map.copyOf(argMethodMap);
ARG_TABLE_UNSAFE = ArgMethods.of(LuaTable.class, "TableUnsafe");
@ -335,10 +351,9 @@ final class Generator<T> {
}
private static @Nullable ArgMethods getArgMethods(Class<?> type, boolean unsafe) {
var getter = argMethods.get(type);
if (getter != null) return getter;
if (type == LuaTable.class && unsafe) return ARG_TABLE_UNSAFE;
return null;
return argMethods.get(type);
}
/**

View File

@ -10,6 +10,7 @@ import dan200.computercraft.core.computer.ComputerSide;
import dan200.computercraft.core.methods.LuaMethod;
import dan200.computercraft.core.methods.NamedMethod;
import org.hamcrest.Matcher;
import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.Test;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
@ -123,6 +124,17 @@ public class GeneratorTest {
assertThrows(LuaException.class, () -> apply(methods, new EnumMethods(), "getEnum", "not as side"));
}
@Test
public void testLuaTable() throws LuaException {
var methods = GENERATOR.getMethods(TableMethods.class);
assertThat(methods, containsInAnyOrder(named("getTable"), named("optTable")));
assertThat(apply(methods, new TableMethods(), "getTable", Map.of("x", "y")), one(is(Map.of("x", "y"))));
assertThat(apply(methods, new TableMethods(), "optTable", Map.of("x", "y")), one(is(Map.of("x", "y"))));
assertThat(apply(methods, new TableMethods(), "optTable"), one(nullValue()));
assertThrows(LuaException.class, () -> apply(methods, new TableMethods(), "getTable", "not a table"));
}
@Test
public void testMainThread() throws LuaException {
var methods = GENERATOR.getMethods(MainThread.class);
@ -277,6 +289,18 @@ public class GeneratorTest {
}
}
public static class TableMethods {
@LuaFunction
public final LuaTable<?, ?> getTable(LuaTable<?, ?> table) {
return table;
}
@LuaFunction
public final @Nullable LuaTable<?, ?> optTable(Optional<LuaTable<?, ?>> table) {
return table.orElse(null);
}
}
public static class MainThread {
@LuaFunction(mainThread = true)
public final void go() {
@ -288,10 +312,6 @@ public class GeneratorTest {
public final void withUnsafe(LuaTable<?, ?> table) {
}
@LuaFunction
public final void withoutUnsafe(LuaTable<?, ?> table) {
}
@LuaFunction(unsafe = true, mainThread = true)
public final void invalid(LuaTable<?, ?> table) {
}