1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2024-06-22 21:23:21 +00:00

Allow returning lua functions

Not sure how this will play with persistence when it happens (badly,
most likely), but it's not a bad idea to support it.

Closes #466
This commit is contained in:
SquidDev 2020-06-03 21:44:08 +01:00
parent c493d668c8
commit b9ff9b7f90
4 changed files with 60 additions and 1 deletions

View File

@ -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 <em>always</em> 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;
}

View File

@ -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}.

View File

@ -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<Object, LuaValu
LuaValue result = values.get( object );
if( result != null ) return result;
if( object instanceof ILuaFunction )
{
return new ResultInterpreterFunction( this, FUNCTION_METHOD, object, context, object.toString() );
}
if( object instanceof IDynamicLuaObject )
{
LuaValue wrapped = wrapLuaObject( object );

View File

@ -87,6 +87,14 @@ public void testMany()
x -> 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" };
}
}
}