试图在Android应用程序中使用LUAJ,找不到类Lua

时间:2015-03-28 03:01:14

标签: android eclipse luaj

我怀疑我的无知比LUAJ更深刻,所以请保持温柔。

目标:定期从我的应用程序中运行lua脚本,在Lua和Java之间来回传递数据,具有一定的安全性(例如,不要让lua删除文件)

我的应用程序的大多数是直接的android / java,并且工作正常。在这种情况下,我不是一个白痴。

通过各种示例,我最终将LUAJ Jar文件作为外部Jar添加到Eclipse中。之后,这些导入工作

import org.luaj.vm2.Lua;
import org.luaj.vm2.LuaClosure;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.Prototype;
import org.luaj.vm2.compiler.LuaC;
import org.luaj.vm2.lib.jse.CoerceJavaToLua;
import org.luaj.vm2.lib.jse.JsePlatform;

大部分代码主要是编译,但我仍然没有" Lua"此行中使用的界面:

public class MyLuaEngine  implements Lua

该行失败,因为Lua不是超类而无法实现'。我很确定它不知道Lua是什么(除非它在某些其他命名空间中找到同源词)。

另外,我对Lua的覆盖:add()等也是抱怨(他们没有super来覆盖)例如:

@Override
public void run(int id, EventArgs args) throws LuaException
{
    LuaClosure script = scripts.get(id);

(必须覆盖超类型)

我假设有一些类似外部Jar的东西,我需要为Lua本身添加到Eclipse中?但是我没有发现任何指令(也就是说,如果LUAJ是Lua的完整java实现,那么我会期待这个接口类也是LUAJ jar的一部分。

在我发现的三个LUAJ罐子中,我只告诉了Eclipse其中一个(JSE,而不是JME或Source)。

1 个答案:

答案 0 :(得分:1)

所以,这对我有用。在Android java应用程序中使用Luaj 3.0和eclipse。

1。)从其下载页面下载Luaj zip,并确保将jse jar放入某个已知位置(luaj-jse-3.0.jar)

2.)告诉Eclipse将其添加为外部Jar(右键单击项目,buildPath / configureBuildPath / Libraries / Add External Jar

3。)添加这些导入

import org.luaj.vm2.Globals;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.lib.OneArgFunction;
import org.luaj.vm2.lib.TwoArgFunction;
import org.luaj.vm2.lib.jse.JsePlatform;

(以及其他根据需要,但是来自那些类路径。只要你有jar文件,Eclipse ctrl-shift-O就会计算出来)

4.。)一些示例用法(luaj将打印文本发送到android logcat)

void testLua()
{
    //-----
    // Simple Test Lua Script

    String myScript = "require 'com.Your.Class.Path.Here.GameFunctions' \n" 
                    + " \n"
                    + "print 'hello, world from lua' \n" 
                    + "print( game.testFunction( 5 ) ) \n"
                    + " \n"
                    + "function foo() \n"
                    + "  print( 'You have been fooed!' ) \n"
                    + "end \n"
                    + " \n"
                    + "function foo2( a, b ) \n"
                    + "  print( 'Foo2 got '.. a ..', and '.. b ..' !' ) \n"
                    + "end \n"
                    + " \n"
                    + "function foo3( a, b ) \n"
                    + "  print( 'Foo3 got '.. a ..', and '.. b ..' !' ) \n"
                    + "  return 'fantastic!' \n"
                    + "end \n"
                    + " \n"
                    + "print 'Good bye from my lua program' \n"
                    + ""
                    ;
     // Create the globals object and initialize with standard stuff
    Globals globals = JsePlatform.standardGlobals();

     // Load (and compile?) the simple script and get a Chunk
    LuaValue chunk = globals.load( myScript );

     // run the script once from the beginning (root level)
    chunk.call();

     // run it a second time, just to see if it blows up, and
     // get the return value, if any. (didnt blow up)
    LuaValue result = chunk.call();

    // try to call a specific function, no args
    LuaValue foo = globals.get( "foo" );    // get the function to call as a LuaValue
    if( !foo.isnil() ) {
        foo.call();   // runs just that function
    }

    LuaValue foo2 = globals.get( "foo2" );  // pass two args
    if( !foo2.isnil() ) {
        foo2.call(  LuaValue.valueOf("first"), 
                    LuaValue.valueOf("second") );
    }

    LuaValue foo3 = globals.get( "foo3" );  // pass 2 args, get 1 back
    if( !foo3.isnil() ) {
        LuaValue retVal = foo3.call(    LuaValue.valueOf("first"), 
                                        LuaValue.valueOf("second") );
        Log.v( TAG, "LUA: foo3 returned: " + retVal.toString() );
    }

}

lua脚本的第一行是一个require命令,它调出一个名为GameFunctions的公共类的完整类路径。它是lua可以回调到感兴趣的自定义java函数的界面(也许是获得玩家的分数。播放声音效果等)

我的Bare Bones实现看起来像这样:(非常感谢所有为此做出贡献的网页,但最终我猜测2个arg调用会有modName和env)

当您.load()脚本字符串时,它被编译并且返回LuaValue(块)是已编译的代码。但是你不能在块上使用.get(“functionName”),你必须使用'globals'对象(这是有道理的,但是在我编写的时候我的头脑会旋转一点,我觉得发生在,load(),但我想留下某种符号表,以便以后使用全局变量。

无论如何,所以当.call()命令执行脚本并获得'require'时,这个类被实例化。在调用do-nothing创建者之后,Luaj使用modName和env调用2 arg methof。然后,您可以将任何想要的东西粘贴到环境中。在这种情况下,我们构建一个LuaTable函数,然后将其粘贴到名为“game”的环境中,然后从lua我们可以调用Java游戏函数,如

无论如何= game.doSomething(some,junk)

虽然您可能希望将所有lua放在一个单独的线程中,这样您的UI就不会停滞。我希望Lua调试挂钩存在于某处,这样我就可以限制玩家提供的无限循环的执行时间: - )

public class GameFunctions extends TwoArgFunction {
private static final String TAG = GameFunctions.class.getSimpleName();

public GameFunctions() {
}

public LuaValue call( LuaValue modname, LuaValue env ) 
{
    Log.v( TAG, "LUA: modName: " + modname.toString() 
            + ", Env: " + env.toString() );

    LuaTable game = new LuaTable(); 

    // the actual functions get added to game table
    game.set("testFunction", new testFunction());

    // we set it into the environment so lua can see them
    env.set("game", game);

    // we mark it so no 'require' is needed 
    env.get("package").get("loaded").set("game", game);

    return game;
}

// An example Game Function... not a very good one.  Pretend
// it plays a sound effect.  I just wanted to test arg passing
// don't forget to convert to LuaValues as needed.

class testFunction extends OneArgFunction {
    public LuaValue call(LuaValue x) {
        return LuaValue.valueOf( "you said: " + x );
    }
}

}

理论上,最后的位应该使得不必在脚本中包含require命令。我希望这是真的,但我并不介意我的申请中的要求

无论如何,我希望有一天能帮助别人。从2015年3月开始,就像luaj 3.0版一样,这一切都是真的,只有未来才会知道这会产生什么样的误导。后来会发现这一点。