1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2024-10-31 23:26:19 +00:00

Allow returning collections and arrays from Java

Closes #344
This commit is contained in:
SquidDev 2020-01-13 13:20:15 +00:00
parent 35c1b10224
commit 4c8fd4fc35
6 changed files with 67 additions and 101 deletions

View File

@ -22,8 +22,6 @@ import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
import static dan200.computercraft.api.lua.ArgumentHelper.getString;
@ -93,13 +91,7 @@ public class FSAPI implements ILuaAPI
m_env.addTrackingChange( TrackingField.FS_OPS );
try
{
String[] results = m_fileSystem.list( path );
Map<Object, Object> table = new HashMap<>();
for( int i = 0; i < results.length; i++ )
{
table.put( i + 1, results[i] );
}
return new Object[] { table };
return new Object[] { m_fileSystem.list( path ) };
}
catch( FileSystemException e )
{
@ -330,13 +322,7 @@ public class FSAPI implements ILuaAPI
try
{
m_env.addTrackingChange( TrackingField.FS_OPS );
String[] results = m_fileSystem.find( path );
Map<Object, Object> table = new HashMap<>();
for( int i = 0; i < results.length; i++ )
{
table.put( i + 1, results[i] );
}
return new Object[] { table };
return new Object[] { m_fileSystem.find( path ) };
}
catch( FileSystemException e )
{

View File

@ -377,16 +377,7 @@ public class PeripheralAPI implements ILuaAPI, IAPIEnvironment.IPeripheralChange
}
}
}
if( methods != null )
{
Map<Object, Object> table = new HashMap<>();
for( int i = 0; i < methods.length; i++ )
{
table.put( i + 1, methods[i] );
}
return new Object[] { table };
}
return null;
return methods != null ? new Object[] { new HashMap<>() } : null;
}
case 3:
{

View File

@ -11,8 +11,6 @@ import dan200.computercraft.api.lua.LuaException;
import dan200.computercraft.core.computer.ComputerSide;
import javax.annotation.Nonnull;
import java.util.HashMap;
import java.util.Map;
import static dan200.computercraft.api.lua.ArgumentHelper.*;
@ -58,16 +56,8 @@ public class RedstoneAPI implements ILuaAPI
{
switch( method )
{
case 0:
{
// getSides
Map<Object, Object> table = new HashMap<>();
for( int i = 0; i < ComputerSide.NAMES.length; i++ )
{
table.put( i + 1, ComputerSide.NAMES[i] );
}
return new Object[] { table };
}
case 0: // getSides
return new Object[] { ComputerSide.NAMES };
case 1:
{
// setOutput

View File

@ -25,11 +25,9 @@ import org.squiddev.cobalt.lib.*;
import org.squiddev.cobalt.lib.platform.VoidResourceManipulator;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.InputStream;
import java.util.Arrays;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.*;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
@ -263,80 +261,79 @@ public class CobaltLuaMachine implements ILuaMachine
return table;
}
private LuaValue toValue( Object object, Map<Object, LuaValue> values )
@Nonnull
private LuaValue toValue( @Nullable Object object, @Nonnull Map<Object, LuaValue> values )
{
if( object == null )
{
return Constants.NIL;
}
else if( object instanceof Number )
{
double d = ((Number) object).doubleValue();
return valueOf( d );
}
else if( object instanceof Boolean )
{
return valueOf( (Boolean) object );
}
else if( object instanceof String )
{
String s = object.toString();
return valueOf( s );
}
else if( object instanceof byte[] )
if( object == null ) return Constants.NIL;
if( object instanceof Number ) return valueOf( ((Number) object).doubleValue() );
if( object instanceof Boolean ) return valueOf( (Boolean) object );
if( object instanceof String ) return valueOf( object.toString() );
if( object instanceof byte[] )
{
byte[] b = (byte[]) object;
return valueOf( Arrays.copyOf( b, b.length ) );
}
else if( object instanceof Map )
LuaValue result = values.get( object );
if( result != null ) return result;
if( object instanceof ILuaObject )
{
LuaValue wrapped = wrapLuaObject( (ILuaObject) object );
values.put( object, wrapped );
return wrapped;
}
if( object instanceof Map )
{
// Table:
// Start remembering stuff
if( values == null )
{
values = new IdentityHashMap<>();
}
else if( values.containsKey( object ) )
{
return values.get( object );
}
LuaTable table = new LuaTable();
values.put( object, table );
// Convert all keys
for( Map.Entry<?, ?> pair : ((Map<?, ?>) object).entrySet() )
{
LuaValue key = toValue( pair.getKey(), values );
LuaValue value = toValue( pair.getValue(), values );
if( !key.isNil() && !value.isNil() )
{
table.rawset( key, value );
}
if( !key.isNil() && !value.isNil() ) table.rawset( key, value );
}
return table;
}
else if( object instanceof ILuaObject )
if( object instanceof Collection )
{
return wrapLuaObject( (ILuaObject) object );
Collection<?> objects = (Collection<?>) object;
LuaTable table = new LuaTable( objects.size(), 0 );
values.put( object, table );
int i = 0;
for( Object child : objects ) table.rawset( ++i, toValue( child, values ) );
return table;
}
else
if( object instanceof Object[] )
{
return Constants.NIL;
Object[] objects = (Object[]) object;
LuaTable table = new LuaTable( objects.length, 0 );
values.put( object, table );
for( int i = 0; i < objects.length; i++ ) table.rawset( i + 1, toValue( objects[i], values ) );
return table;
}
if( ComputerCraft.logPeripheralErrors )
{
ComputerCraft.log.warn( "Received unknown type '{}', returning nil.", object.getClass().getName() );
}
return Constants.NIL;
}
private Varargs toValues( Object[] objects )
{
if( objects == null || objects.length == 0 )
{
return Constants.NONE;
}
if( objects == null || objects.length == 0 ) return Constants.NONE;
Map<Object, LuaValue> result = new IdentityHashMap<>( 0 );
LuaValue[] values = new LuaValue[objects.length];
for( int i = 0; i < values.length; i++ )
{
Object object = objects[i];
values[i] = toValue( object, null );
values[i] = toValue( object, result );
}
return varargsOf( values );
}

View File

@ -25,8 +25,9 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import javax.annotation.Nonnull;
import java.util.Collections;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static dan200.computercraft.api.lua.ArgumentHelper.getInt;
@ -63,9 +64,9 @@ public class CommandAPI implements ILuaAPI
};
}
private static Map<Object, Object> createOutput( String output )
private static Object createOutput( String output )
{
return Collections.singletonMap( 1, output );
return new Object[] { output };
}
private Object[] doCommand( String command )
@ -141,8 +142,7 @@ public class CommandAPI implements ILuaAPI
case 2: // list
return context.executeMainThreadTask( () ->
{
int i = 1;
Map<Object, Object> result = new HashMap<>();
List<String> result = new ArrayList<>();
MinecraftServer server = m_computer.getWorld().getMinecraftServer();
if( server != null )
{
@ -157,7 +157,7 @@ public class CommandAPI implements ILuaAPI
{
if( command.checkPermission( server, commandSender ) )
{
result.put( i++, name );
result.add( name );
}
}
catch( Throwable t )
@ -205,12 +205,11 @@ public class CommandAPI implements ILuaAPI
{
throw new LuaException( "Co-ordinates out of range" );
}
if( (max.getX() - min.getX() + 1) * (max.getY() - min.getY() + 1) * (max.getZ() - min.getZ() + 1) > 4096 )
{
throw new LuaException( "Too many blocks" );
}
int i = 1;
Map<Object, Object> results = new HashMap<>();
int blocks = (max.getX() - min.getX() + 1) * (max.getY() - min.getY() + 1) * (max.getZ() - min.getZ() + 1);
if( blocks > 4096 ) throw new LuaException( "Too many blocks" );
List<Object> results = new ArrayList<>( blocks );
for( int y = min.getY(); y <= max.getY(); y++ )
{
for( int z = min.getZ(); z <= max.getZ(); z++ )
@ -218,7 +217,7 @@ public class CommandAPI implements ILuaAPI
for( int x = min.getX(); x <= max.getX(); x++ )
{
BlockPos pos = new BlockPos( x, y, z );
results.put( i++, getBlockInfo( world, pos ) );
results.add( getBlockInfo( world, pos ) );
}
}
}

View File

@ -369,7 +369,10 @@ public class TurtlePlaceCommand implements ITurtleCommand
if( !placed && (item instanceof ItemBucket || item instanceof ItemBoat || item instanceof ItemLilyPad || item instanceof ItemGlassBottle) )
{
EnumActionResult actionResult = ForgeHooks.onItemRightClick( turtlePlayer, EnumHand.MAIN_HAND );
PlayerInteractEvent.RightClickItem evt = new PlayerInteractEvent.RightClickItem( turtlePlayer, EnumHand.MAIN_HAND );
MinecraftForge.EVENT_BUS.post( evt );
EnumActionResult actionResult = evt.isCanceled() ? evt.getCancellationResult() : null;
// EnumActionResult actionResult = ForgeHooks.onItemRightClick( turtlePlayer, EnumHand.MAIN_HAND );
if( actionResult == EnumActionResult.SUCCESS )
{
placed = true;