Hey!
So, Android have a tendency to run multiple threads. Those are parallel units of execution, and you cannot, say Invoke Lua from other thread than one which runs Lua, because then you can (and will) get situation when you interrupt Lua in undefined state to execute your code and it will break both currently executing code and your code.
Same goes for Android UI - all interactions with Android UI should be performed when no other Android UI interactions are performed, i.e., on UI thread.
So, for that reason there are execution queues. Those are pieces of code, you can send to be executed on separate thread. With UI and Lua - specific threads.
There are examples provided in Native for both cases. My favourite example is in Project Template. First -
activity.runOnUiThread(new Runnable() { @Override public void run() { ......... } });
This allows to start some UI from Lua thread. It would run … on UI thread, allowing to create new widgets etc.
Another example is
CoronaEnvironment.getCoronaActivity().getRuntimeTaskDispatcher().send( new CoronaRuntimeTask() { @Override public void executeUsing(CoronaRuntime runtime) { LuaState L = runtime.getLuaState(); CoronaLua.newEvent( L, EVENT\_NAME ); L.pushString(message); L.setField(-2, "message"); try { CoronaLua.dispatchEvent( L, fListener, 0 ); } catch (Exception ignored) { } } } );
This code when run from any thread (including UI thread), would schedule message to be sent to Lua
Note, that in both cases, code is not immediately executed. It would “wait it’s turn” to be executed on appropriate thread.
To make users more conscious of this we have a bunch of comments around.
EDIT:
Couple remarks:
-
you can see that both cases use runtime to get “scheduler”. It is a good practice to check fi runtime still alive when running on UI thread (It’s in example code).
-
iOS/macOS has very similar mechanism. There all UI and Lua interactions must be ran from “Main” thread, both on same thread. Be careful, since many notifications can come on different threads.
This can be done in several ways:
dispatch\_async(dispatch\_get\_main\_queue(), ^{ ..... });
or
[self performSelectorOnMainThread:@selector(myMethod) withObject:nil waitUntilDone:NO];
or
[[NSOperationQueue mainQueue] addOperationWithBlock:^ { ..... }];
or others, including Swift’s (If you’ll manage to bridge Swift with Lua’s C)
DispatchQueue.main.async { .... }