I'm trying to hook lua-scripts to my entities, where several entities of the same type want to use a separate instance of the same script. Problem is, when I run two or more scripts and use any C-api functionality, I get an access violation after some time. I'm guessing some kind of stack corruption occurs but I'm not sure. The application is single-threaded but uses lua_newthread for each entity, and I then use lua_resume on each new thread for when I want the scripts to run. The code looks like this.
Script 1
function Update(dt, owner)
print("Script 1")
pos = GetPosition(owner)
end
Script 2
function Update(dt, owner)
print("Script 2")
end
GetPosition()
static int GetPosition(lua_State* L)
{
Core::Entity entity = lua_tonumber(L, 1);
Core::TransformationComponent* tc = WGETC<Core::TransformationComponent>(entity);
lua_newtable(L);
for (int i = 0; i < 2; i++)
{
lua_pushnumber(L, tc->position[i]);
lua_rawseti(L, -2, i);
}
return 1;
}
How I create new lua threads (m_luaState is the global parent state to which I bind all my functions):
lua_State* LuaCore::CreateThread(std::string file)
{
lua_State* newState = lua_newthread(m_luaState);
lua_newtable(newState); //new globals table
lua_newtable(newState); //metatable
lua_pushliteral(newState, "__index");
lua_pushvalue(newState, LUA_GLOBALSINDEX); //original globals
lua_settable(newState, -3);
lua_setmetatable(newState, -2);
lua_replace(newState, LUA_GLOBALSINDEX); //replace newState's globals
luaL_dofile(newState, file.c_str());
return newState;
}
How each script is called:
lua_State* ls = GetChildState(stateIndex)
lua_pushstring(ls, functionName.c_str());
lua_gettable(ls, LUA_GLOBALSINDEX);
SimpleLuaCallData* slcd = (SimpleLuaCallData*)inData;
lua_pushnumber(ls, slcd->dt);
lua_pushnumber(ls, slcd->ownerID);
lua_pcall(ls, 2, 0, 0);
return nullptr;
If I remove the call to GetPosition from Script 1, the application runs without issue. Am I missing some kind of required clean-up or garbage collection problems? I'd like to try and avoid creating a new state for each entity, as that seems excessive and sharing globals via the core state is nice. lua_pcall doesn't produce any results. The application eventually stops running Script 1 and after a few more cycles it gets the access violation on
lua_gettable(ls, LUA_GLOBALSINDEX);
in the calling function.