/* * 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.util; import com.taobao.luaview.userdata.kit.UDUnicode; import com.taobao.luaview.userdata.ui.UDSpannableString; import org.luaj.vm2.LuaFunction; import org.luaj.vm2.LuaNumber; import org.luaj.vm2.LuaTable; import org.luaj.vm2.LuaUserdata; import org.luaj.vm2.LuaValue; import org.luaj.vm2.Varargs; import org.luaj.vm2.lib.jse.CoerceJavaToLua; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Lua脚本工具类 * * @author song * @date 15/9/14 */ public class LuaUtil { //-------------------------------------get value------------------------------------------------ /** * 获取alpha * * @param varargs * @param poslist * @return */ public static Integer getAlphaInt(final Varargs varargs, int... poslist) { return getAlphaInt(varargs, null, poslist); } public static Integer getAlphaInt(final Varargs varargs, Double defaultAlpha, int... poslist) { final Double alphaDouble = getDouble(varargs, poslist); if (alphaDouble != null) { return (int) (alphaDouble * 0xFF); } else if (defaultAlpha != null) { return (int) (defaultAlpha * 0xFF); } else { return null; } } /** * convert a LuaValue to Alpha int * @param value * @return */ public static Integer toAlphaInt(final LuaValue value) { if (isNumber(value)) { final double dValue = value.optdouble(-1); if (dValue >= 0) { return (int) (dValue * 0xFF); } } return null; } /** * 获取时间,入参为秒(可以是小数),输出为毫秒 * * @param varargs * @param poslist * @return */ public static Long getTimeLong(final Varargs varargs, int... poslist) { return getTimeLong(varargs, null, poslist); } /** * 获取时间,入参为秒(可以是小数),输出为毫秒 * * @param varargs * @param defaultSeconds * @param poslist * @return */ public static Long getTimeLong(final Varargs varargs, Float defaultSeconds, int... poslist) { final Float timeOfFloat = getFloat(varargs, poslist); if (timeOfFloat != null) { return (long) (timeOfFloat * 1000); } else if (defaultSeconds != null) { return (long) (defaultSeconds * 1000); } else { return null; } } /** * 获取boolean * * @param varargs * @param poslist * @return */ public static Boolean getBoolean(final Varargs varargs, int... poslist) { return (Boolean) getValue(LuaValue.TBOOLEAN, varargs, poslist); } public static Boolean getBoolean(final Varargs varargs, Boolean defaultValue, int... poslist) { return (Boolean) getValue(LuaValue.TBOOLEAN, varargs, defaultValue, poslist); } /** * 获取int * * @param varargs * @param poslist * @return */ public static Integer getInt(final Varargs varargs, int... poslist) { final LuaNumber number = (LuaNumber) getValue(LuaValue.TNUMBER, varargs, poslist); return number != null ? number.checkint() : null; } /** * 获取long * * @param varargs * @param poslist * @return */ public static Long getLong(final Varargs varargs, int... poslist) { final LuaNumber number = (LuaNumber) getValue(LuaValue.TNUMBER, varargs, poslist); return number != null ? number.checklong() : null; } public static Long getLong(final Varargs varargs, Long defaultValue, int... poslist) { final LuaNumber number = (LuaNumber) getValue(LuaValue.TNUMBER, varargs, defaultValue, poslist); return number != null ? number.checklong() : null; } /** * 获取double * * @param varargs * @param poslist * @return */ public static Double getDouble(final Varargs varargs, int... poslist) { final LuaNumber number = (LuaNumber) getValue(LuaValue.TNUMBER, varargs, poslist); return number != null ? number.checkdouble() : null; } /** * 获取double * * @param varargs * @param poslist * @return */ public static Double getDouble(final Varargs varargs, Double defaultValue, int... poslist) { final LuaNumber number = (LuaNumber) getValue(LuaValue.TNUMBER, varargs, poslist); return number != null ? number.checkdouble() : defaultValue; } /** * 获取float * * @param varargs * @param poslist * @return */ public static Float getFloat(final Varargs varargs, int... poslist) { final LuaNumber number = (LuaNumber) getValue(LuaValue.TNUMBER, varargs, poslist); return number != null ? (float) number.checkdouble() : null; } /** * 获取float * * @param varargs * @param poslist * @return */ public static Float getFloat(final Varargs varargs, Float defaultValue, int... poslist) { final LuaNumber number = (LuaNumber) getValue(LuaValue.TNUMBER, varargs, defaultValue, poslist); return number != null ? (float) number.checkdouble() : defaultValue; } /** * 获取string * * @param varargs * @param poslist * @return */ public static String getString(final Varargs varargs, int... poslist) { return (String) getValue(LuaValue.TSTRING, varargs, poslist); } public static String getString(final LuaValue valueList, String... poslist) { return (String) getValueFromTable(LuaValue.TSTRING, valueList, poslist); } /** * 获取char sequence * * @param varargs * @param poslist * @return */ public static CharSequence getText(final Varargs varargs, int... poslist) { LuaValue value = getValue(varargs, poslist); return toText(value); } /** * 获取char sequence * * @param values * @param poslist * @return */ public static CharSequence getText(final LuaValue values, String... poslist) { LuaValue value = (LuaValue) getValueFromTable(LuaValue.TVALUE, values, poslist); return toText(value); } /** * 获取table * * @param varargs * @param poslist * @return */ public static LuaTable getTable(final Varargs varargs, int... poslist) { return (LuaTable) getValue(LuaValue.TTABLE, varargs, poslist); } public static LuaTable getTable(final LuaValue valuelist, String... poslist) { return (LuaTable) getValueFromTable(LuaValue.TTABLE, valuelist, poslist); } /** * 获取function * * @param varargs * @param poslist * @return */ public static LuaFunction getFunction(final Varargs varargs, int... poslist) { return (LuaFunction) getValue(LuaValue.TFUNCTION, varargs, poslist); } public static LuaFunction getFunction(final LuaValue valueList, String... keylist) { return (LuaFunction) getValueFromTable(LuaValue.TFUNCTION, valueList, keylist); } /** * 获取LuaValue * * @param varargs * @param poslist * @return */ public static LuaValue getValue(final Varargs varargs, int... poslist) { return (LuaValue) getValue(LuaValue.TVALUE, varargs, poslist); } public static LuaValue getValue(final Varargs varargs, String... poslist) { return (LuaValue) getValueFromTable(LuaValue.TVALUE, varargs, poslist); } public static LuaValue getValue(final Varargs varargs, Varargs defaultValue, String... poslist) { return (LuaValue) getValueFromTable(LuaValue.TVALUE, varargs, defaultValue, poslist); } /** * 获取LuaValue by poslist name * * @param valuelist * @param poslist * @return */ public static LuaValue getValue(final LuaValue valuelist, String... poslist) { return (LuaValue) getValueFromTable(LuaValue.TVALUE, valuelist, poslist); } public static LuaValue getValue(final LuaValue valuelist, LuaValue defaultValue, String... poslist) { return (LuaValue) getValueFromTable(LuaValue.TVALUE, defaultValue, valuelist, poslist); } /** * 获取userdata * * @param varargs * @param poslist * @return */ public static LuaUserdata getUserdata(final Varargs varargs, int... poslist) { return (LuaUserdata) getValue(LuaValue.TUSERDATA, varargs, poslist); } /** * get value of given type, from varargs in position [poslist] * * @param type * @param varargs * @param poslist * @return */ private static Object getValue(final int type, final Varargs varargs, int... poslist) { return getValue(type, varargs, null, poslist); } /** * get value of given type, from varargs in position [poslist] * * @param type * @param varargs * @param poslist * @return */ private static Object getValue(final int type, final Varargs varargs, Object defaultValue, int... poslist) { Object result = null; if (varargs != null) { if (poslist != null && poslist.length > 0) { LuaValue value = null; for (int i = 0; i < poslist.length; i++) { if (varargs.narg() >= poslist[i]) { value = varargs.arg(poslist[i]); result = parseValue(type, value); } if (result != null) { break; } } } } return result != null ? result : defaultValue; } /** * get value from table * * @param type * @param valueList * @param keylist * @return */ private static Object getValueFromTable(final int type, final Varargs valueList, String... keylist) { return getValueFromTable(type, valueList, null, keylist); } /** * get value of given type, from varargs of key [poslist] * * @param type * @param varargs * @param keylist * @return */ private static Object getValueFromTable(final int type, final Varargs varargs, Object defaultValue, String... keylist) { Object result = null; if (varargs instanceof LuaTable) { LuaTable varlist = ((LuaTable) varargs); if (keylist != null && keylist.length > 0) { for (int i = 0; i < keylist.length; i++) { result = parseValue(type, varlist.get(keylist[i])); if (result != null) { break; } } } } return result != null ? result : defaultValue; } /** * parse a value to given type * * @param type * @param value * @return */ private static Object parseValue(int type, LuaValue value) { switch (type) { case LuaValue.TBOOLEAN: if (isBoolean(value)) return value.checkboolean(); break; case LuaValue.TNUMBER: if (isNumber(value)) return value.checknumber(); break; case LuaValue.TSTRING: if (isString(value)) return value.checkjstring(); break; case LuaValue.TTABLE: if (isTable(value)) return value.checktable(); break; case LuaValue.TFUNCTION: if (isFunction(value)) return value.checkfunction(); break; case LuaValue.TUSERDATA: if (isUserdata(value)) return value.checkuserdata(); break; case LuaValue.TVALUE: return value; } return null; } //---------------------------------type of value------------------------------------------------ /** * is string * * @param target * @return */ public static boolean isString(final LuaValue target) { return target != null && target.type() == LuaValue.TSTRING; } /** * is number * * @param target * @return */ public static boolean isNumber(final LuaValue target) { return target != null && target.type() == LuaValue.TNUMBER; } /** * is boolean * * @param target * @return */ public static boolean isBoolean(final LuaValue target) { return target != null && target.type() == LuaValue.TBOOLEAN; } /** * is function * * @param target * @return */ public static boolean isFunction(final LuaValue target) { return target != null && target.type() == LuaValue.TFUNCTION; } /** * is table * * @param target * @return */ public static boolean isTable(final LuaValue target) { return target != null && target.type() == LuaValue.TTABLE; } /** * is userdata * * @param target * @return */ public static boolean isUserdata(final LuaValue target) { return target != null && target.type() == LuaValue.TUSERDATA; } /** * is nil * * @param target * @return */ public static boolean isNil(final LuaValue target) { return target != null && target.type() == LuaValue.TNIL; } /** * is none * * @param target * @return */ public static boolean isNone(final LuaValue target) { return target != null && target.type() == LuaValue.TNONE; } /** * 判断是否空或者nil * * @param target * @return */ public static boolean isValid(final LuaValue target) { return target != null && target.type() != LuaValue.TNIL; } //------------------------------------function call--------------------------------------------- /** * call lua function * * @param target * @return */ public static LuaValue callFunction(LuaValue target) { try { return (target != null && target.isfunction()) ? target.call() : LuaValue.NIL; } catch (Exception e) { e.printStackTrace(); return LuaValue.NIL; } } public static LuaValue callFunction(LuaValue target, LuaValue arg1) { try { return (target != null && target.isfunction()) ? target.call(arg1) : LuaValue.NIL; } catch (Exception e) { e.printStackTrace(); return LuaValue.NIL; } } public static LuaValue callFunction(LuaValue target, LuaValue arg1, LuaValue arg2) { try { return (target != null && target.isfunction()) ? target.call(arg1, arg2) : LuaValue.NIL; } catch (Exception e) { e.printStackTrace(); return LuaValue.NIL; } } public static LuaValue callFunction(LuaValue target, LuaValue arg1, LuaValue arg2, LuaValue arg3) { try { return (target != null && target.isfunction()) ? target.call(arg1, arg2, arg3) : LuaValue.NIL; } catch (Exception e) { e.printStackTrace(); return LuaValue.NIL; } } public static Varargs callFunction(LuaValue target, Object... objs) { if (target != null && target.isfunction()) { LuaValue[] args = null; if (objs != null && objs.length > 0) { args = new LuaValue[objs.length]; for (int i = 0; i < objs.length; i++) { args[i] = CoerceJavaToLua.coerce(objs[i]); } } if (args != null) { return target.invoke(LuaValue.varargsOf(args)); } else { return target.call(); } } return LuaValue.NIL; } /** * call lua function ( return multiple values) * * @param target * @return */ public static Varargs invokeFunction(LuaValue target) { try { return (target != null && target.isfunction()) ? target.invoke() : LuaValue.NIL; } catch (Exception e) { e.printStackTrace(); return LuaValue.NIL; } } public static Varargs invokeFunction(LuaValue target, LuaValue arg1) { try { return (target != null && target.isfunction()) ? target.invoke(arg1) : LuaValue.NIL; } catch (Exception e) { e.printStackTrace(); return LuaValue.NIL; } } public static Varargs invokeFunction(LuaValue target, LuaValue arg1, LuaValue arg2) { try { return (target != null && target.isfunction()) ? target.invoke(arg1, arg2) : LuaValue.NIL; } catch (Exception e) { e.printStackTrace(); return LuaValue.NIL; } } public static Varargs invokeFunction(LuaValue target, LuaValue arg1, LuaValue arg2, LuaValue arg3) { try { return (target != null && target.isfunction()) ? target.invoke(new LuaValue[]{arg1, arg2, arg3}) : LuaValue.NIL; } catch (Exception e) { e.printStackTrace(); return LuaValue.NIL; } } /** * 调用方法或者直接取数据 * * @param target * @return */ public static LuaValue getOrCallFunction(LuaValue target) { try { return (target != null && target.isfunction()) ? target.call() : target; } catch (Exception e) { e.printStackTrace(); return LuaValue.NIL; } } public static LuaValue getOrCallFunction(LuaValue target, LuaValue arg1) { try { return (target != null && target.isfunction()) ? target.call(arg1) : target; } catch (Exception e) { e.printStackTrace(); return LuaValue.NIL; } } public static LuaValue getOrCallFunction(LuaValue target, LuaValue arg1, LuaValue arg2) { try { return (target != null && target.isfunction()) ? target.call(arg1, arg2) : target; } catch (Exception e) { e.printStackTrace(); return LuaValue.NIL; } } public static LuaValue getOrCallFunction(LuaValue target, LuaValue arg1, LuaValue arg2, LuaValue arg3) { try { return (target != null && target.isfunction()) ? target.call(arg1, arg2, arg3) : target; } catch (Exception e) { e.printStackTrace(); return LuaValue.NIL; } } /** * lua 都是从1开始 * * @param pos * @return */ public static LuaValue toLuaInt(Integer pos) { return pos != null ? LuaValue.valueOf(pos + 1) : LuaValue.NIL; } public static LuaValue toLuaBoolean(boolean value) { return LuaValue.valueOf(value); } /** * java 从 0 开始 * * @param pos * @return */ public static int toJavaInt(LuaValue pos) { return pos.optint(1) - 1; } /** * convert a lua Int to java Int * * @param luaInt * @return */ public static Integer toJavaInt(Integer luaInt) { return luaInt != null ? luaInt - 1 : null; } /** * convert params to LuaTable * * @param params * @return */ public static LuaValue toTable(List<?> params) { if (params != null) { final LuaTable result = new LuaTable(); if (params.size() > 0) { Object value = null; for (int i = 0; i < params.size(); i++) { value = params.get(i); result.set(i + 1, toLuaValue(value)); } } return result; } return LuaValue.NIL; } /** * convert map to LuaTable * * @param params * @return */ public static LuaValue toTable(Map<?, ?> params) { if (params != null) { final LuaTable result = new LuaTable(); if (params.size() > 0) { Object valueObj = null; LuaValue key = null; for (final Object keyObj : params.keySet()) { valueObj = params.get(keyObj); key = toLuaValue(keyObj); if (key != LuaValue.NIL) { result.set(key, toLuaValue(valueObj)); } } } return result; } return LuaValue.NIL; } /** * convert luavalue to charsequence * * @param luaValue * @return */ public static CharSequence toText(LuaValue luaValue) { if (LuaUtil.isString(luaValue)) { return luaValue.optjstring(null); } else if (LuaUtil.isUserdata(luaValue)) { if (luaValue instanceof UDSpannableString) { return ((UDSpannableString) luaValue).getSpannableStringBuilder(); } else if (luaValue instanceof UDUnicode) { return ((UDUnicode) luaValue).toString(); } } return null; } /** * convert object to LuaValue * * @param value * @return */ public static LuaValue toLuaValue(Object value) { try { if (value instanceof Integer) { return LuaValue.valueOf((Integer) value); } else if (value instanceof Long) { return LuaValue.valueOf((Long) value); } else if (value instanceof Double) { return LuaValue.valueOf((Double) value); } else if (value instanceof String) { return LuaValue.valueOf((String) value); } else if (value instanceof Boolean) { return LuaValue.valueOf((Boolean) value); } else if (value instanceof byte[]) { return LuaValue.valueOf((byte[]) value); } else if (value instanceof List) { return toTable((List) value); } else if (value instanceof Map) { return toTable((Map) value); } else { return CoerceJavaToLua.coerce(value); } } catch (Exception e) { e.printStackTrace(); return LuaValue.NIL; } } /** * convert a table to map * * @param table * @return */ public static Map<String, String> toMap(LuaTable table) { if (table != null) { final Map<String, String> result = new HashMap<String, String>(); final LuaValue[] keys = table.keys(); LuaValue value = null; for (LuaValue key : keys) { value = table.get(key); result.put(key.optjstring(null), value.optjstring(null)); } } return null; } }