comparison src/luan/LuaJavaFunction.java @ 21:c93d8c781853

add functions git-svn-id: https://luan-java.googlecode.com/svn/trunk@22 21e917c8-12df-6dd8-5cb6-c86387c605b9
author fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
date Tue, 04 Dec 2012 09:16:03 +0000
parents 9cea1aea5eef
children 8a57ebfdfd78
comparison
equal deleted inserted replaced
20:d85510d92eee 21:c93d8c781853
7 7
8 public final class LuaJavaFunction extends LuaFunction { 8 public final class LuaJavaFunction extends LuaFunction {
9 private final Method method; 9 private final Method method;
10 private final Object obj; 10 private final Object obj;
11 private final RtnConverter rtnConverter; 11 private final RtnConverter rtnConverter;
12 private final boolean takesLuaState;
12 private final ArgConverter[] argConverters; 13 private final ArgConverter[] argConverters;
13 private final Class<?> varArgCls; 14 private final Class<?> varArgCls;
14 15
15 public LuaJavaFunction(Method method,Object obj) { 16 public LuaJavaFunction(Method method,Object obj) {
16 this.method = method; 17 this.method = method;
17 this.obj = obj; 18 this.obj = obj;
18 this.rtnConverter = getRtnConverter(method); 19 this.rtnConverter = getRtnConverter(method);
19 this.argConverters = getArgConverters(method); 20 this.takesLuaState = takesLuaState(method);
21 this.argConverters = getArgConverters(takesLuaState,method);
20 if( method.isVarArgs() ) { 22 if( method.isVarArgs() ) {
21 Class<?>[] paramTypes = method.getParameterTypes(); 23 Class<?>[] paramTypes = method.getParameterTypes();
22 this.varArgCls = paramTypes[paramTypes.length-1].getComponentType(); 24 this.varArgCls = paramTypes[paramTypes.length-1].getComponentType();
23 } else { 25 } else {
24 this.varArgCls = null; 26 this.varArgCls = null;
25 } 27 }
26 } 28 }
27 29
28 @Override public Object[] call(LuaState lua,Object... args) { 30 @Override public Object[] call(LuaState lua,Object... args) {
29 args = fixArgs(args); 31 args = fixArgs(lua,args);
30 Object rtn; 32 Object rtn;
31 try { 33 try {
32 rtn = method.invoke(obj,args); 34 rtn = method.invoke(obj,args);
33 } catch(IllegalAccessException e) { 35 } catch(IllegalAccessException e) {
34 throw new RuntimeException(e); 36 throw new RuntimeException(e);
36 throw new RuntimeException(e); 38 throw new RuntimeException(e);
37 } 39 }
38 return rtnConverter.convert(rtn); 40 return rtnConverter.convert(rtn);
39 } 41 }
40 42
41 private Object[] fixArgs(Object[] args) { 43 private Object[] fixArgs(LuaState lua,Object[] args) {
42 if( varArgCls==null ) { 44 int n = argConverters.length;
43 if( args.length != argConverters.length ) { 45 Object[] rtn;
44 Object[] t = new Object[argConverters.length]; 46 int start = 0;
45 System.arraycopy(args,0,t,0,Math.min(args.length,t.length)); 47 if( !takesLuaState && varArgCls==null && args.length == n ) {
46 args = t; 48 rtn = args;
47 } 49 } else {
48 for( int i=0; i<args.length; i++ ) { 50 if( takesLuaState )
49 args[i] = argConverters[i].convert(args[i]); 51 n++;
50 } 52 rtn = new Object[n];
51 return args; 53 if( takesLuaState ) {
52 } else { // varargs 54 rtn[start++] = lua;
53 Object[] rtn = new Object[argConverters.length]; 55 }
54 int n = argConverters.length - 1; 56 n = argConverters.length;
55 if( args.length < argConverters.length ) { 57 if( varArgCls != null ) {
56 System.arraycopy(args,0,rtn,0,args.length); 58 n--;
57 rtn[rtn.length-1] = Array.newInstance(varArgCls,0); 59 if( args.length < argConverters.length ) {
58 } else { 60 rtn[rtn.length-1] = Array.newInstance(varArgCls,0);
59 System.arraycopy(args,0,rtn,0,n); 61 } else {
60 Object[] varArgs = (Object[])Array.newInstance(varArgCls,args.length-n); 62 Object[] varArgs = (Object[])Array.newInstance(varArgCls,args.length-n);
61 ArgConverter ac = argConverters[n]; 63 ArgConverter ac = argConverters[n];
62 for( int i=0; i<varArgs.length; i++ ) { 64 for( int i=0; i<varArgs.length; i++ ) {
63 varArgs[i] = ac.convert(args[n+i]); 65 varArgs[i] = ac.convert(args[n+i]);
66 }
67 rtn[rtn.length-1] = varArgs;
64 } 68 }
65 rtn[rtn.length-1] = varArgs; 69 }
66 } 70 System.arraycopy(args,0,rtn,start,Math.min(args.length,n));
67 for( int i=0; i<n; i++ ) { 71 }
68 rtn[i] = argConverters[i].convert(rtn[i]); 72 for( int i=0; i<n; i++ ) {
69 } 73 rtn[start+i] = argConverters[i].convert(rtn[start+i]);
70 return rtn; 74 }
71 } 75 return rtn;
72 } 76 }
73 77
74 78
75 private interface RtnConverter { 79 private interface RtnConverter {
76 public Object[] convert(Object obj); 80 public Object[] convert(Object obj);
216 } 220 }
217 return obj; 221 return obj;
218 } 222 }
219 }; 223 };
220 224
221 private static ArgConverter[] getArgConverters(Method m) { 225 private static boolean takesLuaState(Method m) {
226 Class<?>[] paramTypes = m.getParameterTypes();
227 return paramTypes.length > 0 && paramTypes[0].equals(LuaState.class);
228 }
229
230 private static ArgConverter[] getArgConverters(boolean takesLuaState,Method m) {
222 final boolean isVarArgs = m.isVarArgs(); 231 final boolean isVarArgs = m.isVarArgs();
223 Class<?>[] paramTypes = m.getParameterTypes(); 232 Class<?>[] paramTypes = m.getParameterTypes();
233 if( takesLuaState ) {
234 Class<?>[] t = new Class<?>[paramTypes.length-1];
235 System.arraycopy(paramTypes,1,t,0,t.length);
236 paramTypes = t;
237 }
224 ArgConverter[] a = new ArgConverter[paramTypes.length]; 238 ArgConverter[] a = new ArgConverter[paramTypes.length];
225 for( int i=0; i<a.length; i++ ) { 239 for( int i=0; i<a.length; i++ ) {
226 Class<?> paramType = paramTypes[i]; 240 Class<?> paramType = paramTypes[i];
227 if( isVarArgs && i == a.length-1 ) 241 if( isVarArgs && i == a.length-1 )
228 paramType = paramType.getComponentType(); 242 paramType = paramType.getComponentType();