THAnimation* l_map_updateblueprint_getnextanim(lua_State *L, int& iIndex) { THAnimation *pAnim; lua_rawgeti(L, 10, iIndex); if(lua_type(L, -1) == LUA_TNIL) { lua_pop(L, 1); pAnim = luaT_new(L, THAnimation); lua_pushvalue(L, luaT_upvalueindex(2)); lua_setmetatable(L, -2); lua_createtable(L, 0, 2); lua_pushvalue(L, 1); lua_setfield(L, -2, "map"); lua_pushvalue(L, 11); lua_setfield(L, -2, "animator"); lua_setfenv(L, -2); lua_rawseti(L, 10, iIndex); } else { pAnim = luaT_testuserdata<THAnimation>(L, -1, luaT_upvalueindex(2)); lua_pop(L, 1); } ++iIndex; return pAnim; }
static int l_load_music_async(lua_State *L) { size_t iLength; const uint8_t *pData = luaT_checkfile(L, 1, &iLength); luaL_checktype(L, 2, LUA_TFUNCTION); SDL_RWops* rwop = SDL_RWFromConstMem(pData, (int)iLength); lua_settop(L, 2); load_music_async_t *async = luaT_new(L, load_music_async_t); lua_pushlightuserdata(L, async); lua_pushvalue(L, -2); lua_settable(L, LUA_REGISTRYINDEX); async->L = L; async->music = nullptr; async->rwop = rwop; async->err = nullptr; lua_createtable(L, 2, 0); lua_pushthread(L); lua_rawseti(L, -2, 1); lua_pushvalue(L, 2); lua_rawseti(L, -2, 2); luaT_stdnew<music_t>(L, luaT_environindex, true); lua_pushvalue(L, 1); luaT_setenvfield(L, -2, "data"); lua_rawseti(L, -2, 3); lua_settable(L, LUA_REGISTRYINDEX); /* In registry: [light userdata async] -> [full userdata async] [full userdata async] -> { [1] = callback_thread, [2] = callback_function, [3] = empty music_t userdata, } New thread will load music, and inform the main loop, which will then call the callback and remove the new entries from the registry. */ SDL_CreateThread(load_music_async_thread, "music_thread", async); return 0; }