8

Luaj+javaを使用してコントローラーを構築しようとしています。私は次のJavaクラスを持っています

public class Duck {
  public void talk() { System.out.println("Duck quacks!"); }
  public void walk() { System.out.println("Duck walks!"); }
}

public class Person {
  public void talk() { System.out.println("Person talks!"); }
  public void walk() { System.out.println("Person walks!"); }
}

コントローラー用の次のluaスクリプト:

onTalk(obj) 
  obj:talk();
end

onWalk(obj)
   obj:walk();
end

理想的には、プログラムのすべてのロジックを保持する1つのコントローラー(luaで記述)を定義し、そのコントローラーからのAPIをJavaコードに公開したいと思います。私は次のアプローチを使おうとしていました:

ScriptEngineManager sem     = new ScriptEngineManager();
ScriptEngine        engine  = sem.getEngineByExtension(".lua");
ScriptEngineFactory factory = engine.getFactory();

// Script defined above
CompiledScript cs = ((Compilable)engine).compile(MY_LUA_SCRIPT);
SimpleBindings b = new SimpleBindings();

b = newSimpletBindings();

LuaValue onWalkHandler = (LuaValue)b.get("onWalk");
//func.call(LuaValue.valueOf(duck)); // Passing duck object does not work ???

オブジェクトをLuaValueに渡すことができません。Javaオブジェクトをluaスクリプトに渡すにはどうすればよいですか?

PS:一般に、Javaと組み込みスクリプトを使用する場合、関数を1つのスクリプトにバンドルしますか、それともコールバックごとに個別のスクリプトがありますか?

4

1 に答える 1

25

エントリを検索していたところ、未回答が見つかりました。あなたの質問は面白くて、私を検索させました。それから2年前に聞いたことに気づきました…私の答えが他の人にも役立つことを願っています!luaj-3.0-alpha1に基づくコード。

有効なLuaスクリプトが必要です(functionキーワードを忘れました):

function onTalk(javaObj)
  print(type(javaObj) .. " " .. tostring(javaObj))
  print(javaObj.name)
  javaObj:talk()
  return true
end

function onWalk(javaObj)
  javaObj:walk()
  return 1, "km"
end

トレースを少し追加しました...私もあなたに似たクラスを作成しました:

class Dog
{
  public String name;
  Dog(String n) { name = n; }
  public void talk() { System.out.println("Dog " + name + " barks!"); }
  public void walk() { System.out.println("Dog " + name + " walks..."); }
}
class Cat
{
  String name;
  Cat(String n) { name = n; }
  public void talk() { System.out.println("Cat " + name + " meows!"); }
  public void walk() { System.out.println("Cat " + name + " walks..."); }
}

これもテストするためのフィールドを追加します。私のテストでは、インスタンスを作成するメソッド内でクラスを宣言しました。

Dog dog = new Dog("Rex");
Cat cat = new Cat("Felix");

私は最初にこれらのJavaオブジェクトをLuaに変換しようとしましLuaValue luaDog = LuaValue.userdataOf(dog);たが、機能しません。トレースで示されているように、実際にはuserdataがありますが、メタテーブルがないため、メソッドを呼び出したり、フィールドにアクセスしたりすることはできません。

たくさん検索した後、私は正しい呪文を見つけました:

CompiledScript script = ((Compilable) scriptEngine).compile(reader);
Bindings sb = new SimpleBindings();
script.eval(sb); // Put the Lua functions into the sb environment
LuaValue luaDog = CoerceJavaToLua.coerce(dog); // Java to Lua
LuaFunction onTalk = (LuaFunction) sb.get("onTalk"); // Get Lua function
LuaValue b = onTalk.call(luaDog); // Call the function
System.out.println("onTalk answered: " + b);
LuaFunction onWalk = (LuaFunction) sb.get("onWalk");
LuaValue[] dogs = { luaDog };
Varargs dist = onWalk.invoke(LuaValue.varargsOf(dogs)); // Alternative
System.out.println("onWalk returned: " + dist);

Luaj APIに感謝します...:-)おそらくJavaプログラマー向けに作成されたものですが、他のライブラリーはLua/Cプログラマー向けになっているようです...

于 2012-10-25T16:17:17.860 に答える