From: John L. <jr...@us...> - 2007-08-03 22:17:20
|
Update of /cvsroot/wxlua/wxLua/modules/wxlua/src In directory sc8-pr-cvs9.sourceforge.net:/tmp/cvs-serv21726/wxLua/modules/wxlua/src Modified Files: wxlbind.cpp wxlcallb.cpp wxlstate.cpp Log Message: Simplify the wxLuaWinDestroyCallback to reuse the table of objects instead of it's own and have windows push into Lua the same as other objects. Index: wxlstate.cpp =================================================================== RCS file: /cvsroot/wxlua/wxLua/modules/wxlua/src/wxlstate.cpp,v retrieving revision 1.127 retrieving revision 1.128 diff -C2 -d -r1.127 -r1.128 *** wxlstate.cpp 2 Aug 2007 23:08:57 -0000 1.127 --- wxlstate.cpp 3 Aug 2007 22:17:16 -0000 1.128 *************** *** 399,402 **** --- 399,417 ---- } + void LUACALL wxlua_tcleartrackedmetatable(lua_State *L, const void *u) + { + wxlua_pushkey_wxLuaObjects(L); + lua_rawget(L, LUA_REGISTRYINDEX); // pop key, push result (the object table) + lua_pushlightuserdata(L, (void*)u); + lua_rawget(L, -2); + if (lua_isuserdata(L, -1)) + { + lua_pushnil(L); + lua_setmetatable(L, -2); // set nil to metatable + } + + lua_pop(L, 2); // pop object table and [userdata or nil] + } + int LUACALL wxlua_ttag(lua_State *L, int stack_idx) { *************** *** 1983,1987 **** lua_rawset( L, LUA_REGISTRYINDEX ); // set the value ! // Create a table for all userdata that we've pushed into lua // Use weak values so the gc works on them wxlua_pushkey_wxLuaObjects(L); --- 1998,2002 ---- lua_rawset( L, LUA_REGISTRYINDEX ); // set the value ! // Create a table for the userdata that we've pushed into lua // Use weak values so the gc works on them wxlua_pushkey_wxLuaObjects(L); *************** *** 2090,2097 **** // register our 'function' object handlers if (registerTypes) - { g_wxluatag_wxLuaFunction = tnewtag(); - g_wxluatag_wxWinDestroyTable = tnewweaktag(false, true); - } tsettagmethod(g_wxluatag_wxLuaFunction, "__gc", wxlua__gc_wxLuaFunction); --- 2105,2109 ---- *************** *** 2356,2360 **** { M_WXLSTATEDATA->m_wxlStateData->m_windowList.Append(win); ! new wxLuaCallback(*this, 3, win->GetId(), wxID_ANY, wxEVT_DESTROY, win->GetEventHandler()); return true; } --- 2368,2372 ---- { M_WXLSTATEDATA->m_wxlStateData->m_windowList.Append(win); ! new wxLuaCallback(*this, WXLUACALLBACK_NOROUTINE, win->GetId(), wxID_ANY, wxEVT_DESTROY, win->GetEventHandler()); return true; } *************** *** 2524,2530 **** wxString name(wxT("Unknown Tracked Window Type")); ! wxObject* obj = (wxObject*)wxlDestroyCallBack->GetEvtHandler(); ! if (obj && obj->GetClassInfo() && obj->GetClassInfo()->GetClassName()) ! name = obj->GetClassInfo()->GetClassName(); names.Add(name); --- 2536,2542 ---- wxString name(wxT("Unknown Tracked Window Type")); ! wxWindow* win = wxlDestroyCallBack->GetWindow(); ! if (win && win->GetClassInfo() && win->GetClassInfo()->GetClassName()) ! name = win->GetClassInfo()->GetClassName(); names.Add(name); *************** *** 2693,2698 **** if (data != NULL) { - bool handled = false; - // if the object we are referencing is derived from wxWindow if (wxlua_isderivedclass(L, tag, g_wxluatag_wxWindow) >= 0) --- 2705,2708 ---- *************** *** 2702,2714 **** { // check to make sure that we're not trying to attach another destroy callback ! bool already_handled = false; wxList::compatibility_iterator node = M_WXLSTATEDATA->m_wxlStateData->m_winDestroyCallbackList.GetFirst(); while (node) { wxLuaWinDestroyCallback *pCallback = (wxLuaWinDestroyCallback *)node->GetData(); ! wxCHECK_RET(pCallback, wxT("Invalid wxLuaWinDestroyCallback")); ! if (pCallback->GetEvtHandler() == win) { ! already_handled = true; break; } --- 2712,2724 ---- { // check to make sure that we're not trying to attach another destroy callback ! bool destroy_handled = false; wxList::compatibility_iterator node = M_WXLSTATEDATA->m_wxlStateData->m_winDestroyCallbackList.GetFirst(); while (node) { wxLuaWinDestroyCallback *pCallback = (wxLuaWinDestroyCallback *)node->GetData(); ! ! if (pCallback->GetWindow() == win) { ! destroy_handled = true; break; } *************** *** 2719,2739 **** // Connect an object to the destroy event and this will also set the // metatable for the object as tpushusertag does. ! if (!already_handled) { - handled = true; wxLuaWinDestroyCallback *pCallback = ! new wxLuaWinDestroyCallback(*this, win->GetId(), ! (wxEvtHandler*)win, tag); if (pCallback == NULL) - { terror("wxLua: Out of memory creating wxLuaWinDestroyCallback."); - } } } } ! // Otherwise handle normally ! if (!handled) ! wxlua_tpushusertag(L, data, tag, true); } else --- 2729,2746 ---- // Connect an object to the destroy event and this will also set the // metatable for the object as tpushusertag does. ! if (!destroy_handled) { wxLuaWinDestroyCallback *pCallback = ! new wxLuaWinDestroyCallback(*this, win, tag); ! if (pCallback == NULL) terror("wxLua: Out of memory creating wxLuaWinDestroyCallback."); } } } ! // push the object into lua by wrapping it with a Lua userdata ! // or if it's already wrapped, return a copy of the userdata ! wxlua_tpushusertag(L, data, tag, true); } else Index: wxlbind.cpp =================================================================== RCS file: /cvsroot/wxlua/wxLua/modules/wxlua/src/wxlbind.cpp,v retrieving revision 1.90 retrieving revision 1.91 diff -C2 -d -r1.90 -r1.91 *** wxlbind.cpp 1 Aug 2007 19:15:37 -0000 1.90 --- wxlbind.cpp 3 Aug 2007 22:17:16 -0000 1.91 *************** *** 41,45 **** int g_wxluatag_wxLuaFunction = 0; - int g_wxluatag_wxWinDestroyTable = 0; int g_wxluatag_NULL = 0; int g_wxluatag_wxEvent = 0; --- 41,44 ---- Index: wxlcallb.cpp =================================================================== RCS file: /cvsroot/wxlua/wxLua/modules/wxlua/src/wxlcallb.cpp,v retrieving revision 1.37 retrieving revision 1.38 diff -C2 -d -r1.37 -r1.38 *** wxlcallb.cpp 3 Aug 2007 02:34:05 -0000 1.37 --- wxlcallb.cpp 3 Aug 2007 22:17:16 -0000 1.38 *************** *** 29,33 **** wxWindowID winId, wxWindowID lastId, wxEventType eventType, wxEvtHandler *evtHandler) ! : wxObject(), m_wxlState(wxlState), m_evtHandler(evtHandler), m_id(winId), m_lastId(lastId), m_wxlBindEvent(NULL) --- 29,33 ---- wxWindowID winId, wxWindowID lastId, wxEventType eventType, wxEvtHandler *evtHandler) ! : wxObject(), m_routine(0), m_wxlState(wxlState), m_evtHandler(evtHandler), m_id(winId), m_lastId(lastId), m_wxlBindEvent(NULL) *************** *** 49,53 **** // create a reference to the lua event handler function ! m_routine = m_wxlState.tinsert(lua_func_stack_idx); m_evtHandler->Connect(winId, lastId, eventType, --- 49,54 ---- // create a reference to the lua event handler function ! if (lua_func_stack_idx != WXLUACALLBACK_NOROUTINE) ! m_routine = m_wxlState.tinsert(lua_func_stack_idx); m_evtHandler->Connect(winId, lastId, eventType, *************** *** 82,89 **** // If this is a wxWindow being destroyed, clear out all callbacks to it for safety ! if (event.GetEventType() == wxEVT_DESTROY) { event.Skip(); - wxlState.RemoveTrackedWindow((wxWindow*)event.GetEventObject()); // delete the reference to this handler since we're clearing it wxlState.RemoveTrackedCallback(theCallback); --- 83,89 ---- // If this is a wxWindow being destroyed, clear out all callbacks to it for safety ! if ((theCallback->m_routine == 0) && (event.GetEventType() == wxEVT_DESTROY)) { event.Skip(); // delete the reference to this handler since we're clearing it wxlState.RemoveTrackedCallback(theCallback); *************** *** 119,122 **** --- 119,126 ---- theCallback->CallFunction(&event); + // we want to get this too or let it pass to someone else + if (event.GetEventType() == wxEVT_DESTROY) + event.Skip(); + wxlState.SetInEventType(wxEVT_NULL); } *************** *** 169,216 **** wxLuaWinDestroyCallback::wxLuaWinDestroyCallback(const wxLuaState& wxlState, ! wxWindowID id, wxEvtHandler *evtHandler, ! int iTag) ! :wxObject(), m_wxlState(wxlState), ! m_evtHandler(evtHandler), m_id(id) { wxCHECK_RET(m_wxlState.Ok(), wxT("Invalid wxLuaState")); ! // allocate a LUA proxy for the object ! const void **ptr = (const void **)m_wxlState.lua_NewUserdata(sizeof(void *)); ! ! if (ptr != NULL) ! { ! // save the address of the object in the proxy ! *ptr = evtHandler; ! ! // and set the metatable of the proxy to the wxLuaReferences registry table ! if (m_wxlState.tget(iTag)) ! { ! if (m_wxlState.lua_SetMetatable(-2) == 0) ! m_wxlState.terror("wxLua: Unable to set metatable of proxy in wxLuaWinDestroyCallback."); ! } ! ! // get a reference to the destroy handler table ! if (m_wxlState.tget(g_wxluatag_wxWinDestroyTable)) ! { ! // create a reference to object ! m_wxlState.lua_PushLightUserdata(evtHandler); // key ! m_wxlState.lua_PushValue(-3); // value ! // save it in the destroy handler table ! m_wxlState.lua_RawSet(-3); ! m_wxlState.lua_Pop(1); // pop the table from GetLuaWinDestroyTableTag() ! } ! ! m_wxlState.AddTrackedWinDestroyCallback(this); ! // connect the event handler ! m_evtHandler->Connect(id, wxEVT_DESTROY, ! (wxObjectEventFunction)&wxLuaWinDestroyCallback::EventHandler, ! this); ! } ! else ! { ! m_wxlState.terror("wxLua: Out of memory trying to create wxLuaWinDestroyCallback."); ! } } --- 173,187 ---- wxLuaWinDestroyCallback::wxLuaWinDestroyCallback(const wxLuaState& wxlState, ! wxWindow* win, int iTag) ! :wxObject(), m_wxlState(wxlState), m_window(win) { wxCHECK_RET(m_wxlState.Ok(), wxT("Invalid wxLuaState")); ! m_wxlState.AddTrackedWinDestroyCallback(this); ! // connect the event handler ! m_window->Connect(m_window->GetId(), wxEVT_DESTROY, ! (wxObjectEventFunction)&wxLuaWinDestroyCallback::EventHandler, ! this); } *************** *** 218,222 **** --- 189,196 ---- { if (m_wxlState.Ok()) + { m_wxlState.RemoveTrackedWinDestroyCallback(this); + m_wxlState.RemoveTrackedWindow(m_window); + } } *************** *** 224,228 **** { wxLuaWinDestroyCallback *theCallback = (wxLuaWinDestroyCallback *)event.m_callbackUserData; ! if (theCallback && (((wxEvtHandler*)event.GetEventObject()) == theCallback->m_evtHandler)) { theCallback->OnDestroy(event); --- 198,202 ---- { wxLuaWinDestroyCallback *theCallback = (wxLuaWinDestroyCallback *)event.m_callbackUserData; ! if (theCallback && (((wxWindow*)event.GetEventObject()) == theCallback->m_window)) { theCallback->OnDestroy(event); *************** *** 238,254 **** // FIXME - Is it an error to receive an event after you've deleted lua? // probably not if lua is getting shutdown - if (!m_wxlState.Ok()) - return; - // Note: do not remove from wxLuaState's destroyHandlerList here, wait 'till destructor ! ! if (m_wxlState.tget(g_wxluatag_wxWinDestroyTable)) { ! // clear the metatable reference in the lua proxy. ! m_wxlState.lua_PushLightUserdata(m_evtHandler); ! m_wxlState.lua_RawGet(-2); ! m_wxlState.lua_PushNil(); ! m_wxlState.lua_SetMetatable(-2); ! m_wxlState.lua_Pop(2); } } --- 212,220 ---- // FIXME - Is it an error to receive an event after you've deleted lua? // probably not if lua is getting shutdown // Note: do not remove from wxLuaState's destroyHandlerList here, wait 'till destructor ! if (m_wxlState.Ok()) { ! wxlua_tcleartrackedmetatable(m_wxlState.GetLuaState(), m_window); ! m_wxlState.RemoveTrackedWindow(m_window); } } |