如何将对象传递给暴露的 luaj 函数? [英] How can I pass objects to an exposed luaj function?
问题描述
我正在尝试使用 Luaj + java 构建控制器.我有以下java类
I am trying to build a controller using Luaj + java. I have the following java classes
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 脚本:
and the following lua script for the controller:
onTalk(obj)
obj:talk();
end
onWalk(obj)
obj:walk();
end
理想情况下,我想定义一个控制器(用 lua 编写),我将在其中保留程序的所有逻辑,并且我想将来自该控制器的 API 公开给我的 Java 代码.我试图使用以下方法:
I would ideally like to define one controller (written in lua) where I will keep all of the program's logic, and I would like to expose API from that controller to my java code. I was trying to use the following approach:
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 脚本?
I am not able to pass the object to the LuaValue. How can I pass a java object to the lua script?
PS:一般来说,在使用 Java 和嵌入式脚本时,人们是将函数捆绑在一个脚本中,还是每个回调都有一个单独的脚本?
PS: In general, when using Java and embedded scripting, do people bundle functions in one script, or is there a separate script for every callback?
推荐答案
我正在搜索 luaj 条目,发现您没有得到答复.你的问题很有趣,让我搜索.然后我意识到这是 2 年前问过的……我希望我的回答对其他人有用!基于luaj-3.0-alpha1的代码.
I was searching luaj entries and found your unanswered. Your question was interesting and made me search. Then I realized that it was asked 2 years ago... I hope my answer can be useful to somebody else! Code based on luaj-3.0-alpha1.
我们需要一个有效的 Lua 脚本(你忘记了 function
关键字):
We need a valid Lua script (you forgot the function
keyword):
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
我添加了一点痕迹...我还制作了类似于您的课程:
I added a bit of trace... I also made classes similar to your:
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..."); }
}
也添加一个字段来测试这个.对于我的测试,我只是在创建它们的实例的方法中声明了类:
Adding a field to test this too. For my test, I just declared the classes inside the method creating their instances:
Dog dog = new Dog("Rex");
Cat cat = new Cat("Felix");
我首先尝试将这些 Java 对象转换为 Lua,使用 LuaValue luaDog = LuaValue.userdataOf(dog);
但它不起作用:我们确实有用户数据,如跟踪所示,但是没有元表,所以我们不能调用方法也不能访问字段.
I first tried to convert these Java objects to Lua, using LuaValue luaDog = LuaValue.userdataOf(dog);
but it doesn't work: we indeed have userdata, as shown by the traces, but no metatable, so we cannot call the methods nor access the fields.
找了好久,终于找到了正确的咒语:
After searching a lot, I found out the right incantation:
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 程序员...
I appreciate the Luaj API... :-) Probably more made for Java programmers while other libraries seem to aim more at Lua / C programmers...
这篇关于如何将对象传递给暴露的 luaj 函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!