comparison src/luan/LuaJavaFunction.java @ 37:8a57ebfdfd78

add JavaLib git-svn-id: https://luan-java.googlecode.com/svn/trunk@38 21e917c8-12df-6dd8-5cb6-c86387c605b9
author fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
date Thu, 20 Dec 2012 02:36:07 +0000
parents c93d8c781853
children e3624b7cd603
comparison
equal deleted inserted replaced
36:2a35154aec14 37:8a57ebfdfd78
1 package luan; 1 package luan;
2 2
3 import java.lang.reflect.Array; 3 import java.lang.reflect.Array;
4 import java.lang.reflect.Method; 4 import java.lang.reflect.Method;
5 import java.lang.reflect.Constructor;
5 import java.lang.reflect.InvocationTargetException; 6 import java.lang.reflect.InvocationTargetException;
6 7
7 8
8 public final class LuaJavaFunction extends LuaFunction { 9 public final class LuaJavaFunction extends LuaFunction {
9 private final Method method; 10 private final JavaMethod method;
10 private final Object obj; 11 private final Object obj;
11 private final RtnConverter rtnConverter; 12 private final RtnConverter rtnConverter;
12 private final boolean takesLuaState; 13 private final boolean takesLuaState;
13 private final ArgConverter[] argConverters; 14 private final ArgConverter[] argConverters;
14 private final Class<?> varArgCls; 15 private final Class<?> varArgCls;
15 16
16 public LuaJavaFunction(Method method,Object obj) { 17 public LuaJavaFunction(Method method,Object obj) {
18 this( JavaMethod.of(method), obj );
19 }
20
21 public LuaJavaFunction(Constructor constr,Object obj) {
22 this( JavaMethod.of(constr), obj );
23 }
24
25 LuaJavaFunction(JavaMethod method,Object obj) {
17 this.method = method; 26 this.method = method;
18 this.obj = obj; 27 this.obj = obj;
19 this.rtnConverter = getRtnConverter(method); 28 this.rtnConverter = getRtnConverter(method);
20 this.takesLuaState = takesLuaState(method); 29 this.takesLuaState = takesLuaState(method);
21 this.argConverters = getArgConverters(takesLuaState,method); 30 this.argConverters = getArgConverters(takesLuaState,method);
25 } else { 34 } else {
26 this.varArgCls = null; 35 this.varArgCls = null;
27 } 36 }
28 } 37 }
29 38
39 public Class<?>[] getParameterTypes() {
40 return method.getParameterTypes();
41 }
42
30 @Override public Object[] call(LuaState lua,Object... args) { 43 @Override public Object[] call(LuaState lua,Object... args) {
31 args = fixArgs(lua,args); 44 args = fixArgs(lua,args);
32 Object rtn; 45 Object rtn;
33 try { 46 try {
34 rtn = method.invoke(obj,args); 47 rtn = method.invoke(obj,args);
35 } catch(IllegalAccessException e) { 48 } catch(IllegalAccessException e) {
36 throw new RuntimeException(e); 49 throw new RuntimeException(e);
37 } catch(InvocationTargetException e) { 50 } catch(InvocationTargetException e) {
51 throw new RuntimeException(e);
52 } catch(InstantiationException e) {
38 throw new RuntimeException(e); 53 throw new RuntimeException(e);
39 } 54 }
40 return rtnConverter.convert(rtn); 55 return rtnConverter.convert(rtn);
41 } 56 }
42 57
106 LuaNumber ln = new LuaNumber(n.doubleValue()); 121 LuaNumber ln = new LuaNumber(n.doubleValue());
107 return new Object[]{ln}; 122 return new Object[]{ln};
108 } 123 }
109 }; 124 };
110 125
111 private static RtnConverter getRtnConverter(Method m) { 126 private static RtnConverter getRtnConverter(JavaMethod m) {
112 Class<?> rtnType = m.getReturnType(); 127 Class<?> rtnType = m.getReturnType();
113 if( rtnType == Void.TYPE ) 128 if( rtnType == Void.TYPE )
114 return RTN_EMPTY; 129 return RTN_EMPTY;
115 if( Number.class.isAssignableFrom(rtnType) 130 if( Number.class.isAssignableFrom(rtnType)
116 || rtnType == Short.TYPE 131 || rtnType == Short.TYPE
220 } 235 }
221 return obj; 236 return obj;
222 } 237 }
223 }; 238 };
224 239
225 private static boolean takesLuaState(Method m) { 240 private static boolean takesLuaState(JavaMethod m) {
226 Class<?>[] paramTypes = m.getParameterTypes(); 241 Class<?>[] paramTypes = m.getParameterTypes();
227 return paramTypes.length > 0 && paramTypes[0].equals(LuaState.class); 242 return paramTypes.length > 0 && paramTypes[0].equals(LuaState.class);
228 } 243 }
229 244
230 private static ArgConverter[] getArgConverters(boolean takesLuaState,Method m) { 245 private static ArgConverter[] getArgConverters(boolean takesLuaState,JavaMethod m) {
231 final boolean isVarArgs = m.isVarArgs(); 246 final boolean isVarArgs = m.isVarArgs();
232 Class<?>[] paramTypes = m.getParameterTypes(); 247 Class<?>[] paramTypes = m.getParameterTypes();
233 if( takesLuaState ) { 248 if( takesLuaState ) {
234 Class<?>[] t = new Class<?>[paramTypes.length-1]; 249 Class<?>[] t = new Class<?>[paramTypes.length-1];
235 System.arraycopy(paramTypes,1,t,0,t.length); 250 System.arraycopy(paramTypes,1,t,0,t.length);
257 if( cls == Short.TYPE || cls.equals(Short.class) ) 272 if( cls == Short.TYPE || cls.equals(Short.class) )
258 return ARG_SHORT; 273 return ARG_SHORT;
259 return ARG_SAME; 274 return ARG_SAME;
260 } 275 }
261 276
277
278
279 private static abstract class JavaMethod {
280 abstract boolean isVarArgs();
281 abstract Class<?>[] getParameterTypes();
282 abstract Object invoke(Object obj,Object... args)
283 throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException;
284 abstract Class<?> getReturnType();
285
286 static JavaMethod of(final Method m) {
287 return new JavaMethod() {
288 boolean isVarArgs() {
289 return m.isVarArgs();
290 }
291 Class<?>[] getParameterTypes() {
292 return m.getParameterTypes();
293 }
294 Object invoke(Object obj,Object... args)
295 throws IllegalAccessException, IllegalArgumentException, InvocationTargetException
296 {
297 return m.invoke(obj,args);
298 }
299 Class<?> getReturnType() {
300 return m.getReturnType();
301 }
302 };
303 }
304
305 static JavaMethod of(final Constructor c) {
306 return new JavaMethod() {
307 boolean isVarArgs() {
308 return c.isVarArgs();
309 }
310 Class<?>[] getParameterTypes() {
311 return c.getParameterTypes();
312 }
313 Object invoke(Object obj,Object... args)
314 throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException
315 {
316 return c.newInstance(args);
317 }
318 Class<?> getReturnType() {
319 return c.getDeclaringClass();
320 }
321 };
322 }
323
324 }
325
262 } 326 }