Luaj学习笔记(四) - 使用Java创建自定义Lua库

4 篇文章 1 订阅

Luaj学习笔记(四) - 使用Java创建自定义Lua库

自定义库示例代码

参考GitHub上找到的示例代码,重新写了一个简单的示例小项目,话不多说上代码:

自定义库的源代码

Java文件命名:TestCustomLibrary.java

package pers.landriesnidis.testluaj.func;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.luaj.vm2.LuaValue;
import org.luaj.vm2.Varargs;
import org.luaj.vm2.lib.OneArgFunction;
import org.luaj.vm2.lib.ThreeArgFunction;
import org.luaj.vm2.lib.TwoArgFunction;
import org.luaj.vm2.lib.VarArgFunction;
import org.luaj.vm2.lib.ZeroArgFunction;

public class MyLibrary extends TwoArgFunction{

    @Override
    public LuaValue call(LuaValue modname, LuaValue env) {
        LuaValue library = tableOf();
        library.set( "time", new TimeFunc() );
        library.set( "echo", new EchoFunc() );
        library.set( "max", new MaxFunc() );
        library.set( "average", new AverageFunc() );
        library.set( "list", new ListFunc() );
        env.set( "mylib", library );
        env.get("package").get("loaded").set("mylib", library);
        return library;
    }

    /**
     * 获取当前时间
     * 无参数的方法
     */
    static class TimeFunc extends ZeroArgFunction{
        @Override
        public LuaValue call() {
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
            return LuaValue.valueOf(df.format(new Date()).toString());
        }
    }

    /**
     * 回显传入的参数
     * 接收一个参数的方法
     */
    static class EchoFunc extends OneArgFunction{
        @Override
        public LuaValue call(LuaValue arg) {
            return LuaValue.valueOf("You say: " + arg.checkstring());
        }
    }

    /**
     * 比较并返回两个整数中较大的值
     * 接收两个参数的方法
     */
    static class MaxFunc extends TwoArgFunction{
        @Override
        public LuaValue call(LuaValue arg1, LuaValue arg2) {
            if(arg1.checkint()>arg2.checkint()){
                return arg1;
            }else{
                return arg2;
            }
        }
    }

    /**
     * 计算三个整数的平均数
     * 接收三个参数的方法
     */
    static class AverageFunc extends ThreeArgFunction{
        @Override
        public LuaValue call(LuaValue arg1, LuaValue arg2, LuaValue arg3) {
            return LuaValue.valueOf((arg1.checkint() + arg2.checkint() + arg3.checkint())/3.0);
        }

    }

    /**
     * 列表显示传入的所有参数
     * 接收多个参数的方法
     */
    static class ListFunc extends VarArgFunction {
        public Varargs invoke(Varargs args) {
            int n = args.narg();
            StringBuilder sb = new StringBuilder();
            for(int i=1;i<=n;++i){
                sb.append(String.format("第%d个数是:%d\n", i, args.checkint(i)));
            }
            return valueOf(sb.toString());
        }
    }

}

Lua脚本源代码

Lua脚本文件命名:test_custom_library.lua

require 'mylib'

print(mylib.time())
print(mylib.echo('Hello,World!'))
print(mylib.max(100,101))
print(mylib.average(1,2,3))
print(mylib.list(2,4,8,16,32,64,128,256,512,1024))

载入脚本的启动代码

Java文件命名:TestCustomLibrary.java

package pers.landriesnidis.testluaj.func;

import org.luaj.vm2.Globals;
import org.luaj.vm2.LoadState;
import org.luaj.vm2.compiler.LuaC;
import org.luaj.vm2.lib.jse.JsePlatform;

public class TestCustomLibrary {
    public static void main(String[] args) {
        // lua脚本文件所在路径
        String luaPath = "script/test_custom_library.lua";
        Globals globals = JsePlatform.standardGlobals();

        //加载自定义函数库
        globals.load(new MyLibrary());
        LoadState.install(globals);
        LuaC.install(globals);

        // 加载脚本文件script/test.lua,并编译
        globals.loadfile(luaPath).call();
    }
}

