1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2024-09-29 23:40:46 +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.io.BufferedWriter;
import java.nio.channels.ReadableByteChannel; import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel; import java.nio.channels.WritableByteChannel;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function; import java.util.function.Function;
import static dan200.computercraft.api.lua.ArgumentHelper.getString; import static dan200.computercraft.api.lua.ArgumentHelper.getString;
@ -93,13 +91,7 @@ public class FSAPI implements ILuaAPI
m_env.addTrackingChange( TrackingField.FS_OPS ); m_env.addTrackingChange( TrackingField.FS_OPS );
try try
{ {
String[] results = m_fileSystem.list( path ); return new Object[] { 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 };
} }
catch( FileSystemException e ) catch( FileSystemException e )
{ {
@ -330,13 +322,7 @@ public class FSAPI implements ILuaAPI
try try
{ {
m_env.addTrackingChange( TrackingField.FS_OPS ); m_env.addTrackingChange( TrackingField.FS_OPS );
String[] results = m_fileSystem.find( path ); return new Object[] { 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 };
} }
catch( FileSystemException e ) catch( FileSystemException e )
{ {

View File

@ -377,16 +377,7 @@ public class PeripheralAPI implements ILuaAPI, IAPIEnvironment.IPeripheralChange
} }
} }
} }
if( methods != null ) return methods != null ? new Object[] { new HashMap<>() } : 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;
} }
case 3: case 3:
{ {

View File

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

View File

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

View File

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