/* * Created by LuaView. * Copyright (c) 2017, Alibaba Group. All rights reserved. * * This source code is licensed under the MIT. * For the full copyright and license information,please view the LICENSE file in the root directory of this source tree. */ package com.taobao.luaview.fun.base; import com.taobao.luaview.cache.AppCache; import com.taobao.luaview.global.LuaViewConfig; import com.taobao.luaview.userdata.base.BaseUserdata; import com.taobao.luaview.util.LogUtil; import org.luaj.vm2.LuaValue; import org.luaj.vm2.Varargs; import org.luaj.vm2.lib.VarArgFunction; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * 基础多参数函数 * * @author song * @date 15/8/14 */ public abstract class BaseMethodMapper<U extends LuaValue> extends VarArgFunction { private static final String CACHE_METHODS = AppCache.CACHE_METHODS; /** * 该函数使用反射,调用方法,并且被调用方法签名必须为:fun(UIView, Varargs)格式,否则不被支持 * 所有的method都是被注册的public方法,使用class.getMethods返回 * TODO 如果这里性能受限的话,考虑使用其他方式实现(反射性能大概低了20倍),但是只会在创建的时候消耗,其他情况下不消耗性能 * * @param args the arguments to the function call. * @return */ public Varargs invoke(Varargs args) { try { if (opcode != -1) { return invoke(opcode, getUD(args), args); } else { return (Varargs) method.invoke(this, getUD(args), args); } } catch (Exception e) { if (LuaViewConfig.isDebug()) { LogUtil.e("[----Method Invoke Error Start----]"); LogUtil.e("[Class]", getClass()); LogUtil.e("[Opcode]", opcode); LogUtil.e("[Method]", method != null ? method : getMethodByOpcode(opcode)); LogUtil.e("[Arguments]", args); LogUtil.e("[Target]", getTarget(args)); LogUtil.e("[Error]", e); LogUtil.e("[----Method Invoke Error End----]"); } e.printStackTrace(); return NONE; } } /** * 获取userdata * * @param varargs * @return */ public U getUD(Varargs varargs) { return (U) varargs.arg1(); } public Object getTarget(Varargs varargs) { U target = getUD(varargs); if (target instanceof BaseUserdata) { return ((BaseUserdata) target).userdata(); } return target; } //---------------------------------------------------------------------------------------------- /** * merge function names with cache tag * * @param tag * @param supernames * @param names * @return */ public List<String> mergeFunctionNames(final String tag, final List<String> supernames, final String[] names) { List<String> result = AppCache.getCache(CACHE_METHODS).get(tag); if (result == null) { result = mergeFunctionNames(supernames, names); AppCache.getCache(CACHE_METHODS).put(tag, result); } return result; } public List<String> mergeFunctionNames(final String tag, final List<String> supernames, final List<String> names) { List<String> result = AppCache.getCache(CACHE_METHODS).get(tag); if (result == null) { result = mergeFunctionNames(supernames, names); AppCache.getCache(CACHE_METHODS).put(tag, result); } return result; } /** * merge function names * 将names拼接在supernames之后 * * @param supernames * @param names * @return */ private List<String> mergeFunctionNames(final List<String> supernames, final String[] names) { return mergeFunctionNames(supernames, Arrays.asList(names)); } /** * merge FunctionNames * 将自己的names拼接在supernames之后 */ private List<String> mergeFunctionNames(final List<String> supernames, final List<String> names) { final List<String> result = new ArrayList<String>(); if (supernames != null && supernames.size() > 0) { result.addAll(supernames); } if (supernames != null && names != null) { result.addAll(supernames.size(), names); } return result; } /** * 获取所有函数名称,供子类调用 * * @return */ public List<String> getAllFunctionNames() { return new ArrayList<String>(); } /** * 根据code获取函数名称 * * @param optcode * @return */ public String getMethodByOpcode(int optcode) { List<String> allMethods = getAllFunctionNames(); if (allMethods != null && allMethods.size() > optcode && optcode >= 0) { return allMethods.get(optcode); } return null; } /** * 调用子类 * * @param code * @param target * @param varargs * @return */ public Varargs invoke(int code, U target, Varargs varargs) { return LuaValue.NIL; } }