Additional support for arrays in luajava library.
This commit is contained in:
@@ -21,17 +21,19 @@
|
|||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
package org.luaj.lib.j2se;
|
package org.luaj.lib.j2se;
|
||||||
|
|
||||||
|
import java.lang.reflect.Array;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.luaj.vm.LBoolean;
|
import org.luaj.vm.LBoolean;
|
||||||
import org.luaj.vm.LDouble;
|
import org.luaj.vm.LDouble;
|
||||||
import org.luaj.vm.LInteger;
|
import org.luaj.vm.LInteger;
|
||||||
import org.luaj.vm.LNil;
|
|
||||||
import org.luaj.vm.LNumber;
|
import org.luaj.vm.LNumber;
|
||||||
import org.luaj.vm.LString;
|
import org.luaj.vm.LString;
|
||||||
|
import org.luaj.vm.LTable;
|
||||||
import org.luaj.vm.LUserData;
|
import org.luaj.vm.LUserData;
|
||||||
import org.luaj.vm.LValue;
|
import org.luaj.vm.LValue;
|
||||||
|
import org.luaj.vm.LuaErrorException;
|
||||||
|
|
||||||
|
|
||||||
public class CoerceLuaToJava {
|
public class CoerceLuaToJava {
|
||||||
@@ -196,14 +198,56 @@ public class CoerceLuaToJava {
|
|||||||
COERCIONS.put( String.class, stringCoercion );
|
COERCIONS.put( String.class, stringCoercion );
|
||||||
COERCIONS.put( Object.class, objectCoercion );
|
COERCIONS.put( Object.class, objectCoercion );
|
||||||
}
|
}
|
||||||
|
|
||||||
static Object coerceArg(LValue v, Class type) {
|
|
||||||
Coercion co = (Coercion) COERCIONS.get( type );
|
/** Score a single parameter, including array handling */
|
||||||
if ( co != null )
|
private static int scoreParam(LValue a, Class c) {
|
||||||
return co.coerce( v );
|
if ( a instanceof LUserData ) {
|
||||||
if ( v instanceof LUserData )
|
Object o = ((LUserData) a).m_instance;
|
||||||
return ((LUserData) v).m_instance;
|
if ( c.isAssignableFrom(o.getClass()) )
|
||||||
return v;
|
return 0;
|
||||||
|
}
|
||||||
|
Coercion co = (Coercion) COERCIONS.get( c );
|
||||||
|
if ( co != null ) {
|
||||||
|
return co.score( a );
|
||||||
|
}
|
||||||
|
if ( c.isArray() ) {
|
||||||
|
Class typ = c.getComponentType();
|
||||||
|
if ( a instanceof LTable ) {
|
||||||
|
return scoreParam( ((LTable)a).get(1), typ );
|
||||||
|
} else {
|
||||||
|
return 0x10 + (scoreParam(a, typ) << 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0x1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Do a conversion */
|
||||||
|
public static Object coerceArg(LValue a, Class c) {
|
||||||
|
if ( a instanceof LUserData ) {
|
||||||
|
Object o = ((LUserData) a).m_instance;
|
||||||
|
if ( c.isAssignableFrom(o.getClass()) )
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
Coercion co = (Coercion) COERCIONS.get( c );
|
||||||
|
if ( co != null ) {
|
||||||
|
return co.coerce( a );
|
||||||
|
}
|
||||||
|
if ( c.isArray() ) {
|
||||||
|
boolean istable = (a instanceof LTable);
|
||||||
|
int n = istable? a.luaLength(): 1;
|
||||||
|
Class typ = c.getComponentType();
|
||||||
|
Object o = Array.newInstance(typ, n);
|
||||||
|
for ( int i=0; i<n; i++ ) {
|
||||||
|
LValue ele = (istable? ((LTable)a).get(i+1): a);
|
||||||
|
if ( ele != null )
|
||||||
|
Array.set(o, i, coerceArg(ele, typ));
|
||||||
|
}
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
if ( a.isNil() )
|
||||||
|
return null;
|
||||||
|
throw new LuaErrorException("no coercion found for "+a.getClass()+" to "+c);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Object[] coerceArgs(LValue[] suppliedArgs, Class[] parameterTypes) {
|
static Object[] coerceArgs(LValue[] suppliedArgs, Class[] parameterTypes) {
|
||||||
@@ -223,23 +267,15 @@ public class CoerceLuaToJava {
|
|||||||
* 3) java has less args
|
* 3) java has less args
|
||||||
* 4) types coerce well
|
* 4) types coerce well
|
||||||
*/
|
*/
|
||||||
static int scoreParamTypes(LValue[] suppliedArgs, Class[] paramTypes) {
|
public static int scoreParamTypes(LValue[] suppliedArgs, Class[] paramTypes) {
|
||||||
int nargs = suppliedArgs.length;
|
int nargs = suppliedArgs.length;
|
||||||
int njava = paramTypes.length;
|
int njava = paramTypes.length;
|
||||||
int score = (njava == nargs? 0: njava > nargs? 0x4000: 0x8000);
|
int score = (njava == nargs? 0: njava > nargs? 0x4000: 0x8000);
|
||||||
for ( int i=0; i<nargs && i<njava; i++ ) {
|
for ( int i=0; i<nargs && i<njava; i++ ) {
|
||||||
LValue a = suppliedArgs[i];
|
LValue a = suppliedArgs[i];
|
||||||
Class c = paramTypes[i];
|
Class c = paramTypes[i];
|
||||||
Coercion co = (Coercion) COERCIONS.get( c );
|
int s = scoreParam( a, c );
|
||||||
if ( co != null ) {
|
score += s;
|
||||||
score += co.score( a );
|
|
||||||
} else if ( a instanceof LUserData ) {
|
|
||||||
Object o = ((LUserData) a).m_instance;
|
|
||||||
if ( ! c.isAssignableFrom(o.getClass()) )
|
|
||||||
score += 0x10000;
|
|
||||||
} else {
|
|
||||||
score += 0x100;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ package org.luaj.lib.j2se;
|
|||||||
*
|
*
|
||||||
* TODO: coerce types on way in and out, pick method base on arg count ant types.
|
* TODO: coerce types on way in and out, pick method base on arg count ant types.
|
||||||
*/
|
*/
|
||||||
|
import java.lang.reflect.Array;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.InvocationHandler;
|
import java.lang.reflect.InvocationHandler;
|
||||||
@@ -38,7 +39,7 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.luaj.vm.LFunction;
|
import org.luaj.vm.LFunction;
|
||||||
import org.luaj.vm.LNil;
|
import org.luaj.vm.LInteger;
|
||||||
import org.luaj.vm.LString;
|
import org.luaj.vm.LString;
|
||||||
import org.luaj.vm.LTable;
|
import org.luaj.vm.LTable;
|
||||||
import org.luaj.vm.LUserData;
|
import org.luaj.vm.LUserData;
|
||||||
@@ -194,6 +195,7 @@ public final class LuajavaLib extends LFunction {
|
|||||||
public final LValue[] values;
|
public final LValue[] values;
|
||||||
public final Class[] classes;
|
public final Class[] classes;
|
||||||
public int hash;
|
public int hash;
|
||||||
|
public boolean cantcache;
|
||||||
ParamsList( LuaState vm ) {
|
ParamsList( LuaState vm ) {
|
||||||
int n = Math.max(vm.gettop()-2,0);
|
int n = Math.max(vm.gettop()-2,0);
|
||||||
values = new LValue[n];
|
values = new LValue[n];
|
||||||
@@ -202,6 +204,9 @@ public final class LuajavaLib extends LFunction {
|
|||||||
values[i] = vm.topointer(i-n);
|
values[i] = vm.topointer(i-n);
|
||||||
classes[i] = values[i].getClass();
|
classes[i] = values[i].getClass();
|
||||||
hash += classes[i].hashCode();
|
hash += classes[i].hashCode();
|
||||||
|
Class c = classes[i];
|
||||||
|
if ( values[i] instanceof LUserData || values[i] instanceof LTable )
|
||||||
|
cantcache = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
@@ -213,8 +218,10 @@ public final class LuajavaLib extends LFunction {
|
|||||||
false;
|
false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static LString LENGTH = LString.valueOf("length");
|
||||||
|
|
||||||
static LUserData toUserdata(Object instance, final Class clazz) {
|
static LUserData toUserdata(final Object instance, final Class clazz) {
|
||||||
LTable mt = (LTable) classMetatables.get(clazz);
|
LTable mt = (LTable) classMetatables.get(clazz);
|
||||||
if ( mt == null ) {
|
if ( mt == null ) {
|
||||||
mt = new LTable();
|
mt = new LTable();
|
||||||
@@ -222,6 +229,17 @@ public final class LuajavaLib extends LFunction {
|
|||||||
public boolean luaStackCall(LuaState vm) {
|
public boolean luaStackCall(LuaState vm) {
|
||||||
LValue table = vm.topointer(2);
|
LValue table = vm.topointer(2);
|
||||||
LValue key = vm.topointer(3);
|
LValue key = vm.topointer(3);
|
||||||
|
if ( key instanceof LInteger ) {
|
||||||
|
if ( clazz.isArray() ) {
|
||||||
|
vm.resettop();
|
||||||
|
int index = key.toJavaInt()-1;
|
||||||
|
if ( index >= 0 && index < Array.getLength(instance) )
|
||||||
|
vm.pushlvalue( CoerceJavaToLua.coerce( Array.get(instance, index) ) );
|
||||||
|
else
|
||||||
|
vm.pushnil();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
final String s = key.toJavaString();
|
final String s = key.toJavaString();
|
||||||
vm.resettop();
|
vm.resettop();
|
||||||
try {
|
try {
|
||||||
@@ -229,7 +247,11 @@ public final class LuajavaLib extends LFunction {
|
|||||||
Object o = f.get(table.toJavaInstance());
|
Object o = f.get(table.toJavaInstance());
|
||||||
vm.pushlvalue( CoerceJavaToLua.coerce( o ) );
|
vm.pushlvalue( CoerceJavaToLua.coerce( o ) );
|
||||||
} catch (NoSuchFieldException nsfe) {
|
} catch (NoSuchFieldException nsfe) {
|
||||||
vm.pushlvalue( new LMethod(clazz,s) );
|
if ( clazz.isArray() && key.equals(LENGTH) ) {
|
||||||
|
vm.pushinteger( Array.getLength(instance) );
|
||||||
|
} else {
|
||||||
|
vm.pushlvalue( new LMethod(clazz,s) );
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new LuaErrorException(e);
|
throw new LuaErrorException(e);
|
||||||
}
|
}
|
||||||
@@ -241,6 +263,19 @@ public final class LuajavaLib extends LFunction {
|
|||||||
LValue table = vm.topointer(2);
|
LValue table = vm.topointer(2);
|
||||||
LValue key = vm.topointer(3);
|
LValue key = vm.topointer(3);
|
||||||
LValue val = vm.topointer(4);
|
LValue val = vm.topointer(4);
|
||||||
|
if ( key instanceof LInteger ) {
|
||||||
|
if ( clazz.isArray() ) {
|
||||||
|
vm.resettop();
|
||||||
|
Object v = CoerceLuaToJava.coerceArg(val, clazz.getComponentType());
|
||||||
|
int index = key.toJavaInt()-1;
|
||||||
|
if ( index >= 0 && index < Array.getLength(instance) )
|
||||||
|
Array.set(instance, key.toJavaInt()-1, v);
|
||||||
|
else
|
||||||
|
throw new LuaErrorException("array bounds exceeded "+index);
|
||||||
|
vm.resettop();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
String s = key.toJavaString();
|
String s = key.toJavaString();
|
||||||
try {
|
try {
|
||||||
Field f = clazz.getField(s);
|
Field f = clazz.getField(s);
|
||||||
@@ -342,7 +377,8 @@ public final class LuajavaLib extends LFunction {
|
|||||||
|
|
||||||
// put into cache
|
// put into cache
|
||||||
c = (Constructor) list.get(besti);
|
c = (Constructor) list.get(besti);
|
||||||
cache.put( params, c );
|
if ( ! params.cantcache )
|
||||||
|
cache.put( params, c );
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -396,6 +432,15 @@ public final class LuajavaLib extends LFunction {
|
|||||||
if ( list == null )
|
if ( list == null )
|
||||||
throw new IllegalArgumentException("no method named '"+methodName+"' with "+n+" args");
|
throw new IllegalArgumentException("no method named '"+methodName+"' with "+n+" args");
|
||||||
|
|
||||||
|
// trivial lists match
|
||||||
|
if ( list.size() == 1 ) {
|
||||||
|
m = (Method) list.get(0);
|
||||||
|
if ( ! params.cantcache )
|
||||||
|
cache.put( params, m );
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// find constructor with best score
|
// find constructor with best score
|
||||||
int bests = Integer.MAX_VALUE;
|
int bests = Integer.MAX_VALUE;
|
||||||
int besti = 0;
|
int besti = 0;
|
||||||
@@ -410,7 +455,8 @@ public final class LuajavaLib extends LFunction {
|
|||||||
|
|
||||||
// put into cache
|
// put into cache
|
||||||
m = (Method) list.get(besti);
|
m = (Method) list.get(besti);
|
||||||
cache.put( params, m );
|
if ( ! params.cantcache )
|
||||||
|
cache.put( params, m );
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
69
src/sample/org/luaj/sample/SampleUserdataMain.java
Normal file
69
src/sample/org/luaj/sample/SampleUserdataMain.java
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
package org.luaj.sample;
|
||||||
|
import org.luaj.lib.j2se.CoerceJavaToLua;
|
||||||
|
import org.luaj.platform.*;
|
||||||
|
import org.luaj.vm.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Program that illustrates how userdata is mapped into lua using
|
||||||
|
* LuaJava's automated coercion
|
||||||
|
*/
|
||||||
|
public class SampleUserdataMain {
|
||||||
|
|
||||||
|
public static class MyData {
|
||||||
|
public int x = 7;
|
||||||
|
public String y = "seven";
|
||||||
|
public int xx[] = new int[] { 11, 22, 33, };
|
||||||
|
public String yy[] = new String[] { "aa", "bb" };
|
||||||
|
public int xxx[][] = new int[][] { {444, 555}, {666, 777} } ;
|
||||||
|
public String yyy[][] = new String[][] { { "ccc", "ddd" }, { "eee", "fff" } };
|
||||||
|
public void initScalars( int newx, String newy ) {
|
||||||
|
x = newx;
|
||||||
|
y = newy;
|
||||||
|
}
|
||||||
|
public void initArrays( int[] newxx, String[] newyy ) {
|
||||||
|
xx = newxx;
|
||||||
|
yy = newyy;
|
||||||
|
}
|
||||||
|
public void initMatrices( int[][] newxxx, String[][] newyyy ) {
|
||||||
|
xxx = newxxx;
|
||||||
|
yyy = newyyy;
|
||||||
|
}
|
||||||
|
public int getx() { return x; }
|
||||||
|
public String gety() { return y; }
|
||||||
|
public int[] getxx() { return xx; }
|
||||||
|
public String[] getyy() { return yy; }
|
||||||
|
public int[][] getxxx() { return xxx; }
|
||||||
|
public String[][] getyyy() { return yyy; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
Platform.setInstance( new J2sePlatform() );
|
||||||
|
LuaState vm = Platform.newLuaState();
|
||||||
|
org.luaj.compiler.LuaC.install();
|
||||||
|
|
||||||
|
// test script
|
||||||
|
vm.getglobal( "loadstring" );
|
||||||
|
vm.pushstring( "local mydata = ...\n" +
|
||||||
|
"print( 'mydata', mydata )\n" +
|
||||||
|
"print( 'mydata.x, mydata.y', mydata.x, mydata.y )\n" +
|
||||||
|
"print( 'mydata:getx()', mydata:getx() )\n" +
|
||||||
|
"print( 'mydata:getxx()', mydata:getxx()[1], mydata:getxx()[2] )\n" +
|
||||||
|
"print( 'mydata:getxxx()', mydata:getxxx()[1][1], mydata:getxxx()[1][2] )\n" +
|
||||||
|
"print( 'mydata:getyyy()', mydata:getyyy()[1][1], mydata:getyyy()[1][2] )\n" +
|
||||||
|
"mydata:initScalars(3,'pqr')\n" +
|
||||||
|
"mydata:initArrays({55,66},{'abc','def'})\n" +
|
||||||
|
"mydata:initMatrices({{44,55},{66}},{{'qq','rr'},{'ss','tt'}})\n" +
|
||||||
|
"print( 'mydata:getx()', mydata:getx() )\n" +
|
||||||
|
"print( 'mydata:getxx()', mydata:getxx()[1], mydata:getxx()[2] )\n" +
|
||||||
|
"print( 'mydata:getxxx()', mydata:getxxx()[1][1], mydata:getxxx()[1][2] )\n" +
|
||||||
|
"print( 'mydata:getyyy()', mydata:getyyy()[1][1], mydata:getyyy()[1][2] )\n" +
|
||||||
|
"");
|
||||||
|
vm.call( 1, 2 );
|
||||||
|
System.out.println("load result: "+vm.tostring(-2)+", "+vm.tostring(-1));
|
||||||
|
vm.settop(1);
|
||||||
|
|
||||||
|
// load argument to test script
|
||||||
|
vm.pushlvalue( CoerceJavaToLua.coerce(new MyData()) );
|
||||||
|
vm.call( 1, 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
187
src/test/java/org/luaj/vm/LuaJavaCoercionTest.java
Normal file
187
src/test/java/org/luaj/vm/LuaJavaCoercionTest.java
Normal file
@@ -0,0 +1,187 @@
|
|||||||
|
package org.luaj.vm;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
import org.luaj.lib.j2se.CoerceJavaToLua;
|
||||||
|
import org.luaj.lib.j2se.CoerceLuaToJava;
|
||||||
|
import org.luaj.platform.J2sePlatform;
|
||||||
|
|
||||||
|
public class LuaJavaCoercionTest extends TestCase {
|
||||||
|
|
||||||
|
private LuaState vm;
|
||||||
|
private static LInteger ZERO = LInteger.valueOf(0);
|
||||||
|
private static LInteger ONE = LInteger.valueOf(1);
|
||||||
|
private static LInteger TWO = LInteger.valueOf(2);
|
||||||
|
private static LInteger THREE = LInteger.valueOf(3);
|
||||||
|
private static LString LENGTH = LString.valueOf("length");
|
||||||
|
|
||||||
|
protected void setUp() throws Exception {
|
||||||
|
super.setUp();
|
||||||
|
Platform.setInstance( new J2sePlatform() );
|
||||||
|
org.luaj.compiler.LuaC.install();
|
||||||
|
vm = Platform.newLuaState();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testJavaIntToLuaInt() {
|
||||||
|
Integer i = Integer.valueOf(777);
|
||||||
|
LValue v = CoerceJavaToLua.coerce(i);
|
||||||
|
assertEquals( LInteger.class, v.getClass() );
|
||||||
|
assertEquals( 777, v.toJavaInt() );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testLuaIntToJavaInt() {
|
||||||
|
LInteger i = LInteger.valueOf(777);
|
||||||
|
Object o = CoerceLuaToJava.coerceArg(i, int.class);
|
||||||
|
assertEquals( Integer.class, o.getClass() );
|
||||||
|
assertEquals( 777, ((Number)o).intValue() );
|
||||||
|
o = CoerceLuaToJava.coerceArg(i, Integer.class);
|
||||||
|
assertEquals( Integer.class, o.getClass() );
|
||||||
|
assertEquals( new Integer(777), o );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testJavaStringToLuaString() {
|
||||||
|
String s = new String("777");
|
||||||
|
LValue v = CoerceJavaToLua.coerce(s);
|
||||||
|
assertEquals( LString.class, v.getClass() );
|
||||||
|
assertEquals( "777", v.toJavaString() );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testLuaStringToJavaString() {
|
||||||
|
LString s = new LString("777");
|
||||||
|
Object o = CoerceLuaToJava.coerceArg(s, String.class);
|
||||||
|
assertEquals( String.class, o.getClass() );
|
||||||
|
assertEquals( "777", o );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testJavaIntArrayToLuaTable() {
|
||||||
|
int[] i = { 222, 333 };
|
||||||
|
LValue v = CoerceJavaToLua.coerce(i);
|
||||||
|
assertEquals( LUserData.class, v.getClass() );
|
||||||
|
assertNotNull( v.luaGetMetatable() );
|
||||||
|
assertEquals( LInteger.valueOf(222), v.luaGetTable(vm, ONE) );
|
||||||
|
assertEquals( LInteger.valueOf(333), v.luaGetTable(vm, TWO) );
|
||||||
|
assertEquals( TWO, v.luaGetTable(vm, LENGTH));
|
||||||
|
assertEquals( LNil.NIL, v.luaGetTable(vm, THREE) );
|
||||||
|
assertEquals( LNil.NIL, v.luaGetTable(vm, ZERO) );
|
||||||
|
v.luaSetTable(vm, ONE, LInteger.valueOf(444));
|
||||||
|
v.luaSetTable(vm, TWO, LInteger.valueOf(555));
|
||||||
|
assertEquals( 444, i[0] );
|
||||||
|
assertEquals( 555, i[1] );
|
||||||
|
assertEquals( LInteger.valueOf(444), v.luaGetTable(vm, ONE) );
|
||||||
|
assertEquals( LInteger.valueOf(555), v.luaGetTable(vm, TWO) );
|
||||||
|
try {
|
||||||
|
v.luaSetTable(vm, ZERO, LInteger.valueOf(777));
|
||||||
|
fail( "array bound exception not thrown" );
|
||||||
|
} catch ( LuaErrorException lee ) {
|
||||||
|
// expected
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
v.luaSetTable(vm, THREE, LInteger.valueOf(777));
|
||||||
|
fail( "array bound exception not thrown" );
|
||||||
|
} catch ( LuaErrorException lee ) {
|
||||||
|
// expected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testLuaTableToJavaIntArray() {
|
||||||
|
LTable t = new LTable();
|
||||||
|
t.put(1, LInteger.valueOf(222) );
|
||||||
|
t.put(2, LInteger.valueOf(333) );
|
||||||
|
int[] i = null;
|
||||||
|
Object o = CoerceLuaToJava.coerceArg(t, int[].class);
|
||||||
|
assertEquals( int[].class, o.getClass() );
|
||||||
|
i = (int[]) o;
|
||||||
|
assertEquals( 2, i.length );
|
||||||
|
assertEquals( 222, i[0] );
|
||||||
|
assertEquals( 333, i[1] );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void testArrayParamScoring() {
|
||||||
|
int a = 5;
|
||||||
|
int[] b = { 44, 66 };
|
||||||
|
int[][] c = { { 11, 22 }, { 33, 44 } };
|
||||||
|
LValue la = LInteger.valueOf(a);
|
||||||
|
LTable tb = new LTable();
|
||||||
|
LTable tc = new LTable();
|
||||||
|
LValue va = CoerceJavaToLua.coerce(a);
|
||||||
|
LValue vb = CoerceJavaToLua.coerce(b);
|
||||||
|
LValue vc = CoerceJavaToLua.coerce(c);
|
||||||
|
tc.put( ONE, new LTable() );
|
||||||
|
|
||||||
|
int saa = CoerceLuaToJava.scoreParamTypes( new LValue[] { la }, new Class[] { int.class } );
|
||||||
|
int sab = CoerceLuaToJava.scoreParamTypes( new LValue[] { la }, new Class[] { int[].class } );
|
||||||
|
int sac = CoerceLuaToJava.scoreParamTypes( new LValue[] { la }, new Class[] { int[][].class } );
|
||||||
|
assertTrue( saa < sab );
|
||||||
|
assertTrue( saa < sac );
|
||||||
|
int sba = CoerceLuaToJava.scoreParamTypes( new LValue[] { tb }, new Class[] { int.class } );
|
||||||
|
int sbb = CoerceLuaToJava.scoreParamTypes( new LValue[] { tb }, new Class[] { int[].class } );
|
||||||
|
int sbc = CoerceLuaToJava.scoreParamTypes( new LValue[] { tb }, new Class[] { int[][].class } );
|
||||||
|
assertTrue( sbb < sba );
|
||||||
|
assertTrue( sbb < sbc );
|
||||||
|
int sca = CoerceLuaToJava.scoreParamTypes( new LValue[] { tc }, new Class[] { int.class } );
|
||||||
|
int scb = CoerceLuaToJava.scoreParamTypes( new LValue[] { tc }, new Class[] { int[].class } );
|
||||||
|
int scc = CoerceLuaToJava.scoreParamTypes( new LValue[] { tc }, new Class[] { int[][].class } );
|
||||||
|
assertTrue( scc < sca );
|
||||||
|
assertTrue( scc < scb );
|
||||||
|
|
||||||
|
int vaa = CoerceLuaToJava.scoreParamTypes( new LValue[] { va }, new Class[] { int.class } );
|
||||||
|
int vab = CoerceLuaToJava.scoreParamTypes( new LValue[] { va }, new Class[] { int[].class } );
|
||||||
|
int vac = CoerceLuaToJava.scoreParamTypes( new LValue[] { va }, new Class[] { int[][].class } );
|
||||||
|
assertTrue( vaa < vab );
|
||||||
|
assertTrue( vaa < vac );
|
||||||
|
int vba = CoerceLuaToJava.scoreParamTypes( new LValue[] { vb }, new Class[] { int.class } );
|
||||||
|
int vbb = CoerceLuaToJava.scoreParamTypes( new LValue[] { vb }, new Class[] { int[].class } );
|
||||||
|
int vbc = CoerceLuaToJava.scoreParamTypes( new LValue[] { vb }, new Class[] { int[][].class } );
|
||||||
|
assertTrue( vbb < vba );
|
||||||
|
assertTrue( vbb < vbc );
|
||||||
|
int vca = CoerceLuaToJava.scoreParamTypes( new LValue[] { vc }, new Class[] { int.class } );
|
||||||
|
int vcb = CoerceLuaToJava.scoreParamTypes( new LValue[] { vc }, new Class[] { int[].class } );
|
||||||
|
int vcc = CoerceLuaToJava.scoreParamTypes( new LValue[] { vc }, new Class[] { int[][].class } );
|
||||||
|
assertTrue( vcc < vca );
|
||||||
|
assertTrue( vcc < vcb );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class SampleClass {
|
||||||
|
public String sample() { return "void-args"; }
|
||||||
|
public String sample(int a) { return "int-args "+a; }
|
||||||
|
public String sample(int[] a) { return "int-array-args "+a[0]+","+a[1]; }
|
||||||
|
public String sample(int[][] a) { return "int-array-array-args "+a[0][0]+","+a[0][1]+","+a[1][0]+","+a[1][1]; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final LString SAMPLE = LString.valueOf("sample");
|
||||||
|
|
||||||
|
public void testIntArrayParameterMatching() {
|
||||||
|
LValue v = CoerceJavaToLua.coerce(new SampleClass());
|
||||||
|
|
||||||
|
// get sample field, call with no arguments
|
||||||
|
LValue method = v.luaGetTable(vm, SAMPLE);
|
||||||
|
vm.pushlvalue(method);
|
||||||
|
vm.pushlvalue(v);
|
||||||
|
vm.call(1,1);
|
||||||
|
assertEquals( "void-args", vm.tostring(-1) );
|
||||||
|
|
||||||
|
// get sample field, call with no arguments
|
||||||
|
vm.pushlvalue(method);
|
||||||
|
vm.pushlvalue(v);
|
||||||
|
vm.pushlvalue( CoerceJavaToLua.coerce(new Integer(123)));
|
||||||
|
vm.call(2,1);
|
||||||
|
assertEquals( "int-args 123", vm.tostring(-1) );
|
||||||
|
|
||||||
|
// get sample field, call with no arguments
|
||||||
|
vm.pushlvalue(method);
|
||||||
|
vm.pushlvalue(v);
|
||||||
|
vm.pushlvalue( CoerceJavaToLua.coerce(new int[]{345,678}) );
|
||||||
|
vm.call(2,1);
|
||||||
|
assertEquals( "int-array-args 345,678", vm.tostring(-1) );
|
||||||
|
|
||||||
|
// get sample field, call with no arguments
|
||||||
|
vm.pushlvalue(method);
|
||||||
|
vm.pushlvalue(v);
|
||||||
|
vm.pushlvalue( CoerceJavaToLua.coerce(new int[][]{{22,33},{44,55}}) );
|
||||||
|
vm.call(2,1);
|
||||||
|
assertEquals( "int-array-array-args 22,33,44,55", vm.tostring(-1) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user