mirror of
				https://github.com/SquidDev-CC/CC-Tweaked
				synced 2025-10-31 05:33:00 +00:00 
			
		
		
		
	Migrate LuaJLuaMachine to use Cobalt
This commit is contained in:
		| @@ -15,7 +15,7 @@ import dan200.computercraft.core.apis.*; | ||||
| import dan200.computercraft.core.filesystem.FileSystem; | ||||
| import dan200.computercraft.core.filesystem.FileSystemException; | ||||
| import dan200.computercraft.core.lua.ILuaMachine; | ||||
| import dan200.computercraft.core.lua.LuaJLuaMachine; | ||||
| import dan200.computercraft.core.lua.CobaltLuaMachine; | ||||
| import dan200.computercraft.core.terminal.Terminal; | ||||
|  | ||||
| import java.io.IOException; | ||||
| @@ -622,7 +622,7 @@ public class Computer | ||||
|     private void initLua() | ||||
|     { | ||||
|         // Create the lua machine | ||||
|         ILuaMachine machine = new LuaJLuaMachine( this ); | ||||
|         ILuaMachine machine = new CobaltLuaMachine( this ); | ||||
|          | ||||
|         // Add the APIs | ||||
|         for(ILuaAPI api : m_apis) | ||||
|   | ||||
| @@ -15,105 +15,102 @@ import dan200.computercraft.core.apis.ILuaAPI; | ||||
| import dan200.computercraft.core.computer.Computer; | ||||
| import dan200.computercraft.core.computer.ITask; | ||||
| import dan200.computercraft.core.computer.MainThread; | ||||
| 
 | ||||
| import org.luaj.vm2.*; | ||||
| import org.luaj.vm2.lib.OneArgFunction; | ||||
| import org.luaj.vm2.lib.VarArgFunction; | ||||
| import org.luaj.vm2.lib.ZeroArgFunction; | ||||
| import org.luaj.vm2.lib.jse.JsePlatform; | ||||
| import org.squiddev.cobalt.*; | ||||
| import org.squiddev.cobalt.compiler.CompileException; | ||||
| import org.squiddev.cobalt.compiler.LoadState; | ||||
| import org.squiddev.cobalt.debug.DebugFrame; | ||||
| import org.squiddev.cobalt.debug.DebugHandler; | ||||
| import org.squiddev.cobalt.debug.DebugState; | ||||
| import org.squiddev.cobalt.function.LuaFunction; | ||||
| import org.squiddev.cobalt.function.VarArgFunction; | ||||
| import org.squiddev.cobalt.lib.*; | ||||
| import org.squiddev.cobalt.lib.platform.AbstractResourceManipulator; | ||||
| 
 | ||||
| import javax.annotation.Nonnull; | ||||
| import java.io.*; | ||||
| import java.io.IOException; | ||||
| import java.io.InputStream; | ||||
| import java.io.OutputStream; | ||||
| import java.util.Arrays; | ||||
| import java.util.HashMap; | ||||
| import java.util.IdentityHashMap; | ||||
| import java.util.Map; | ||||
| 
 | ||||
| public class LuaJLuaMachine implements ILuaMachine | ||||
| import static org.squiddev.cobalt.Constants.NONE; | ||||
| import static org.squiddev.cobalt.ValueFactory.valueOf; | ||||
| import static org.squiddev.cobalt.ValueFactory.varargsOf; | ||||
| 
 | ||||
| public class CobaltLuaMachine implements ILuaMachine | ||||
| { | ||||
|     private Computer m_computer; | ||||
|     private final Computer m_computer; | ||||
| 
 | ||||
|     private LuaValue m_globals; | ||||
|     private LuaValue m_loadString; | ||||
|     private LuaValue m_assert; | ||||
|     private LuaValue m_coroutine_create; | ||||
|     private LuaValue m_coroutine_resume; | ||||
|     private LuaValue m_coroutine_yield; | ||||
|     private final LuaState m_state; | ||||
|     private final LuaTable m_globals; | ||||
| 
 | ||||
|     private LuaValue m_mainRoutine; | ||||
|     private LuaThread m_mainRoutine; | ||||
|     private String m_eventFilter; | ||||
|     private String m_softAbortMessage; | ||||
|     private String m_hardAbortMessage; | ||||
| 
 | ||||
|     private Map<Object, LuaValue> m_valuesInProgress; | ||||
|     private Map<LuaValue, Object> m_objectsInProgress; | ||||
| 
 | ||||
|     public LuaJLuaMachine( Computer computer ) | ||||
|     public CobaltLuaMachine( Computer computer ) | ||||
|     { | ||||
|         m_computer = computer; | ||||
| 
 | ||||
|         // Create an environment to run in | ||||
|         m_globals = JsePlatform.debugGlobals(); | ||||
|         m_loadString = m_globals.get("loadstring"); | ||||
|         m_assert = m_globals.get("assert"); | ||||
| 
 | ||||
|         LuaValue coroutine = m_globals.get("coroutine"); | ||||
|         final LuaValue native_coroutine_create = coroutine.get("create"); | ||||
|          | ||||
|         LuaValue debug = m_globals.get("debug"); | ||||
|         final LuaValue debug_sethook = debug.get("sethook"); | ||||
|          | ||||
|         coroutine.set("create", new OneArgFunction() { | ||||
|             @Override | ||||
|             public LuaValue call( LuaValue value ) | ||||
|         final LuaState state = this.m_state = new LuaState( new AbstractResourceManipulator() | ||||
|         { | ||||
|                 final LuaThread thread = native_coroutine_create.call( value ).checkthread(); | ||||
|                 debug_sethook.invoke( new LuaValue[] { | ||||
|                     thread, | ||||
|                     new ZeroArgFunction() { | ||||
|             @Override | ||||
|                         public LuaValue call() { | ||||
|                             String hardAbortMessage = m_hardAbortMessage; | ||||
|                             if( hardAbortMessage != null ) | ||||
|             public InputStream findResource( String filename ) | ||||
|             { | ||||
|                                 LuaThread.yield(LuaValue.NIL); | ||||
|                 return null; | ||||
|             } | ||||
|                             return LuaValue.NIL; | ||||
|                         } | ||||
|                     }, | ||||
|                     LuaValue.NIL, | ||||
|                     LuaValue.valueOf(100000) | ||||
|         } ); | ||||
|                 return thread;                 | ||||
|             } | ||||
|         }); | ||||
|         state.debug = new DebugHandler( state ) | ||||
|         { | ||||
|             private int count = 0; | ||||
| 
 | ||||
|         m_coroutine_create = coroutine.get("create"); | ||||
|         m_coroutine_resume = coroutine.get("resume"); | ||||
|         m_coroutine_yield = coroutine.get("yield"); | ||||
|             @Override | ||||
|             public void onInstruction( DebugState ds, DebugFrame di, int pc, Varargs extras, int top ) throws LuaError | ||||
|             { | ||||
|                 int count = ++this.count; | ||||
|                 if( count > 100000 ) | ||||
|                 { | ||||
|                     if( m_hardAbortMessage != null ) LuaThread.yield( state, NONE ); | ||||
|                     this.count = 0; | ||||
|                 } | ||||
| 
 | ||||
|                 super.onInstruction( ds, di, pc, extras, top ); | ||||
|             } | ||||
| 
 | ||||
|             @Override | ||||
|             public void poll() throws LuaError | ||||
|             { | ||||
|                 if( m_hardAbortMessage != null ) LuaThread.yield( state, NONE ); | ||||
|             } | ||||
|         }; | ||||
| 
 | ||||
|         m_globals = new LuaTable(); | ||||
|         state.setupThread( m_globals ); | ||||
| 
 | ||||
|         // Add basic libraries | ||||
|         m_globals.load( state, new BaseLib() ); | ||||
|         m_globals.load( state, new TableLib() ); | ||||
|         m_globals.load( state, new StringLib() ); | ||||
|         m_globals.load( state, new MathLib() ); | ||||
|         m_globals.load( state, new CoroutineLib() ); | ||||
| 
 | ||||
|         // Remove globals we don't want to expose | ||||
|         m_globals.set( "collectgarbage", LuaValue.NIL ); | ||||
|         m_globals.set( "dofile", LuaValue.NIL ); | ||||
|         m_globals.set( "loadfile", LuaValue.NIL ); | ||||
|         m_globals.set( "module", LuaValue.NIL ); | ||||
|         m_globals.set( "require", LuaValue.NIL ); | ||||
|         m_globals.set( "package", LuaValue.NIL );         | ||||
|         m_globals.set( "io", LuaValue.NIL ); | ||||
|         m_globals.set( "os", LuaValue.NIL ); | ||||
|         m_globals.set( "print", LuaValue.NIL ); | ||||
|         m_globals.set( "luajava", LuaValue.NIL ); | ||||
|         m_globals.set( "debug", LuaValue.NIL ); | ||||
|         m_globals.set( "newproxy", LuaValue.NIL ); | ||||
|         m_globals.set( "__inext", LuaValue.NIL ); | ||||
|         m_globals.rawset( "collectgarbage", Constants.NIL ); | ||||
|         m_globals.rawset( "dofile", Constants.NIL ); | ||||
|         m_globals.rawset( "loadfile", Constants.NIL ); | ||||
|         m_globals.rawset( "print", Constants.NIL ); | ||||
| 
 | ||||
|         // Add version globals | ||||
|         m_globals.set( "_VERSION", "Lua 5.1" ); | ||||
|         m_globals.set( "_HOST", computer.getAPIEnvironment().getComputerEnvironment().getHostString() ); | ||||
|         m_globals.set( "_CC_DEFAULT_SETTINGS", toValue( ComputerCraft.default_computer_settings ) ); | ||||
|         m_globals.rawset( "_VERSION", valueOf( "Lua 5.1" ) ); | ||||
|         m_globals.rawset( "_HOST", valueOf( computer.getAPIEnvironment().getComputerEnvironment().getHostString() ) ); | ||||
|         m_globals.rawset( "_CC_DEFAULT_SETTINGS", valueOf( ComputerCraft.default_computer_settings ) ); | ||||
|         if( ComputerCraft.disable_lua51_features ) | ||||
|         { | ||||
|             m_globals.set( "_CC_DISABLE_LUA51_FEATURES", toValue( true ) ); | ||||
|             m_globals.rawset( "_CC_DISABLE_LUA51_FEATURES", Constants.TRUE ); | ||||
|         } | ||||
| 
 | ||||
|         // Our main function will go here | ||||
| @@ -132,7 +129,7 @@ public class LuaJLuaMachine implements ILuaMachine | ||||
|         String[] names = api.getNames(); | ||||
|         for( String name : names ) | ||||
|         { | ||||
|             m_globals.set( name, table ); | ||||
|             m_globals.rawset( name, table ); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| @@ -147,48 +144,23 @@ public class LuaJLuaMachine implements ILuaMachine | ||||
| 
 | ||||
|         try | ||||
|         { | ||||
|             // Read the whole bios into a string | ||||
|             String biosText; | ||||
|             try | ||||
|             LuaFunction value = LoadState.load( m_state, bios, "@bios.lua", m_globals ); | ||||
|             m_mainRoutine = new LuaThread( m_state, value, m_globals ); | ||||
|         } | ||||
|         catch( CompileException e ) | ||||
|         { | ||||
|                 InputStreamReader isr; | ||||
|                 try | ||||
|             if( m_mainRoutine != null ) | ||||
|             { | ||||
|                     isr = new InputStreamReader( bios, "UTF-8" ); | ||||
|                 m_mainRoutine.abandon(); | ||||
|                 m_mainRoutine = null; | ||||
|             } | ||||
|                 catch( UnsupportedEncodingException e ) | ||||
|                 { | ||||
|                     isr = new InputStreamReader( bios ); | ||||
|                 } | ||||
|                 BufferedReader reader = new BufferedReader( isr ); | ||||
|                 StringBuilder fileText = new StringBuilder( "" ); | ||||
|                 String line = reader.readLine(); | ||||
|                 while( line != null ) { | ||||
|                     fileText.append( line ); | ||||
|                     line = reader.readLine(); | ||||
|                     if( line != null ) { | ||||
|                         fileText.append( "\n" ); | ||||
|                     } | ||||
|                 } | ||||
|                 biosText = fileText.toString(); | ||||
|         } | ||||
|         catch( IOException e ) | ||||
|             { | ||||
|                 throw new LuaError( "Could not read file" ); | ||||
|             } | ||||
|              | ||||
|             // Load it | ||||
|             LuaValue program = m_assert.call( m_loadString.call(  | ||||
|                 toValue( biosText ), toValue( "bios.lua" ) | ||||
|             )); | ||||
|             m_mainRoutine = m_coroutine_create.call( program ); | ||||
|         } | ||||
|         catch( LuaError e ) | ||||
|         { | ||||
|             ComputerCraft.log.warn( "Could not load bios.lua ", e ); | ||||
|             if( m_mainRoutine != null ) | ||||
|             { | ||||
|                 ((LuaThread)m_mainRoutine).abandon(); | ||||
|                 m_mainRoutine.abandon(); | ||||
|                 m_mainRoutine = null; | ||||
|             } | ||||
|         } | ||||
| @@ -209,32 +181,25 @@ public class LuaJLuaMachine implements ILuaMachine | ||||
| 
 | ||||
|         try | ||||
|         { | ||||
|             LuaValue[] resumeArgs; | ||||
|             Varargs resumeArgs = Constants.NONE; | ||||
|             if( eventName != null ) | ||||
|             { | ||||
|                 resumeArgs = toValues( arguments, 2 ); | ||||
|                 resumeArgs[0] = m_mainRoutine; | ||||
|                 resumeArgs[1] = toValue( eventName ); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 resumeArgs = new LuaValue[1]; | ||||
|                 resumeArgs[0] = m_mainRoutine; | ||||
|                 resumeArgs = varargsOf( valueOf( eventName ), toValues( arguments ) ); | ||||
|             } | ||||
| 
 | ||||
|             Varargs results = m_coroutine_resume.invoke( LuaValue.varargsOf( resumeArgs ) ); | ||||
|             Varargs results = m_mainRoutine.resume( resumeArgs ); | ||||
|             if( m_hardAbortMessage != null ) | ||||
|             { | ||||
|                 throw new LuaError( m_hardAbortMessage ); | ||||
|             } | ||||
|             else if( results.arg1().checkboolean() == false ) | ||||
|             else if( !results.first().checkBoolean() ) | ||||
|             { | ||||
|                 throw new LuaError( results.arg(2).checkstring().toString() ); | ||||
|                 throw new LuaError( results.arg( 2 ).checkString() ); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 LuaValue filter = results.arg(2); | ||||
|                 if( filter.isstring() ) | ||||
|                 LuaValue filter = results.arg( 2 ); | ||||
|                 if( filter.isString() ) | ||||
|                 { | ||||
|                     m_eventFilter = filter.toString(); | ||||
|                 } | ||||
| @@ -244,15 +209,15 @@ public class LuaJLuaMachine implements ILuaMachine | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             LuaThread mainThread = (LuaThread)m_mainRoutine; | ||||
|             if( mainThread.getStatus().equals("dead") ) | ||||
|             LuaThread mainThread = m_mainRoutine; | ||||
|             if( mainThread.getStatus().equals( "dead" ) ) | ||||
|             { | ||||
|                 m_mainRoutine = null; | ||||
|             } | ||||
|         } | ||||
|         catch( LuaError e ) | ||||
|         { | ||||
|             ((LuaThread)m_mainRoutine).abandon(); | ||||
|             m_mainRoutine.abandon(); | ||||
|             m_mainRoutine = null; | ||||
|         } | ||||
|         finally | ||||
| @@ -298,7 +263,7 @@ public class LuaJLuaMachine implements ILuaMachine | ||||
|     { | ||||
|         if( m_mainRoutine != null ) | ||||
|         { | ||||
|             LuaThread mainThread = (LuaThread)m_mainRoutine; | ||||
|             LuaThread mainThread = m_mainRoutine; | ||||
|             mainThread.abandon(); | ||||
|             m_mainRoutine = null; | ||||
|         } | ||||
| @@ -306,11 +271,6 @@ public class LuaJLuaMachine implements ILuaMachine | ||||
| 
 | ||||
|     private void tryAbort() throws LuaError | ||||
|     { | ||||
| //        while( m_stopped ) | ||||
| //        { | ||||
| //            m_coroutine_yield.call(); | ||||
| //        } | ||||
|          | ||||
|         String abortMessage = m_softAbortMessage; | ||||
|         if( abortMessage != null ) | ||||
|         { | ||||
| @@ -324,29 +284,31 @@ public class LuaJLuaMachine implements ILuaMachine | ||||
|     { | ||||
|         LuaTable table = new LuaTable(); | ||||
|         String[] methods = object.getMethodNames(); | ||||
|         for(int i=0; i<methods.length; ++i ) | ||||
|         for( int i = 0; i < methods.length; ++i ) | ||||
|         { | ||||
|             if( methods[i] != null ) | ||||
|             if( methods[ i ] != null ) | ||||
|             { | ||||
|                 final int method = i; | ||||
|                 final ILuaObject apiObject = object; | ||||
|                 final String methodName = methods[i]; | ||||
|                 table.set( methodName, new VarArgFunction() { | ||||
|                 final String methodName = methods[ i ]; | ||||
|                 table.rawset( methodName, new VarArgFunction() | ||||
|                 { | ||||
|                     @Override | ||||
|                     public Varargs invoke( Varargs _args ) | ||||
|                     public Varargs invoke( final LuaState state, Varargs _args ) throws LuaError | ||||
|                     { | ||||
|                         tryAbort(); | ||||
|                         Object[] arguments = toObjects( _args, 1 ); | ||||
|                         Object[] results; | ||||
|                         try | ||||
|                         { | ||||
|                             results = apiObject.callMethod( new ILuaContext() { | ||||
|                             results = apiObject.callMethod( new ILuaContext() | ||||
|                             { | ||||
|                                 @Nonnull | ||||
|                                 @Override | ||||
|                                 public Object[] pullEvent( String filter ) throws LuaException, InterruptedException | ||||
|                                 { | ||||
|                                     Object[] results = pullEventRaw( filter ); | ||||
|                                     if( results.length >= 1 && results[0].equals( "terminate" ) ) | ||||
|                                     if( results.length >= 1 && results[ 0 ].equals( "terminate" ) ) | ||||
|                                     { | ||||
|                                         throw new LuaException( "Terminated", 0 ); | ||||
|                                     } | ||||
| @@ -366,14 +328,17 @@ public class LuaJLuaMachine implements ILuaMachine | ||||
|                                 { | ||||
|                                     try | ||||
|                                     { | ||||
|                                         LuaValue[] yieldValues = toValues( yieldArgs, 0 ); | ||||
|                                         Varargs results = m_coroutine_yield.invoke( LuaValue.varargsOf( yieldValues ) ); | ||||
|                                         Varargs results = LuaThread.yield( state, toValues( yieldArgs ) ); | ||||
|                                         return toObjects( results, 1 ); | ||||
|                                     } | ||||
|                                     catch( OrphanedThread e ) | ||||
|                                     { | ||||
|                                         throw new InterruptedException(); | ||||
|                                     } | ||||
|                                     catch( Throwable e ) | ||||
|                                     { | ||||
|                                         throw new RuntimeException( e ); | ||||
|                                     } | ||||
|                                 } | ||||
| 
 | ||||
|                                 @Override | ||||
| @@ -448,10 +413,10 @@ public class LuaJLuaMachine implements ILuaMachine | ||||
|                                         Object[] response = pullEvent( "task_complete" ); | ||||
|                                         if( response.length >= 3 && response[ 1 ] instanceof Number && response[ 2 ] instanceof Boolean ) | ||||
|                                         { | ||||
|                                             if( ( (Number)response[ 1 ] ).intValue() == taskID ) | ||||
|                                             if( ((Number) response[ 1 ]).intValue() == taskID ) | ||||
|                                             { | ||||
|                                                 Object[] returnValues = new Object[ response.length - 3 ]; | ||||
|                                                 if( (Boolean)response[ 2 ] ) | ||||
|                                                 if( (Boolean) response[ 2 ] ) | ||||
|                                                 { | ||||
|                                                     // Extract the return values from the event and return them | ||||
|                                                     System.arraycopy( response, 3, returnValues, 0, returnValues.length ); | ||||
| @@ -460,9 +425,9 @@ public class LuaJLuaMachine implements ILuaMachine | ||||
|                                                 else | ||||
|                                                 { | ||||
|                                                     // Extract the error message from the event and raise it | ||||
|                                                     if( response.length >= 4 && response[3] instanceof String ) | ||||
|                                                     if( response.length >= 4 && response[ 3 ] instanceof String ) | ||||
|                                                     { | ||||
|                                                         throw new LuaException( (String)response[ 3 ] ); | ||||
|                                                         throw new LuaException( (String) response[ 3 ] ); | ||||
|                                                     } | ||||
|                                                     else | ||||
|                                                     { | ||||
| @@ -492,7 +457,7 @@ public class LuaJLuaMachine implements ILuaMachine | ||||
|                             } | ||||
|                             throw new LuaError( "Java Exception Thrown: " + t.toString(), 0 ); | ||||
|                         } | ||||
|                         return LuaValue.varargsOf( toValues( results, 0 ) ); | ||||
|                         return toValues( results ); | ||||
|                     } | ||||
|                 } ); | ||||
|             } | ||||
| @@ -500,159 +465,145 @@ public class LuaJLuaMachine implements ILuaMachine | ||||
|         return table; | ||||
|     } | ||||
| 
 | ||||
|     private LuaValue toValue( Object object ) | ||||
|     private LuaValue toValue( Object object, Map<Object, LuaValue> values ) | ||||
|     { | ||||
|         if( object == null ) | ||||
|         { | ||||
|             return LuaValue.NIL; | ||||
|             return Constants.NIL; | ||||
|         } | ||||
|         else if( object instanceof Number ) | ||||
|         { | ||||
|             double d = ((Number)object).doubleValue(); | ||||
|             return LuaValue.valueOf( d ); | ||||
|             double d = ((Number) object).doubleValue(); | ||||
|             return valueOf( d ); | ||||
|         } | ||||
|         else if( object instanceof Boolean ) | ||||
|         { | ||||
|             boolean b = (Boolean) object; | ||||
|             return LuaValue.valueOf( b ); | ||||
|             return valueOf( (Boolean) object ); | ||||
|         } | ||||
|         else if( object instanceof String ) | ||||
|         { | ||||
|             String s = object.toString(); | ||||
|             return LuaValue.valueOf( s ); | ||||
|             return valueOf( s ); | ||||
|         } | ||||
|         else if( object instanceof byte[] ) | ||||
|         { | ||||
|             byte[] b = (byte[]) object; | ||||
|             return LuaValue.valueOf( Arrays.copyOf( b, b.length ) ); | ||||
|             return valueOf( Arrays.copyOf( b, b.length ) ); | ||||
|         } | ||||
|         else if( object instanceof Map ) | ||||
|         { | ||||
|             // Table: | ||||
|             // Start remembering stuff | ||||
|             boolean clearWhenDone = false; | ||||
|             try | ||||
|             if( values == null ) | ||||
|             { | ||||
|                 if( m_valuesInProgress == null ) | ||||
|                 { | ||||
|                     m_valuesInProgress = new IdentityHashMap<>(); | ||||
|                     clearWhenDone = true; | ||||
|                 values = new IdentityHashMap<>(); | ||||
|             } | ||||
|                 else if( m_valuesInProgress.containsKey( object ) ) | ||||
|             else if( values.containsKey( object ) ) | ||||
|             { | ||||
|                     return m_valuesInProgress.get( object ); | ||||
|                 return values.get( object ); | ||||
|             } | ||||
|                 LuaValue table = new LuaTable(); | ||||
|                 m_valuesInProgress.put( object, table ); | ||||
|             LuaTable table = new LuaTable(); | ||||
|             values.put( object, table ); | ||||
| 
 | ||||
|             // Convert all keys | ||||
|             for( Map.Entry<?, ?> pair : ((Map<?, ?>) object).entrySet() ) | ||||
|             { | ||||
|                     LuaValue key = toValue( pair.getKey() ); | ||||
|                     LuaValue value = toValue( pair.getValue() ); | ||||
|                     if( !key.isnil() && !value.isnil() ) | ||||
|                 LuaValue key = toValue( pair.getKey(), values ); | ||||
|                 LuaValue value = toValue( pair.getValue(), values ); | ||||
|                 if( !key.isNil() && !value.isNil() ) | ||||
|                 { | ||||
|                         table.set( key, value ); | ||||
|                     table.rawset( key, value ); | ||||
|                 } | ||||
|             } | ||||
|             return table; | ||||
|         } | ||||
|             finally | ||||
|             { | ||||
|                 // Clear (if exiting top level) | ||||
|                 if( clearWhenDone ) | ||||
|                 { | ||||
|                     m_valuesInProgress = null; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         else if( object instanceof ILuaObject ) | ||||
|         { | ||||
|             return wrapLuaObject( (ILuaObject)object ); | ||||
|             return wrapLuaObject( (ILuaObject) object ); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             return LuaValue.NIL; | ||||
|             return Constants.NIL; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private LuaValue[] toValues( Object[] objects, int leaveEmpty ) | ||||
|     private Varargs toValues( Object[] objects ) | ||||
|     { | ||||
|         if( objects == null || objects.length == 0 ) | ||||
|         { | ||||
|             return new LuaValue[ leaveEmpty ]; | ||||
|             return Constants.NONE; | ||||
|         } | ||||
| 
 | ||||
|         LuaValue[] values = new LuaValue[objects.length + leaveEmpty]; | ||||
|         for( int i=0; i<values.length; ++i ) | ||||
|         LuaValue[] values = new LuaValue[ objects.length ]; | ||||
|         for( int i = 0; i < values.length; ++i ) | ||||
|         { | ||||
|             if( i < leaveEmpty ) | ||||
|             { | ||||
|                 values[i] = null; | ||||
|                 continue; | ||||
|             Object object = objects[ i ]; | ||||
|             values[ i ] = toValue( object, null ); | ||||
|         } | ||||
|             Object object = objects[i - leaveEmpty]; | ||||
|             values[i] = toValue( object ); | ||||
|         } | ||||
|         return values; | ||||
|         return varargsOf( values ); | ||||
|     } | ||||
| 
 | ||||
|     private Object toObject( LuaValue value ) | ||||
|     private static Object toObject( LuaValue value, Map<LuaValue, Object> objects ) | ||||
|     { | ||||
|         switch( value.type() ) | ||||
|         { | ||||
|             case LuaValue.TNIL: | ||||
|             case LuaValue.TNONE:  | ||||
|             case Constants.TNIL: | ||||
|             case Constants.TNONE: | ||||
|             { | ||||
|                 return null; | ||||
|             } | ||||
|             case LuaValue.TINT: | ||||
|             case LuaValue.TNUMBER: | ||||
|             case Constants.TINT: | ||||
|             case Constants.TNUMBER: | ||||
|             { | ||||
|                 return value.todouble(); | ||||
|                 return value.toDouble(); | ||||
|             } | ||||
|             case LuaValue.TBOOLEAN: | ||||
|             case Constants.TBOOLEAN: | ||||
|             { | ||||
|                 return value.toboolean(); | ||||
|                 return value.toBoolean(); | ||||
|             } | ||||
|             case LuaValue.TSTRING: | ||||
|             case Constants.TSTRING: | ||||
|             { | ||||
|                 LuaString str = value.checkstring(); | ||||
|                 return str.tojstring(); | ||||
|                 return value.toString(); | ||||
|             } | ||||
|             case LuaValue.TTABLE: | ||||
|             case Constants.TTABLE: | ||||
|             { | ||||
|                 // Table: | ||||
|                 boolean clearWhenDone = false; | ||||
|                 try | ||||
|                 { | ||||
|                 // Start remembering stuff | ||||
|                     if( m_objectsInProgress == null ) | ||||
|                 if( objects == null ) | ||||
|                 { | ||||
|                         m_objectsInProgress = new IdentityHashMap<>(); | ||||
|                         clearWhenDone = true; | ||||
|                     objects = new IdentityHashMap<>(); | ||||
|                 } | ||||
|                     else if( m_objectsInProgress.containsKey( value ) ) | ||||
|                 else if( objects.containsKey( value ) ) | ||||
|                 { | ||||
|                         return m_objectsInProgress.get( value ); | ||||
|                     return objects.get( value ); | ||||
|                 } | ||||
|                 Map<Object, Object> table = new HashMap<>(); | ||||
|                     m_objectsInProgress.put( value, table ); | ||||
|                 objects.put( value, table ); | ||||
| 
 | ||||
|                 LuaTable luaTable = (LuaTable) value; | ||||
| 
 | ||||
|                 // Convert all keys | ||||
|                     LuaValue k = LuaValue.NIL; | ||||
|                 LuaValue k = Constants.NIL; | ||||
|                 while( true ) | ||||
|                 { | ||||
|                         Varargs keyValue = value.next( k ); | ||||
|                         k = keyValue.arg1(); | ||||
|                         if( k.isnil() ) | ||||
|                     Varargs keyValue; | ||||
|                     try | ||||
|                     { | ||||
|                         keyValue = luaTable.next( k ); | ||||
|                     } | ||||
|                     catch( LuaError luaError ) | ||||
|                     { | ||||
|                         break; | ||||
|                     } | ||||
|                     k = keyValue.first(); | ||||
|                     if( k.isNil() ) | ||||
|                     { | ||||
|                         break; | ||||
|                     } | ||||
| 
 | ||||
|                         LuaValue v = keyValue.arg(2); | ||||
|                         Object keyObject = toObject(k); | ||||
|                         Object valueObject = toObject(v); | ||||
|                     LuaValue v = keyValue.arg( 2 ); | ||||
|                     Object keyObject = toObject( k, objects ); | ||||
|                     Object valueObject = toObject( v, objects ); | ||||
|                     if( keyObject != null && valueObject != null ) | ||||
|                     { | ||||
|                         table.put( keyObject, valueObject ); | ||||
| @@ -660,15 +611,6 @@ public class LuaJLuaMachine implements ILuaMachine | ||||
|                 } | ||||
|                 return table; | ||||
|             } | ||||
|                 finally | ||||
|                 { | ||||
|                     // Clear (if exiting top level) | ||||
|                     if( clearWhenDone ) | ||||
|                     { | ||||
|                         m_objectsInProgress = null; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             default: | ||||
|             { | ||||
|                 return null; | ||||
| @@ -676,15 +618,15 @@ public class LuaJLuaMachine implements ILuaMachine | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private Object[] toObjects( Varargs values, int startIdx ) | ||||
|     private static Object[] toObjects( Varargs values, int startIdx ) | ||||
|     { | ||||
|         int count = values.narg(); | ||||
|         int count = values.count(); | ||||
|         Object[] objects = new Object[ count - startIdx + 1 ]; | ||||
|         for( int n=startIdx; n<=count; ++n ) | ||||
|         for( int n = startIdx; n <= count; ++n ) | ||||
|         { | ||||
|             int i = n - startIdx; | ||||
|             LuaValue value = values.arg(n); | ||||
|             objects[i] = toObject( value ); | ||||
|             LuaValue value = values.arg( n ); | ||||
|             objects[ i ] = toObject( value, null ); | ||||
|         } | ||||
|         return objects; | ||||
|     } | ||||
		Reference in New Issue
	
	Block a user
	 SquidDev
					SquidDev