From: John L. <jr...@us...> - 2007-03-21 23:43:16
|
Update of /cvsroot/wxlua/wxLua/modules/wxlua/src In directory sc8-pr-cvs9.sourceforge.net:/tmp/cvs-serv16781/wxLua/modules/wxlua/src Modified Files: wxlstate.cpp Log Message: Use luaL_ref and luaL_unref in tinsert and tremove so we can remove the m_unusedReferences array in the wxLuaStateData. All tXXX functions are now C functions and don't depend on the wxLuaState. Index: wxlstate.cpp =================================================================== RCS file: /cvsroot/wxlua/wxLua/modules/wxlua/src/wxlstate.cpp,v retrieving revision 1.91 retrieving revision 1.92 diff -C2 -d -r1.91 -r1.92 *** wxlstate.cpp 19 Mar 2007 03:47:21 -0000 1.91 --- wxlstate.cpp 21 Mar 2007 23:43:12 -0000 1.92 *************** *** 267,272 **** // ---------------------------------------------------------------------------- ! // txxx functions to make lua calls easier // ---------------------------------------------------------------------------- bool LUACALL wxLua_lua_tget(lua_State *L, int wxlref_index) { --- 267,322 ---- // ---------------------------------------------------------------------------- ! // txxx functions to make wxLua registry table calls easier // ---------------------------------------------------------------------------- + + // Note about luaL_ref and luaL_unref. + // ref creates integer numbers from 1 to ... + // unref uses t[0] to hold the last unused reference and when you call unref + // again the next unused ref points back to the first and t[0] points to the + // last unrefed key. + // eg. create 5 refs, get refs 1,2,3,4,5, then call unref on 3 then 4 then + // call ref 3 times and the new references will be 4, 3, 6 + + int wxLua_lua_tinsert(lua_State* L, int stack_idx) + { + if (lua_isnone(L, stack_idx)) // nothing on stack to insert + return LUA_REFNIL; + + if (lua_isnil(L, stack_idx)) // don't bother inserting nil + { + lua_pop(L, 1); + return LUA_REFNIL; + } + + lua_pushvalue(L, stack_idx); // get value to store + int nTop = lua_gettop(L); // this is where the value is + + wxLua_lua_push_wxLuaReferences(L); // push name of wxLua's reference registry table + lua_rawget(L, LUA_REGISTRYINDEX); // pop key, push result (the refs table) + + lua_pushvalue(L, nTop); // push value to store + + int table_idx = luaL_ref(L, -2); // create unique integer reference + // in our refs table + + lua_pop(L, 3); // pop value + + return table_idx; + } + + bool wxLua_lua_tremove(lua_State* L, int wxlref_index) + { + if (wxlref_index == LUA_REFNIL) + return true; + + wxLua_lua_push_wxLuaReferences(L); + lua_rawget(L, LUA_REGISTRYINDEX); // pop key, push result (the refs table) + + luaL_unref(L, -1, wxlref_index); // remove key and value in refs table + // note: this key will be used for the next tinsert + lua_pop(L, -1); // pop the refs table + return true; + } + bool LUACALL wxLua_lua_tget(lua_State *L, int wxlref_index) { *************** *** 277,293 **** } ! int table_count; ! bool ret = false; // false indicates index out of range ! ! wxLua_lua_push_wxLuaReferences(L); ! lua_rawget(L, LUA_REGISTRYINDEX); // pop key, push result (refs table) ! lua_pushliteral(L, "n"); // push 'n' as key ! lua_rawget(L, -2); // pop key, push result ! table_count = (int)lua_tonumber(L, -1); // get result value lua_pop(L, 1); // pop result // ensure ref index in range of table ! if ((wxlref_index > 0) && (wxlref_index <= table_count)) { lua_rawgeti(L, -1, wxlref_index); // push result --- 327,345 ---- } ! wxLua_lua_push_wxLuaReferences(L); // push name of wxLua's reference registry table ! lua_rawget(L, LUA_REGISTRYINDEX); // pop key, push result (the refs table) ! /* ! // Note: We used to check that wxlref_index <= length of the table and ! // if it wasn't pushnil. I don't think this is a good idea since ! // the table may have holes in it temporarily. -JL ! bool ret = false; ! lua_pushliteral(L, "n"); // push the key where we store table length ! lua_rawget(L, -2); // pop key, push table value ! int len = (int)lua_tonumber(L, -1); // get result value the length lua_pop(L, 1); // pop result // ensure ref index in range of table ! if ((wxlref_index > 0) && (wxlref_index <= len)) { lua_rawgeti(L, -1, wxlref_index); // push result *************** *** 296,334 **** else lua_pushnil(L); // push result ! lua_remove(L, -2); // balance stack ! ! return ret; ! } ! ! int LUACALL wxLua_lua_tgetn(lua_State *L) ! { ! wxLua_lua_push_wxLuaReferences(L); ! lua_rawget(L, LUA_REGISTRYINDEX); // pop key, push result (refs table) ! ! lua_pushliteral(L, "n"); ! lua_rawget(L, -2); ! int n = 0; ! if (lua_isnumber(L, -1)) ! { ! n = (int)lua_tonumber(L, -1); ! } ! else ! { ! // must count elements ! n = 0; ! for (;;) ! { ! lua_rawgeti(L, -2, ++n); ! bool is_nil = lua_isnil(L, -1); ! lua_pop(L, 1); ! if (is_nil) ! break; ! } ! --n; ! } ! lua_pop(L, 2); ! return n; } --- 348,357 ---- else lua_pushnil(L); // push result + */ ! lua_rawgeti(L, -1, wxlref_index); // get table value at wxlref_index ! lua_remove(L, -2); // remove wxLua's registry table ! return !lua_isnil(L, -1); // return if table has a valid value at index } *************** *** 404,407 **** --- 427,476 ---- } + int wxLua_lua_tnewtag(lua_State* L) + { + lua_newtable(L); // create a table for our new tag + lua_pushvalue(L, -1); // push a copy of our new table onto the top of the stack + int tag = wxLua_lua_tinsert(L, -1); // insert the table into the wxLuaReferences registry table + + lua_pushliteral(L, "tag"); // add t["tag"] = tag to new table + lua_pushnumber(L, tag); + lua_rawset(L, -3); + lua_pop(L, 1); // pop our new table + return tag; + } + + int wxLua_lua_tnewweaktag(lua_State* L, bool weak_keys, bool weak_values) + { + lua_newtable(L); // main table + lua_newtable(L); // metatable + + // for metatable.__weak = k for weak keys, v for weak values + if (weak_keys) + { + if (weak_values) + lua_pushliteral(L, "kv"); + else + lua_pushliteral(L, "k"); + } + else + { + if (weak_values) + lua_pushliteral(L, "v"); + else + lua_pushnil(L); + } + + lua_pushliteral(L, "__mode"); + lua_rawset(L, -3); // set mode of main table + lua_setmetatable(L, -2); // via the metatable + lua_pushvalue(L, -1); + int tag = wxLua_lua_tinsert(L, -1); + lua_pushliteral(L, "tag"); + lua_pushnumber(L, tag); + lua_rawset(L, -3); + lua_pop(L, 1); + return tag; + } + void LUACALL wxLua_lua_tsettag(lua_State *L, int tag) { *************** *** 2027,2084 **** { wxCHECK_MSG(Ok(), LUA_REFNIL, wxT("Invalid wxLuaState")); ! lua_State* L = M_WXLSTATEDATA->m_lua_State; ! ! if (lua_isnone(L, stack_idx)) ! return LUA_REFNIL; ! ! if (lua_isnil(L, stack_idx)) ! { ! lua_pop(L, 1); ! return LUA_REFNIL; ! } ! ! int table_idx = 0; ! ! lua_pushvalue(L, stack_idx); // get value to store ! int nTop = lua_gettop(L); ! ! wxLua_lua_push_wxLuaReferences(L); ! lua_rawget(L, LUA_REGISTRYINDEX); // pop key, push result ! ! if (M_WXLSTATEDATA->m_wxlStateData->m_unusedReferenceIndexes.GetCount() > 0) ! { ! // Use an available, but previously used and removed index from the ! // wxLuaReferences registry table so the index doesn't grow too large. ! // see tremove. ! table_idx = M_WXLSTATEDATA->m_wxlStateData->m_unusedReferenceIndexes.Item(0); ! M_WXLSTATEDATA->m_wxlStateData->m_unusedReferenceIndexes.RemoveAt(0); ! ! lua_pushvalue(L, nTop); // push value to store ! lua_rawseti(L, -2, table_idx); // store value, pop value ! } ! else ! { ! lua_pushliteral(L, "n"); // push 'n' as key ! lua_rawget(L, -2); // pop key, push result ! if (lua_isnil(L, -1)) // table not used before? ! table_idx = 0; ! else ! table_idx = (int)lua_tonumber(L, -1); // get result value ! ! lua_pop(L, 1); // pop result ! ! table_idx++; // next unallocated index ! ! lua_pushvalue(L, nTop); // push value to store ! lua_rawseti(L, -2, table_idx); // store value, pop value ! ! lua_pushliteral(L, "n"); // push key ! lua_pushnumber(L, table_idx); // push value ! lua_rawset(L, -3); // pop key, value ! } ! ! lua_pop(L, 3); // restore stack ! ! return table_idx; } --- 2096,2100 ---- { wxCHECK_MSG(Ok(), LUA_REFNIL, wxT("Invalid wxLuaState")); ! return wxLua_lua_tinsert(M_WXLSTATEDATA->m_lua_State, stack_idx); } *************** *** 2086,2117 **** { wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState")); ! ! if (wxlref_index == LUA_REFNIL) ! return true; ! ! lua_State* L = M_WXLSTATEDATA->m_lua_State; ! ! int table_count; ! bool ret = false; // false indicates index out of range ! ! wxLua_lua_push_wxLuaReferences(L); ! lua_rawget(L, LUA_REGISTRYINDEX); // pop key, push result (refs table) ! ! lua_pushliteral(L, "n"); // push 'n' as key ! lua_rawget(L, -2); // pop key, push result ! table_count = (int)lua_tonumber(L, -1); // get result value ! lua_pop(L, 1); // pop result ! ! // ensure ref index in range of table ! if ((wxlref_index > 0) && (wxlref_index <= table_count)) ! { ! lua_pushnil(L); // push nil as value ! lua_rawseti(L, -2, wxlref_index); // set table, pop value ! // add the now available index to use for the next tinsert ! M_WXLSTATEDATA->m_wxlStateData->m_unusedReferenceIndexes.Add(wxlref_index); ! ret = true; ! } ! lua_pop(L, 1); // clean up stack ! return ret; } --- 2102,2106 ---- { wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState")); ! return wxLua_lua_tremove(M_WXLSTATEDATA->m_lua_State, wxlref_index); } *************** *** 2119,2131 **** { wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState")); ! lua_State* L = M_WXLSTATEDATA->m_lua_State; ! return wxLua_lua_tget(L, wxlref_index); ! } ! ! int wxLuaState::tgetn() ! { ! wxCHECK_MSG(Ok(), 0, wxT("Invalid wxLuaState")); ! lua_State* L = M_WXLSTATEDATA->m_lua_State; ! return wxLua_lua_tgetn(L); } --- 2108,2112 ---- { wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState")); ! return wxLua_lua_tget(M_WXLSTATEDATA->m_lua_State, wxlref_index); } *************** *** 2133,2138 **** { wxCHECK_RET(Ok(), wxT("Invalid wxLuaState")); ! lua_State* L = M_WXLSTATEDATA->m_lua_State; ! wxLua_lua_terror(L, errorMsg); } --- 2114,2118 ---- { wxCHECK_RET(Ok(), wxT("Invalid wxLuaState")); ! wxLua_lua_terror(M_WXLSTATEDATA->m_lua_State, errorMsg); } *************** *** 2140,2145 **** { wxCHECK_RET(Ok(), wxT("Invalid wxLuaState")); ! lua_State* L = M_WXLSTATEDATA->m_lua_State; ! wxLua_lua_tpushusertag(L, u, tag); } --- 2120,2124 ---- { wxCHECK_RET(Ok(), wxT("Invalid wxLuaState")); ! wxLua_lua_tpushusertag(M_WXLSTATEDATA->m_lua_State, u, tag); } *************** *** 2147,2152 **** { wxCHECK_MSG(Ok(), TLUA_NOTAG, wxT("Invalid wxLuaState")); ! lua_State* L = M_WXLSTATEDATA->m_lua_State; ! return wxLua_lua_ttag(L, stack_idx); } --- 2126,2130 ---- { wxCHECK_MSG(Ok(), TLUA_NOTAG, wxT("Invalid wxLuaState")); ! return wxLua_lua_ttag(M_WXLSTATEDATA->m_lua_State, stack_idx); } *************** *** 2154,2159 **** { wxCHECK_MSG(Ok(), NULL, wxT("Invalid wxLuaState")); ! lua_State* L = M_WXLSTATEDATA->m_lua_State; ! return wxLua_lua_ttouserdata(L, stack_idx, reset); } --- 2132,2136 ---- { wxCHECK_MSG(Ok(), NULL, wxT("Invalid wxLuaState")); ! return wxLua_lua_ttouserdata(M_WXLSTATEDATA->m_lua_State, stack_idx, reset); } *************** *** 2161,2174 **** { wxCHECK_MSG(Ok(), TLUA_NOTAG, wxT("Invalid wxLuaState")); ! lua_State* L = M_WXLSTATEDATA->m_lua_State; ! ! lua_newtable(L); ! lua_pushvalue(L, -1); ! int tag = tinsert(-1); ! lua_pushliteral(L, "tag"); ! lua_pushnumber(L, tag); ! lua_rawset(L, -3); ! lua_pop(L, 1); ! return tag; } --- 2138,2142 ---- { wxCHECK_MSG(Ok(), TLUA_NOTAG, wxT("Invalid wxLuaState")); ! return wxLua_lua_tnewtag(M_WXLSTATEDATA->m_lua_State); } *************** *** 2176,2210 **** { wxCHECK_MSG(Ok(), TLUA_NOTAG, wxT("Invalid wxLuaState")); ! lua_State* L = M_WXLSTATEDATA->m_lua_State; ! ! lua_newtable(L); // main table ! lua_newtable(L); // metatable ! ! // for metatable.__weak = k for weak keys, v for weak values ! if (weak_keys) ! { ! if (weak_values) ! lua_pushliteral(L, "kv"); ! else ! lua_pushliteral(L, "k"); ! } ! else ! { ! if (weak_values) ! lua_pushliteral(L, "v"); ! else ! lua_pushnil(L); ! } ! ! lua_pushliteral(L, "__mode"); ! lua_rawset(L, -3); // set mode of main table ! lua_setmetatable(L, -2); // via the metatable ! lua_pushvalue(L, -1); ! int tag = tinsert(-1); ! lua_pushliteral(L, "tag"); ! lua_pushnumber(L, tag); ! lua_rawset(L, -3); ! lua_pop(L, 1); ! return tag; } --- 2144,2148 ---- { wxCHECK_MSG(Ok(), TLUA_NOTAG, wxT("Invalid wxLuaState")); ! return wxLua_lua_tnewweaktag(M_WXLSTATEDATA->m_lua_State, weak_keys, weak_values); } *************** *** 2212,2217 **** { wxCHECK_RET(Ok(), wxT("Invalid wxLuaState")); ! lua_State* L = M_WXLSTATEDATA->m_lua_State; ! wxLua_lua_tsettag(L, tag); } --- 2150,2154 ---- { wxCHECK_RET(Ok(), wxT("Invalid wxLuaState")); ! wxLua_lua_tsettag(M_WXLSTATEDATA->m_lua_State, tag); } *************** *** 2219,2224 **** { wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState")); ! lua_State* L = M_WXLSTATEDATA->m_lua_State; ! return wxLua_lua_tsettagmethod(L, tag, method, func, pClass); } --- 2156,2160 ---- { wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState")); ! return wxLua_lua_tsettagmethod(M_WXLSTATEDATA->m_lua_State, tag, method, func, pClass); } |