Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lua coroutines/threads support #88

Open
odraencoded opened this issue Jun 28, 2015 · 2 comments
Open

Lua coroutines/threads support #88

odraencoded opened this issue Jun 28, 2015 · 2 comments

Comments

@odraencoded
Copy link

Ok, I really could use some help using coroutines/threads in LuaD.

To begin with, if I create a coroutine like this:

lua.doString(`foo = coroutine.create(...)`);

How do I get the lua_State* or LuaState associated with it?

There is no LuaState conversion. You can't LuaObject.to!LuaState, and you can't LuaObject.to!lua_State* either. So you have to push the object and use the C function lua_tothread instead.

Turns out for whatever reason LuaObject doesn't expose its push method. It's marked as private. So you must push pushValue instead.

It took me some time but I was able to do it using this code:

lua_State* toLuaThread(LuaObject obj) {
    lua_State* L = obj.state;
    L.pushValue(obj);
    lua_State* thread_state = lua_tothread(L, -1);
    lua_pop(L, 1);
    return thread_state;
}
auto foo_d_wrapper = lua.get!LuaObject("foo");
lua_State* foo_c_thread = toLuaThread(foo_d_wrapper);

Now I got the thread, but there is no way to lua_resume from LuaD, so another C function has to be called.

int status = lua_resume(foo_c_thread, 0);

The lack of support so far was kind of frustrating but everything went well so far and I could use part of the library. But then I had to lua_yield from a function.

For lua_yield to work properly, its return value must be returned by the C function calling it. So something like this:

extern(C) int foo_calls_me(lua_State* L) {
    return lua_yield(L, 0);
}

Sure there must be a way I could do this with a D function, right?

Well, no. There is not.

LuaD will handle the returning values of D functions and C functions that don't comply with that signature, and that means it will either return 0 or some other calculated value that has nothing to do with lua_yield.

Well, at least I could reuse LuaD amazing templating code to turn that alien lua_State* into typed arguments, right?

Nope. Same reason as LuaObject.push, the extremely convenient functionWrapper is marked as private. Even argsError is marked as private. Everything is private here. This sucks D:

TL;DR: coroutine support please.

@odraencoded odraencoded changed the title Getting a thread Lua coroutines/threads support Jun 28, 2015
@daurnimator
Copy link

For lua_yield to work properly, its return value must be returned by the C function calling it.

I don't believe it does.
lua_yield will longjmp out; it never returns.

@JakobOvrum
Copy link
Owner

Indeed LuaD contains an intermediate layer of template code that operates on the Lua stack, but these primitives are intended to be internal. The goal of the library is to abstract away the Lua stack with higher level expressions, without sacrificing performance.

Coroutines are indeed a blind spot in the LuaD interface.

Until they are properly supported I recommend using the C API (exposed in the luad.c package) for functions that operate on coroutines, as mixing the C API and the LuaD API within the same function can be hazardous. Function pointers with the signature extern(C) int function(lua_State*) are given special handling in the LuaD API so it's possible to mix the two APIs at function level.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants