diff --git a/src/main/java/dan200/computercraft/api/lua/ILuaFunction.java b/src/main/java/dan200/computercraft/api/lua/ILuaFunction.java new file mode 100644 index 000000000..cd75848e1 --- /dev/null +++ b/src/main/java/dan200/computercraft/api/lua/ILuaFunction.java @@ -0,0 +1,29 @@ +/* + * This file is part of the public ComputerCraft API - http://www.computercraft.info + * Copyright Daniel Ratcliffe, 2011-2020. This API may be redistributed unmodified and in full only. + * For help using the API, and posting your mods, visit the forums at computercraft.info. + */ +package dan200.computercraft.api.lua; + +import javax.annotation.Nonnull; + +/** + * A function, which can be called from Lua. If you need to return a table of functions, it is recommended to use + * an object with {@link LuaFunction} methods, or implement {@link IDynamicLuaObject}. + * + * @see MethodResult#of(Object) + */ +@FunctionalInterface +public interface ILuaFunction +{ + /** + * Call this function with a series of arguments. Note, this will always be called on the computer thread, + * and so its implementation must be thread-safe. + * + * @param arguments The arguments for this function + * @return The result of calling this function. + * @throws LuaException Upon Lua errors. + */ + @Nonnull + MethodResult call( @Nonnull IArguments arguments ) throws LuaException; +} diff --git a/src/main/java/dan200/computercraft/api/lua/MethodResult.java b/src/main/java/dan200/computercraft/api/lua/MethodResult.java index 2a7f80155..fce9f970f 100644 --- a/src/main/java/dan200/computercraft/api/lua/MethodResult.java +++ b/src/main/java/dan200/computercraft/api/lua/MethodResult.java @@ -58,7 +58,7 @@ public static MethodResult of() * * Integers, doubles, floats, strings, booleans, {@link Map}, {@link Collection}s, arrays and {@code null} will be * converted to their corresponding Lua type. {@code byte[]} and {@link ByteBuffer} will be treated as binary - * strings. + * strings. {@link ILuaFunction} will be treated as a function. * * In order to provide a custom object with methods, one may return a {@link IDynamicLuaObject}, or an arbitrary * class with {@link LuaFunction} annotations. Anything else will be converted to {@code nil}. diff --git a/src/main/java/dan200/computercraft/core/lua/CobaltLuaMachine.java b/src/main/java/dan200/computercraft/core/lua/CobaltLuaMachine.java index 40bf39c23..e678667e1 100644 --- a/src/main/java/dan200/computercraft/core/lua/CobaltLuaMachine.java +++ b/src/main/java/dan200/computercraft/core/lua/CobaltLuaMachine.java @@ -48,6 +48,8 @@ public class CobaltLuaMachine implements ILuaMachine ThreadUtils.factory( "Coroutine" ) ); + private static final LuaMethod FUNCTION_METHOD = ( target, context, args ) -> ((ILuaFunction) target).call( args ); + private final Computer m_computer; private final TimeoutState timeout; private final TimeoutDebugHandler debug; @@ -275,6 +277,11 @@ private LuaValue toValue( @Nullable Object object, @Nullable Map x.addApi( new ManyMethods() ), 50 ); } + @Test + public void testFunction() + { + ComputerBootstrap.run( + "assert(func.call()(123) == 123)", + x -> x.addApi( new ReturnFunction() ), 50 ); + } + public static class MainThread implements ILuaAPI, IPeripheral { public final String thread = Thread.currentThread().getName(); @@ -239,4 +247,19 @@ public String[] getNames() return new String[] { "many" }; } } + + public static class ReturnFunction implements ILuaAPI + { + @LuaFunction + public final ILuaFunction call() + { + return args -> MethodResult.of( args.getAll() ); + } + + @Override + public String[] getNames() + { + return new String[] { "func" }; + } + } }