Question

I am writing Android app using LuaJ 3.0. How can I bind my Java object to specific LuaClosure(for whole script)?

Lua code:

local  = state or nil
state.foo("some string")

Java code:

Prototype prototype;

    try{

        InputStream stream = mContext.getResources().getAssets().open(LUA_ASSETS_DIRECTORY + "test.lua");
        prototype = LuaC.compile(stream, "script");

    } catch (IOException e) {

        return false;
    }

    LuaClosure closure = new LuaClosure(prototype, mLuaGlobals);
    // binding code
    closure.call();

I know that in LuaJ 2.0(but not in 3.0) there was LuaValue.setenv, and also I know about creating libs and binding them to Globals.

Was it helpful?

Solution

From LuaJ 3.0, the ability to modify closures are removed from the API. If you just want to bind your Java objects to specific Lua environment, you can create multiple Globals. You can then bind your Java objects to specific Globals, and create a closure from each of them:

Globals mLuaGlobals1 = JsePlatform.standardGlobals();
Globals mLuaGlobals2 = JsePlatform.standardGlobals();
Globals mLuaGlobals3 = JsePlatform.standardGlobals();

// binding code
mLuaGlobals1.rawset("state", CoerceJavaToLua.coerce(yourJavaObject));
mLuaGlobals2.rawset("state", CoerceJavaToLua.coerce(anotherJavaObject));
// We don't expose anything to mLuaGlobals3 in this example

// Create closures
// We use exact same prototype (script code) for each of them
LuaClosure closure1 = new LuaClosure(prototype, mLuaGlobals1);
LuaClosure closure2 = new LuaClosure(prototype, mLuaGlobals2);
LuaClosure closure3 = new LuaClosure(prototype, mLuaGlobals3);

closure1.call(); // yourJavaObject is exposed through "state" variable
closure2.call(); // anotherJavaObject is exposed through "state" variable
closure3.call(); // "state" variable is absent

Yes it's a silly solution, so if you really need the control of LuaClosure, downgrading to LuaJ 2.0.3 is the best option.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top