Mercurial Hosting > luan
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(); |