From: John L. <jr...@us...> - 2007-12-13 06:23:59
|
Update of /cvsroot/wxlua/wxLua/modules/wxlua/src In directory sc8-pr-cvs9.sourceforge.net:/tmp/cvs-serv11381/wxLua/modules/wxlua/src Modified Files: wxlbind.cpp wxlcallb.cpp wxlstate.cpp Log Message: Second try at really allowing pushing the same object, but with different tags by tracking the userdata and have it fully clean up after itself. Index: wxlstate.cpp =================================================================== RCS file: /cvsroot/wxlua/wxLua/modules/wxlua/src/wxlstate.cpp,v retrieving revision 1.150 retrieving revision 1.151 diff -C2 -d -r1.150 -r1.151 *** wxlstate.cpp 13 Dec 2007 00:47:51 -0000 1.150 --- wxlstate.cpp 13 Dec 2007 06:23:55 -0000 1.151 *************** *** 629,645 **** } ! bool LUACALL wxluaO_deletegcobject(lua_State *L, void *obj_ptr, int flags) { if (obj_ptr == 0) return false; ! // No derived methods and remove weak refs to it ! if (WXLUA_HASBIT(flags, wxLUA_REMOVE_OBJECT)) ! { ! wxlua_removederivedmethod(L, obj_ptr); ! wxluaO_untrackweakobject(L, obj_ptr); ! } ! if (WXLUA_HASBIT(flags, wxLUA_UNDELETE_OBJECT|wxLUA_DELETE_OBJECT)) { lua_pushlightuserdata(L, &wxlua_lreg_gcobjects_key); // push key lua_rawget(L, LUA_REGISTRYINDEX); // pop key, push value (table) --- 629,645 ---- } ! bool LUACALL wxluaO_deletegcobject(lua_State *L, void* udata, void *obj_ptr, int flags) { if (obj_ptr == 0) return false; ! bool delete_all = WXLUA_HASBIT(flags, WXLUA_DELETE_OBJECT_ALL); ! // Remove the weak ref to it ! int udata_count = wxluaO_untrackweakobject(L, delete_all ? NULL : udata, obj_ptr); ! ! if (delete_all || (udata_count < 2)) { + wxlua_removederivedmethods(L, obj_ptr); + lua_pushlightuserdata(L, &wxlua_lreg_gcobjects_key); // push key lua_rawget(L, LUA_REGISTRYINDEX); // pop key, push value (table) *************** *** 651,659 **** { // delete the real object for the case where it's encapsulated ! if (WXLUA_HASBIT(flags, wxLUA_DELETE_OBJECT)) ! { ! wxObject *wxobj_ptr = (wxObject*)lua_touserdata(L, -1); ! delete wxobj_ptr; ! } lua_pop(L, 1); // pop lightuserdata --- 651,657 ---- { // delete the real object for the case where it's encapsulated ! ! wxObject *wxobj_ptr = (wxObject*)lua_touserdata(L, -1); ! delete wxobj_ptr; lua_pop(L, 1); // pop lightuserdata *************** *** 671,674 **** --- 669,673 ---- // no error message since we're called from wxluabind__gc_wxLuaBindClass // automatically for all our objects and this table stores which ones to delete + // so we don't want to have to check first and then call this. lua_pop(L, 2); // pop nil and delobj } *************** *** 678,681 **** --- 677,707 ---- } + bool LUACALL wxluaO_undeletegcobject(lua_State *L, void *obj_ptr) + { + if (obj_ptr == 0) return false; + + lua_pushlightuserdata(L, &wxlua_lreg_gcobjects_key); // push key + lua_rawget(L, LUA_REGISTRYINDEX); // pop key, push value (table) + + lua_pushlightuserdata(L, obj_ptr); // push key + lua_rawget(L, -2); // get t[key] = value, pops key + + if (lua_islightuserdata(L, -1)) // is the wxObject* we delete + { + lua_pop(L, 1); // pop lightuserdata + + lua_pushlightuserdata(L, obj_ptr); // push key + lua_pushnil(L); // push value + lua_rawset(L, -3); // set t[key] = value, pops key and value + + lua_pop(L, 1); // pop delobj table + return true; + } + else + lua_pop(L, 2); // pop nil and delobj + + return false; + } + bool LUACALL wxluaO_isgcobject(lua_State *L, void *obj_ptr) { *************** *** 740,744 **** lua_setmetatable(L, -2); // via the metatable lua_rawset(L, -3); ! lua_pushlightuserdata(L, obj_ptr); // get the table back lua_rawget(L, -2); --- 766,770 ---- lua_setmetatable(L, -2); // via the metatable lua_rawset(L, -3); ! lua_pushlightuserdata(L, obj_ptr); // get the table back lua_rawget(L, -2); *************** *** 752,756 **** lua_pop(L, 1); // pop nil } ! lua_pushnumber(L, tag); lua_pushvalue(L, ABS_LUA_STKIDX(udata_stack_idx, 3)); // push the Lua userdata as the value (note: weak valued table) --- 778,782 ---- lua_pop(L, 1); // pop nil } ! lua_pushnumber(L, tag); lua_pushvalue(L, ABS_LUA_STKIDX(udata_stack_idx, 3)); // push the Lua userdata as the value (note: weak valued table) *************** *** 759,763 **** } ! bool LUACALL wxluaO_untrackweakobject(lua_State *L, void *obj_ptr) { lua_pushlightuserdata(L, &wxlua_lreg_weakobjects_key); // push key --- 785,789 ---- } ! int LUACALL wxluaO_untrackweakobject(lua_State *L, void* udata, void *obj_ptr) { lua_pushlightuserdata(L, &wxlua_lreg_weakobjects_key); // push key *************** *** 767,770 **** --- 793,799 ---- lua_rawget(L, -2); // get t[key] = value; pop key push value + int count = 0; + bool cleared_udata = false; + if (lua_istable(L, -1)) { *************** *** 774,794 **** { // value = -1, key = -2, table = -3 ! lua_pushnil(L); ! lua_setmetatable(L, -2); // remove value's metatable ! lua_pop(L, 1); // pop value, leave key for next iteration } lua_pop(L, 1); // pop obj_ptr table ! lua_pushlightuserdata(L, (void*)obj_ptr); // push key ! lua_pushnil(L); // push value ! lua_rawset(L, -3); // set t[key] = nil; pops key and value lua_pop(L, 1); // pop objects table - return true; } else lua_pop(L, 2); // pop nil and weakobj table ! return false; } --- 803,843 ---- { // value = -1, key = -2, table = -3 ! void *u = lua_touserdata(L, -1); ! ++count; ! ! if ((udata == NULL) || (udata == u)) ! { ! lua_pushnil(L); ! lua_setmetatable(L, -2); // remove value's metatable ! } ! ! if (udata == u) ! { ! cleared_udata = true; ! lua_pop(L, 1); // pop value ! ! lua_pushvalue(L, -1); // copy key for next iteration ! lua_pushnil(L); ! lua_rawset(L, -4); // set t[key] = nil to remove it ! } ! else ! lua_pop(L, 1); // pop value, leave key for next iteration } lua_pop(L, 1); // pop obj_ptr table ! if ((udata == NULL) || (count == 0) || ((count == 1) && cleared_udata)) ! { ! lua_pushlightuserdata(L, (void*)obj_ptr); // push key ! lua_pushnil(L); // push value ! lua_rawset(L, -3); // set t[key] = nil; pops key and value ! } ! lua_pop(L, 1); // pop objects table } else lua_pop(L, 2); // pop nil and weakobj table ! return count; } *************** *** 1566,1570 **** return found; } ! bool LUACALL wxlua_removederivedmethod(lua_State* L, void *pObject) { bool found = false; --- 1615,1619 ---- return found; } ! bool LUACALL wxlua_removederivedmethods(lua_State* L, void *obj_ptr) { bool found = false; *************** *** 1573,1577 **** lua_rawget( L, LUA_REGISTRYINDEX ); // pop key, push table ! lua_pushlightuserdata(L, (void *)pObject); lua_rawget(L, -2); // pop key, push table or nil --- 1622,1626 ---- lua_rawget( L, LUA_REGISTRYINDEX ); // pop key, push table ! lua_pushlightuserdata(L, (void *)obj_ptr); lua_rawget(L, -2); // pop key, push table or nil *************** *** 1596,1600 **** lua_pop(L, 1); // pop the obj table ! lua_pushlightuserdata(L, (void *)pObject); // push key lua_pushnil(L); // push value, to remove it lua_rawset(L, -3); // set t[key] = value; pop key and value --- 1645,1649 ---- lua_pop(L, 1); // pop the obj table ! lua_pushlightuserdata(L, (void *)obj_ptr); // push key lua_pushnil(L); // push value, to remove it lua_rawset(L, -3); // set t[key] = value; pop key and value *************** *** 2756,2763 **** } ! bool wxLuaState::DeleteGCObject(void *obj_ptr, int flags) { wxCHECK_MSG(Ok() && obj_ptr, false, wxT("Invalid wxLuaState or object")); ! return wxluaO_deletegcobject(M_WXLSTATEDATA->m_lua_State, obj_ptr, flags); } --- 2805,2812 ---- } ! bool wxLuaState::DeleteGCObject(void* udata, void *obj_ptr, int flags) { wxCHECK_MSG(Ok() && obj_ptr, false, wxT("Invalid wxLuaState or object")); ! return wxluaO_deletegcobject(M_WXLSTATEDATA->m_lua_State, udata, obj_ptr, flags); } *************** *** 3125,3149 **** } ! bool wxLuaState::SetDerivedMethod(void *pObject, const char *method_name, wxLuaObject* wxlObj) { ! wxCHECK_MSG(Ok() && pObject, false, wxT("Invalid wxLuaState or object to set derived method for.")); ! return wxlua_setderivedmethod(M_WXLSTATEDATA->m_lua_State, pObject, method_name, wxlObj); } ! bool wxLuaState::HasDerivedMethod(void *pObject, const char *method_name, bool push_method) const { wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState")); ! return wxlua_hasderivedmethod(M_WXLSTATEDATA->m_lua_State, pObject, method_name, push_method); } ! bool wxLuaState::RemoveDerivedMethod(void *pObject) const { ! wxCHECK_MSG(Ok() && pObject, false, wxT("Invalid wxLuaState or object to remove.")); ! return wxlua_removederivedmethod(M_WXLSTATEDATA->m_lua_State, pObject); } ! wxLuaState wxLuaState::GetDerivedMethodState(void *pObject, const char *method) { ! wxCHECK_MSG(pObject, wxNullLuaState, wxT("Invalid object to wxLuaState::GetDerivedMethod")); wxHashMapLuaState::iterator it; --- 3174,3198 ---- } ! bool wxLuaState::SetDerivedMethod(void *obj_ptr, const char *method_name, wxLuaObject* wxlObj) { ! wxCHECK_MSG(Ok() && obj_ptr, false, wxT("Invalid wxLuaState or object to set derived method for.")); ! return wxlua_setderivedmethod(M_WXLSTATEDATA->m_lua_State, obj_ptr, method_name, wxlObj); } ! bool wxLuaState::HasDerivedMethod(void *obj_ptr, const char *method_name, bool push_method) const { wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState")); ! return wxlua_hasderivedmethod(M_WXLSTATEDATA->m_lua_State, obj_ptr, method_name, push_method); } ! bool wxLuaState::RemoveDerivedMethods(void *obj_ptr) const { ! wxCHECK_MSG(Ok() && obj_ptr, false, wxT("Invalid wxLuaState or object to remove.")); ! return wxlua_removederivedmethods(M_WXLSTATEDATA->m_lua_State, obj_ptr); } ! wxLuaState wxLuaState::GetDerivedMethodState(void *obj_ptr, const char *method) { ! wxCHECK_MSG(obj_ptr, wxNullLuaState, wxT("Invalid object to wxLuaState::GetDerivedMethod")); wxHashMapLuaState::iterator it; *************** *** 3152,3156 **** { wxLuaState wxlState((wxLuaState*)it->second); ! if (wxlState.HasDerivedMethod(pObject, method, false)) return wxlState; } --- 3201,3205 ---- { wxLuaState wxlState((wxLuaState*)it->second); ! if (wxlState.HasDerivedMethod(obj_ptr, method, false)) return wxlState; } Index: wxlbind.cpp =================================================================== RCS file: /cvsroot/wxlua/wxLua/modules/wxlua/src/wxlbind.cpp,v retrieving revision 1.104 retrieving revision 1.105 diff -C2 -d -r1.104 -r1.105 *** wxlbind.cpp 13 Dec 2007 00:47:51 -0000 1.104 --- wxlbind.cpp 13 Dec 2007 06:23:55 -0000 1.105 *************** *** 569,575 **** int LUACALL wxLua_wxluabind_delete(lua_State *L) { ! void* self = wxlua_touserdata(L, 1, false); // if removed from tracked mem list, reset the tag so that gc() is not called on this object. ! if ((self != NULL) && wxluaO_deletegcobject(L, self, wxLUA_DELETE_REMOVE_OBJECT)) { lua_pushnil(L); --- 569,576 ---- int LUACALL wxLua_wxluabind_delete(lua_State *L) { ! void* udata = lua_touserdata(L, 1); ! void* obj_ptr = wxlua_touserdata(L, 1, false); // if removed from tracked mem list, reset the tag so that gc() is not called on this object. ! if ((obj_ptr != NULL) && wxluaO_deletegcobject(L, udata, obj_ptr, WXLUA_DELETE_OBJECT_ALL)) { lua_pushnil(L); *************** *** 579,584 **** { // leave this printf since we really want to know if this happens ! wxPrintf(wxT("Unable to call wxuserdata:delete() on object %p\n"), self); ! wxlua_error(L, wxString::Format(wxT("Unable to call wxuserdata:delete() on object %p"), self)); } --- 580,585 ---- { // leave this printf since we really want to know if this happens ! wxPrintf(wxT("Unable to call wxuserdata:delete() on object %p\n"), obj_ptr); ! wxlua_error(L, wxString::Format(wxT("Unable to call wxuserdata:delete() on object %p"), obj_ptr)); } *************** *** 596,603 **** if ((wxlClass != NULL) && wxlua_iswxuserdata(L, 1) && (wxluaT_gettag(L, 1) == *wxlClass->class_tag)) { ! void* key = wxlua_touserdata(L, 1, true); // clean up the rest of this, this won't error if the key doesn't exist ! wxluaO_deletegcobject(L, key, wxLUA_DELETE_REMOVE_OBJECT); } --- 597,605 ---- if ((wxlClass != NULL) && wxlua_iswxuserdata(L, 1) && (wxluaT_gettag(L, 1) == *wxlClass->class_tag)) { ! void* udata = lua_touserdata(L, 1); ! void* obj_ptr = wxlua_touserdata(L, 1, true); // clean up the rest of this, this won't error if the key doesn't exist ! wxluaO_deletegcobject(L, udata, obj_ptr, WXLUA_DELETE_OBJECT_LAST); } *************** *** 1225,1231 **** if (wxlObject->objPtr != 0) ! wxlState.wxluaT_PushUserTag(wxlObject->objPtr, *wxlObject->class_tag, true); else ! wxlState.wxluaT_PushUserTag(*wxlObject->pObjPtr, *wxlObject->class_tag, true); lua_rawset(L, -3); --- 1227,1233 ---- if (wxlObject->objPtr != 0) ! wxluaT_pushusertag(L, wxlObject->objPtr, *wxlObject->class_tag, true); else ! wxluaT_pushusertag(L, *wxlObject->pObjPtr, *wxlObject->class_tag, true); lua_rawset(L, -3); Index: wxlcallb.cpp =================================================================== RCS file: /cvsroot/wxlua/wxLua/modules/wxlua/src/wxlcallb.cpp,v retrieving revision 1.50 retrieving revision 1.51 diff -C2 -d -r1.50 -r1.51 *** wxlcallb.cpp 13 Dec 2007 00:47:51 -0000 1.50 --- wxlcallb.cpp 13 Dec 2007 06:23:55 -0000 1.51 *************** *** 230,236 **** { // clear the metatable for the copy of the we are tracking (clears it for all copies too) ! wxluaO_deletegcobject(m_wxlState.GetLuaState(), m_window, wxLUA_REMOVE_OBJECT); ! // Now remove the object since it's gone ! m_wxlState.DeleteGCObject(m_window, wxLUA_REMOVE_OBJECT); // Clear our own pointer to this window m_wxlState.RemoveTrackedWindow(m_window); --- 230,236 ---- { // clear the metatable for the copy of the we are tracking (clears it for all copies too) ! wxluaO_untrackweakobject(m_wxlState.GetLuaState(), NULL, m_window); ! wxlua_removederivedmethods(m_wxlState.GetLuaState(), m_window); ! // Clear our own pointer to this window m_wxlState.RemoveTrackedWindow(m_window); |