运行结果

2018-08-22 20:45:35
You say: Hello,World!
101
2
第1个数是:2
第2个数是:4
第3个数是:8
第4个数是:16
第5个数是:32
第6个数是:64
第7个数是:128
第8个数是:256
第9个数是:512
第10个数是:1024

一些可以提供参考的资料

官方提供的示例代码

GitHub中开源的关于创建自定义Lua库的示例代码:https://github.com/luaj/luaj/blob/master/examples/jse/hyperbolic.java

LuaJ的函数库源代码

LuaJ中已经实现好的函数库的源代码是最容易获取到的示例代码:
LuaJ内置函数库
其中最直观的莫过于MathLib.class

public class MathLib extends TwoArgFunction {

    /** Pointer to the latest MathLib instance, used only to dispatch
     * math.exp to tha correct platform math library.
     */
    public static MathLib MATHLIB = null;

    /** Construct a MathLib, which can be initialized by calling it with a 
     * modname string, and a global environment table as arguments using 
     * {@link #call(LuaValue, LuaValue)}. */
    public MathLib() {
        MATHLIB = this;
    }

    /** Perform one-time initialization on the library by creating a table
     * containing the library functions, adding that table to the supplied environment,
     * adding the table to package.loaded, and returning table as the return value.
     * @param modname the module name supplied if this is loaded via 'require'.
     * @param env the environment to load into, typically a Globals instance.
     */
    public LuaValue call(LuaValue modname, LuaValue env) {
        LuaTable math = new LuaTable(0,30);
        math.set("abs", new abs());
        math.set("ceil", new ceil());
        math.set("cos", new cos());
        math.set("deg", new deg());
        math.set("exp", new exp(this));
        math.set("floor", new floor());
        math.set("fmod", new fmod());
        math.set("frexp", new frexp());
        math.set("huge", LuaDouble.POSINF );
        math.set("ldexp", new ldexp());
        math.set("max", new max());
        math.set("min", new min());
        math.set("modf", new modf());
        math.set("pi", Math.PI );
        math.set("pow", new pow());
        random r;
        math.set("random", r = new random());
        math.set("randomseed", new randomseed(r));
        math.set("rad", new rad());
        math.set("sin", new sin());
        math.set("sqrt", new sqrt());
        math.set("tan", new tan());
        env.set("math", math);
        env.get("package").get("loaded").set("math", math);
        return math;
    }

    abstract protected static class UnaryOp extends OneArgFunction {
        public LuaValue call(LuaValue arg) {
            return valueOf(call(arg.checkdouble()));
        }
        abstract protected double call(double d);
    }

    abstract protected static class BinaryOp extends TwoArgFunction {
        public LuaValue call(LuaValue x, LuaValue y) {
            return valueOf(call(x.checkdouble(), y.checkdouble()));
        }
        abstract protected double call(double x, double y);
    }

    static final class abs extends UnaryOp { protected double call(double d) { return Math.abs(d); } }
    static final class ceil extends UnaryOp { protected double call(double d) { return Math.ceil(d); } }
    static final class cos extends UnaryOp { protected double call(double d) { return Math.cos(d); } }
    static final class deg extends UnaryOp { protected double call(double d) { return Math.toDegrees(d); } }
    static final class floor extends UnaryOp { protected double call(double d) { return Math.floor(d); } }
    static final class rad extends UnaryOp { protected double call(double d) { return Math.toRadians(d); } }
    static final class sin extends UnaryOp { protected double call(double d) { return Math.sin(d); } }
    static final class sqrt extends UnaryOp { protected double call(double d) { return Math.sqrt(d); } }
    static final class tan extends UnaryOp { protected double call(double d) { return Math.tan(d); } }

    static final class exp extends UnaryOp {
        final MathLib mathlib;
        exp(MathLib mathlib) {
            this.mathlib = mathlib;
        }
        protected double call(double d) { 
            return mathlib.dpow_lib(Math.E,d); 
        } 
    }

    /*
    省略余下代码……
    */
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猿长大人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值