0

Java コードが特に LuaValue を要求するときに、LuaJ が引数として LuaValue を受け入れないという問題に遭遇しました。

public void registerEvent(LuaValue id, String event, String priority,
                          LuaValue callback)
{
    if(!(id instanceof LuaTable))
    {
        throw new RuntimeException("id must be an LuaTable");
    }
    EventDispatcher.addHandler(id, event, priority, callback);
}

理想的には、これにより、Lua のコードが次のように単純に読み取れるようになります...

function main(this)
    this.modName="Some Mod"
    this.lastX = 0
    hg.both.registerEvent(this, "inputcapturedevent", "last", eventRun)
end

function eventRun(this, event)
    this.lastX += event.getX()
end

悲しいことに、これはシンプルで、ユーザーデータを期待しているがテーブルを取得したというエラーを出します。

org.luaj.vm2.LuaError: script:4 bad argument: userdata expected, got table

「this」の値はどちらの場合も同じ LuaTable ですが、メソッド registerEvent が CoerceJavaToLua.coerce(...) を介して追加されているため、実際に LuaVale が必要であることに気付くのではなく、Java オブジェクトが必要であると認識しています。

だから私の質問はこれです。Java と Lua の両方から同じ関数を使用できるようにする、これを回避するより良い方法はありますか? そして、ここまで読んでくれてありがとう:)

4

1 に答える 1

1

あなたが得ているエラーはおそらく赤いニシンであり、「registerEvent」関数を「hg.both」の値にバインドしている方法が原因である可能性があります。おそらく、代わりに次のようなメソッド構文を使用する必要があるだけです。

hg.both:registerEvent(this, "inputcapturedevent", "last", eventRun)

ドット構文hg.both.registerEventを使用する場合は、 VarArgFunctionを使用して invoke() を実装すると、より直接的に実装できます。この例では、Both.registerEvent は VarArgFunction である単純な変数です。

public static class Both {
    public static VarArgFunction registerEvent = new VarArgFunction() {
        public Varargs invoke(Varargs args) {
            LuaTable id = args.checktable(1);
            String event = args.tojstring(2);
            String priority = args.tojstring(3);
            LuaValue callback = args.arg(4);
            EventDispatcher.addHandler(id, event, priority, callback);
            return NIL;
        }
    };
}

public static void main(String[] args) throws ScriptException {

    ScriptEngineManager sem = new ScriptEngineManager();
    ScriptEngine engine = sem.getEngineByName("luaj");
    Bindings sb = engine.createBindings();

    String fr = 
        "function main(this);" +
        "   this.modName='Some Mod';" +
        "   this.lastX = 0;" +
        "   hg.both.registerEvent(this, 'inputcapturedevent', 'last', eventRun);" +
        "end;";
    System.out.println(fr);

    CompiledScript script = ((Compilable) engine).compile(fr);
    script.eval(sb);
    LuaFunction mainFunc = (LuaFunction) sb.get("main");

    LuaTable hg = new LuaTable();
    hg.set("both", CoerceJavaToLua.coerce(Both.class));
    sb.put("hg", hg);

    LuaTable library = new LuaTable();
    mainFunc.call(CoerceJavaToLua.coerce(library));
}
于 2016-01-23T19:05:22.163 に答える