Is it possible to execute one lua statement from the main program?

I am trying to embed a lua-based script in my game engine. I would like the scripts to have both blocking and non-blocking commands, for example:

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

Since "walkTo" must be "active" for more than one execution frame, I would like to be able to run 1 time instruction from the Java host instead of the whole function. This is because it would be unnecessary to have real multithreading, which is not needed.

If I could only execute 1 statement and keep the execution state “paused” until the next statement was executed, I could implement lock commands of type “walkTo”, checking if the command completed in the host, and if so, go to the next statement, otherwise wait until the next iteration of the frame.

Is there a way to execute 1 time statement from a Java host using LuaJ (or with any other Lua api), or am I forced to develop my own script engine using lex and yacc?

Any good idea is welcome, thanks!

+4
source share
2 answers

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

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

walk , . script 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 script=nil.

yield() , .

+2

, .

:

- 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 API Globals, , Globals , , .
+3

Source: https://habr.com/ru/post/1568513/


All Articles