Как я могу добавить функции _G, которые запускают Java-код, используя Luaj?

Я хочу добавить функции к _G который может запустить код Java. Я использую Luaj, и он уже может запускать пользовательский код Lua, но я хочу добавить API, который позволит пользователю взаимодействовать с игровым миром.

1 ответ

Решение

Вы создаете класс для каждой библиотечной функции и один класс для загрузки функций. Вы расширяете соответствующий класс в зависимости от того, сколько аргументов принимает ваша функция (до трех аргументов, тогда вам нужно сделать свой собственный FourArgFunction).

Вот сокращенный пример кода из файла MathLib.java из источника luaj (можно найти здесь: http://sourceforge.net/projects/luaj/files/latest/download):

Это то, что вам нужно загрузить, когда вы добавляете свою библиотеку.

public class MathLib extends OneArgFunction {
    public static MathLib MATHLIB = null;
    public MathLib() {
        MATHLIB = this;
    }

    public LuaValue call(LuaValue env) {
        LuaTable math = new LuaTable(0,30); // I think "new LuaTable()" instead of "(0, 30)" is OK
        math.set("abs", new abs());
        math.set("max", new max());
        env.set("math", math);
        env.get("package").get("loaded").set("math", math);
        return math;
    }
}

Вы загружаете это так:

globals.load(new MathLib());

Затем вы создаете подклассы MathLib для каждой библиотечной функции. Для функции, которая принимает один аргумент, вот пример:

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

static final class abs extends UnaryOp {
    protected double call(double d) {
        return Math.abs(d);
    }
}

Вам не нужен абстрактный класс, вы можете сделать abs напрямую, но если вы посмотрите на источник, будет очевидно, что более удобно делать это так, когда вам нужно реализовать много математических унарных операций.

Вот пример для функции, которая принимает переменное количество аргументов:

static class max extends VarArgFunction {
    public Varargs invoke(Varargs args) {
    double m = args.checkdouble(1);
    for ( int i=2,n=args.narg(); i<=n; ++i )
        m = Math.max(m,args.checkdouble(i));
    return valueOf(m);
}

Из Lua вы делаете: require('math') загрузить библиотеку, а затем что-то вроде math.abs(-123) вызвать функцию lib.

Я действительно рекомендую проверить источник luaj, если это трудно понять. Кроме того, мой урезанный код не проверен, поэтому я не уверен на 100 %, что он работает.

Другие вопросы по тегам