繁体   English   中英

是否可以从宿主程序执行单个lua语句?

[英]Is it possible to execute a single lua statement from a host program?

我正在尝试将基于lua的脚本系统嵌入到我的游戏引擎中。 我希望脚本能够同时具有阻塞和非阻塞命令,例如:

character.walkTo(24, 359);  // Blocks until character arrives
c = 35; // Non blocking, execution goes on to the next statement

由于“walkTo”需要“活动”超过1帧执行,我希望能够从Java主机而不是整个函数运行1个语句。 这是因为拥有真正的多线程是不合适的,这是不需要的。

如果我只能执行1个语句,并保持执行状态“暂停”直到下一个语句执行,我将能够通过检查命令是否在主机中完成来实现像“walkTo”这样的阻塞命令,如果是,则去到下一个语句,否则,等到下一帧迭代。

有没有办法从带有LuaJ的Java主机(或任何其他Lua api)执行1个语句,或者我被迫使用lex和yacc开发自己的脚本引擎?

欢迎任何好主意,谢谢!

对于坚持这个问题的每个人的奖励回答。

这是我的确切解决方案:

- test.lua -

onLookAt = function()
    character:walkTo(234, 35)
    print("Arrived!")
end

- LuaTest.java -

public static void luaTest() {
    Globals g = JsePlatform.standardGlobals();
    g.load(new CoroutineLib());

    g.set("character", CoerceJavaToLua.coerce(new Character(g)));
    g.load(Gdx.files.internal("test.lua").reader(), "test.lua").call();
    g.load("co = coroutine.wrap(onLookAt)").call();
    g.get("co").call();
    try {
        // Simulate time that passes while the script is paused
        Thread.sleep(2000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    g.get("co").call();
}

public static class Character{
    Globals g;

    public Character(Globals g){
        this.g = g;
    }

    public void walkTo(int x, int y) {
        System.out.println("Started walking.");
        g.yield(LuaValue.NONE);
    }
}

- 输出 -

开始走路了。

(2秒钟后)

到了!

有一件事你应该非常小心:

  • 如果要完成此任务,请不要使用java的ScriptEngine接口。 ScriptEngine接口不提供用于获取生成所需的隐式分配的Globals实例的API,并且创建Globals的新实例并将其用于屈服显然是没有意义的。

好像你缺少异步模式。 如果在(24,359)处出现一个character时必须执行c=35 ,那么正确的方法是将function() c=35 end作为walk方法的第三个参数传递,并且你的引擎(执行实际的“行走”)将调用适当时回调。

character.walkTo(24, 359, function ()
    c = 35
end)

否则, walk可以安排步行到引擎并立即屈服,恢复正确的事件。 在这种情况下,您必须设置脚本worker-coroutine(您无法在主状态下生成)。

script = coroutine.wrap(function ()
    character.walkTo(24, 359) -- will yield and leave callable global 'script'
    c = 35
end)
script() -- resume first time
-- here script is over

...

-- this wrapper may be implemented in Lua or host language

function character.walkTo(x, y)
    engine.startActualWalkingTo(x, y)
    coroutine.yield() -- yields to host
    -- coroutine.resume() will continue here
end

...

-- somewhere in engine code (pseudo-code here)

for event in eventLoop do
    if character.x == endPoint.x and character.y == endPoint.y then
        script() -- resume again at c=35
    end
end

您可以随时使用script=nil取消脚本。

yield()有一些限制,请参考手册。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM