Reputation: 1226
I am writing a library called LuaVM to manage the interaction between Lua Scripts and my own project using the Lua library.
I am searching a way to expose somewhat "local" coroutine variables. So I can access different values from different coroutines using the same "variable name". But as you probably know coroutines share the same global environment with their lua_State parent and all they other coroutines issued from the same lua_State.
For example I would like to expose the thisItem
global to each coroutine so each script (each one with it's own coroutine) could call thisItem
and get a different value, even if they are using the same lua_State parent and are nested.
So I tried different approach, such as exposing / unexposing the value using a stack, but none was "thread" proof indeed.
My last attempt was to associate the global thisItem
with a metatable where __index
and/or __call
keys were modified to call a function which in turn tried to return the right value.
Here is how I expose it
//-- Define a callback function
int LuaVM::DEBUGFUNCTION(lua_State *L)
{
//-- Do stuff to return the right value
return 1;
}
//-- Create callback metatable in the constructor
LuaVM::LuaVM()
{
//--Init Lua
mState = luaL_newstate();
luaL_openlibs(mState);
/* etc...*/
//-- Define the callback metatable
luaL_newmetatable(mState, "ThreadLocalMT");
lua_pushstring(mState, "__call");
lua_pushcclosure(mState, DEBUGFUNCTION,0);
lua_settable(mState, -3);
}
//-- Then define the exposeInstance function
template <class C>
bool LuaVM::exposeInstance(C* _ptr, /*other stuff*/ )
{
LuaObject<C>* ret = (LuaObject<C>*)lua_newuserdata(mState, sizeof(LuaObject<C>));
ret->ptr = _ptr;
luaL_getmetatable(mState, "ThreadLocalMT");
lua_setmetatable(mState, -2);
lua_setglobal(mState,"thisItem");
/* other stuff */
return true;
}
But it's not really what I was looking for... (I need to call thisItem()
instead of the variable thisItem
) and I'm wondering if there is a way to create a table to store all the values and return the right one using a less "tricky" solution.
I am not accustomed with threads nor with Lua C-api and so I need your help. There is maybe a better way to manage this problem in a multi-thread environment ?
Thank you
Upvotes: 0
Views: 329
Reputation: 41180
If you are using Lua 5.1.x, then you can use lua_setfenv
to set the environment of the coroutine (as described here). Use a table with the global bindings you want, and optionally with a metatable with an __index
of the usual globals _G
. This mechanism is described in the Lua 5.1 reference manual section 2.9 Environments
Things are a bit more complicated (for this use-case) in Lua 5.2; the relevant reference manual section is 2.2 – Environments and the Global Environment
Upvotes: 1