From: John L. <jr...@us...> - 2007-12-05 00:34:53
|
Update of /cvsroot/wxlua/wxLua/modules/wxlua/src In directory sc8-pr-cvs9.sourceforge.net:/tmp/cvs-serv21421/wxLua/modules/wxlua/src Modified Files: wxlbind.cpp wxlcallb.cpp wxlstate.cpp wxlua_bind.cpp Log Message: Removed the rest of "UnregisterBinding" functions since they did nothing useful Moved binding base class linking code to wxLuaBinding::InitAllBindings from wxLuaState::RegisterBindings Removed wxLuaStateData::m_winDestroyCallbackList and wxLuaStateData::m_callbackList and added two registry tables for their values. Should be faster and easier to verify operation. Fix searching in the wxLuaStackDialog. Index: wxlstate.cpp =================================================================== RCS file: /cvsroot/wxlua/wxLua/modules/wxlua/src/wxlstate.cpp,v retrieving revision 1.142 retrieving revision 1.143 diff -C2 -d -r1.142 -r1.143 *** wxlstate.cpp 4 Dec 2007 05:20:28 -0000 1.142 --- wxlstate.cpp 5 Dec 2007 00:34:46 -0000 1.143 *************** *** 30,33 **** --- 30,35 ---- const char* wxlua_lreg_wxluastate_key = "wxLuaState"; const char* wxlua_lreg_objects_key = "wxLua pushed userdata"; + const char* wxlua_lreg_evtcallbacks_key = "wxLuaCallbacks"; + const char* wxlua_lreg_windestroycallbacks_key = "wxLuaWinDestoyCallbacks"; const char* wxlua_lreg_callbaseclassfunc_key = "wxLua CallBaseClassFunc"; *************** *** 286,290 **** } ! lua_pop(L, 1); // pop object we pushed and the ref table } --- 288,292 ---- } ! lua_pop(L, 1); // pop ref table } *************** *** 299,303 **** lua_pushlightuserdata(L, &wxlua_metatable_tag_key); // push key lua_pushnumber(L, tag); // push value ! lua_rawset(L, -3); // t[key] = value; pop key and value return tag; // leave the table on the stack --- 301,305 ---- lua_pushlightuserdata(L, &wxlua_metatable_tag_key); // push key lua_pushnumber(L, tag); // push value ! lua_rawset(L, -3); // set t[key] = value; pop key and value return tag; // leave the table on the stack *************** *** 890,898 **** // delete all of the derived methods we've pushed ! lua_pushnil(L); /* first key */ while (lua_next(L, -2) != 0) { ! // uses 'key' (at index -2) and 'value' (at index -1) ! if (lua_islightuserdata(L, -1)) { --- 892,899 ---- // delete all of the derived methods we've pushed ! lua_pushnil(L); while (lua_next(L, -2) != 0) { ! // value at -1, key at -2, table at -3 if (lua_islightuserdata(L, -1)) { *************** *** 904,908 **** } ! lua_pop(L, 1); // pop the obj table so reg table is on top lua_pushlightuserdata(L, (void *)pObject); // push key --- 905,909 ---- } ! lua_pop(L, 1); // pop the obj table lua_pushlightuserdata(L, (void *)pObject); // push key *************** *** 910,917 **** lua_rawset(L, -3); // set t[key] = value; pop key and value ! lua_pop(L, 1); // pop reg table } else ! lua_pop(L, 2); // pop the reg table and nil for the obj table return found; --- 911,918 ---- lua_rawset(L, -3); // set t[key] = value; pop key and value ! lua_pop(L, 1); // pop the derived table } else ! lua_pop(L, 2); // pop the derived table and nil for the obj table return found; *************** *** 1079,1086 **** m_id(wxID_ANY) { - // don't "own" pointers to wxLuaCallbacks, let wxEventHandler do it - m_callbackList.DeleteContents(false); - // don't delete wxLuaWinDestroyCallbacks, let wxEventHandler do it - m_winDestroyCallbackList.DeleteContents(false); // don't delete wxWindow derived classes, let wxWidgets do it m_windowList.DeleteContents(false); --- 1080,1083 ---- *************** *** 1152,1160 **** bool wxLuaStateRefData::CloseLuaState(bool force) { ! if ((m_lua_State == NULL) || m_wxlStateData->m_is_closing) return true; - if (m_lua_State_coroutine) return true; - m_wxlStateData->m_is_closing = true; --- 1149,1155 ---- bool wxLuaStateRefData::CloseLuaState(bool force) { ! if ((m_lua_State == NULL) || m_wxlStateData->m_is_closing || m_lua_State_coroutine) return true; m_wxlStateData->m_is_closing = true; *************** *** 1192,1201 **** } - // m_wxlStateData->m_windowList.Clear(); wxLuaCleanupWindows does this for us - - ClearCallbacks(); if (m_lua_State != NULL) { ! UnRegisterBindings(); if (!m_lua_State_static) --- 1187,1208 ---- } if (m_lua_State != NULL) { ! ClearCallbacks(); ! ! // remove refs table to try to clear memory gracefully ! lua_pushlightuserdata(m_lua_State, &wxlua_lreg_refs_key); ! lua_pushnil(m_lua_State); ! lua_rawset(m_lua_State, LUA_REGISTRYINDEX); ! ! lua_pushlightuserdata(m_lua_State, &wxlua_lreg_debug_refs_key); ! lua_pushnil(m_lua_State); ! lua_rawset(m_lua_State, LUA_REGISTRYINDEX); ! ! //lua_pushlightuserdata(m_lua_State, &wxlua_lreg_derivedmethods_key); // gc will delete them ! //lua_pushnil(m_lua_State); ! //lua_rawset(m_lua_State, LUA_REGISTRYINDEX); ! ! lua_gc(m_lua_State, LUA_GCCOLLECT, 0); // round up dead refs if (!m_lua_State_static) *************** *** 1206,1210 **** // Note: even though the lua_State is closed the pointer value is still good. // The wxLuaState we pushed into the reg table is a light userdata so ! // it doesn't get deleted. wxHashMapLuaState::iterator it = s_wxHashMapLuaState.find(m_lua_State); if (it != s_wxHashMapLuaState.end()) --- 1213,1217 ---- // Note: even though the lua_State is closed the pointer value is still good. // The wxLuaState we pushed into the reg table is a light userdata so ! // it didn't get deleted. wxHashMapLuaState::iterator it = s_wxHashMapLuaState.find(m_lua_State); if (it != s_wxHashMapLuaState.end()) *************** *** 1224,1290 **** void wxLuaStateRefData::ClearCallbacks() { ! // remove any and all callbacks that use this event handler since its gone ! wxList::compatibility_iterator node = m_wxlStateData->m_callbackList.GetFirst(); ! while (node) ! { ! wxLuaCallback *pCallback = (wxLuaCallback *)node->GetData(); ! wxCHECK_RET(pCallback, wxT("Invalid wxLuaCallback")); ! if (pCallback->GetwxLuaState().GetRefData() != this) // don't unref us ! pCallback->ClearwxLuaState(); ! ! node = node->GetNext(); ! } ! ! node = m_wxlStateData->m_winDestroyCallbackList.GetFirst(); ! while (node) ! { ! wxLuaWinDestroyCallback *pCallback = (wxLuaWinDestroyCallback *) node->GetData(); ! wxCHECK_RET(pCallback, wxT("Invalid wxLuaWinDestroyCallback")); ! if (pCallback->GetwxLuaState().GetRefData() != this) // don't unref us ! pCallback->ClearwxLuaState(); ! ! node = node->GetNext(); ! } ! m_wxlStateData->m_callbackList.Clear(); ! m_wxlStateData->m_winDestroyCallbackList.Clear(); ! } ! void wxLuaStateRefData::UnRegisterBindings() ! { ! if (m_lua_State == NULL) return; ! // UnRegister bindings ! wxLuaBindingList::compatibility_iterator node = m_wxlStateData->m_bindingList.GetFirst(); ! while (node) { ! wxLuaBinding* binding = node->GetData(); ! binding->UnRegisterBinding(m_lua_State); ! node = node->GetNext(); } ! lua_pushlightuserdata(m_lua_State, &wxlua_lreg_wxluastate_key); ! lua_pushnil(m_lua_State); ! lua_rawset(m_lua_State, LUA_REGISTRYINDEX); ! lua_pushlightuserdata(m_lua_State, &wxlua_lreg_tags_key); ! lua_pushnil(m_lua_State); ! lua_rawset(m_lua_State, LUA_REGISTRYINDEX); ! lua_pushlightuserdata(m_lua_State, &wxlua_lreg_refs_key); ! lua_pushnil(m_lua_State); ! lua_rawset(m_lua_State, LUA_REGISTRYINDEX); ! lua_pushlightuserdata(m_lua_State, &wxlua_lreg_debug_refs_key); ! lua_pushnil(m_lua_State); ! lua_rawset(m_lua_State, LUA_REGISTRYINDEX); ! lua_pushlightuserdata(m_lua_State, &wxlua_lreg_classes_key); ! lua_pushnil(m_lua_State); ! lua_rawset(m_lua_State, LUA_REGISTRYINDEX); ! //lua_pushlightuserdata(m_lua_State, &wxlua_lreg_derivedmethods_key); // gc will delete them ! //lua_pushnil(m_lua_State); ! //lua_rawset(m_lua_State, LUA_REGISTRYINDEX); } --- 1231,1284 ---- void wxLuaStateRefData::ClearCallbacks() { ! wxCHECK_RET(m_lua_State, wxT("Invalid lua_State")); ! lua_State* L = m_lua_State; ! lua_pushlightuserdata(L, &wxlua_lreg_evtcallbacks_key); // push key ! lua_rawget(L, LUA_REGISTRYINDEX); // pop key, push value (table) ! lua_pushnil(L); ! while (lua_next(L, -2) != 0) { ! // value = -1, key = -2, table = -3 ! wxLuaCallback* cb = (wxLuaCallback*)lua_touserdata(L, -1); ! wxCHECK_RET(cb, wxT("Invalid wxLuaCallback")); ! if (cb && (cb->GetwxLuaState().GetRefData() != this)) // don't unref us ! cb->ClearwxLuaState(); ! ! lua_pop(L, 1); // pop value, lua_next will pop key at end } ! lua_pop(L, 1); // pop table ! lua_pushlightuserdata(L, &wxlua_lreg_evtcallbacks_key); // push key ! lua_newtable(L); // push value ! lua_rawset(L, LUA_REGISTRYINDEX); // set t[key] = value, pops key and value ! // ---------------------------------------------------------------------- ! lua_pushlightuserdata(L, &wxlua_lreg_windestroycallbacks_key); // push key ! lua_rawget(L, LUA_REGISTRYINDEX); // pop key, push value (table) ! lua_pushnil(L); ! while (lua_next(L, -2) != 0) ! { ! // value = -1, key = -2, table = -3 ! if (lua_type(L, -2) == LUA_TNUMBER) ! { ! wxLuaWinDestroyCallback* cb = (wxLuaWinDestroyCallback*)lua_touserdata(L, -1); ! wxCHECK_RET(cb, wxT("Invalid wxLuaWinDestroyCallback")); ! if (cb && (cb->GetwxLuaState().GetRefData() != this)) // don't unref us ! cb->ClearwxLuaState(); ! } ! ! lua_pop(L, 1); // pop value, lua_next will pop key at end ! } ! lua_pop(L, 1); // pop table ! ! lua_pushlightuserdata(L, &wxlua_lreg_windestroycallbacks_key); // push key ! lua_newtable(L); // push value ! lua_rawset(L, LUA_REGISTRYINDEX); // set t[key] = value, pops key and value } *************** *** 1580,1585 **** { wxLuaCharBuffer buf(script); ! int status = CompileBuffer((unsigned char*)buf.GetData(), buf.Length(), name, errMsg_, line_num_); ! return status; } int wxLuaState::CompileBuffer(const unsigned char buf[], size_t size, const wxString &name, wxString* errMsg_, int* line_num_) --- 1574,1578 ---- { wxLuaCharBuffer buf(script); ! return CompileBuffer((unsigned char*)buf.GetData(), buf.Length(), name, errMsg_, line_num_); } int wxLuaState::CompileBuffer(const unsigned char buf[], size_t size, const wxString &name, wxString* errMsg_, int* line_num_) *************** *** 1844,1848 **** lua_rawset(L, LUA_REGISTRYINDEX); // set the value ! // create the wxLuaClasses table in the registry lua_pushlightuserdata(L, &wxlua_lreg_classes_key); lua_newtable(L); --- 1837,1841 ---- lua_rawset(L, LUA_REGISTRYINDEX); // set the value ! // create the wxLuaBindClasses table in the registry lua_pushlightuserdata(L, &wxlua_lreg_classes_key); lua_newtable(L); *************** *** 1865,1868 **** --- 1858,1873 ---- lua_rawset( L, LUA_REGISTRYINDEX ); // set the value + // Create a table for wxLuaCallbacks + lua_pushlightuserdata(L, &wxlua_lreg_evtcallbacks_key); + lua_newtable(L); + lua_rawset( L, LUA_REGISTRYINDEX ); // set the value + + // Create a table for wxLuaWinDestroyCallbacks + lua_pushlightuserdata(L, &wxlua_lreg_windestroycallbacks_key); + lua_newtable(L); + lua_rawset( L, LUA_REGISTRYINDEX ); // set the value + + wxLuaBinding::InitAllBindings(); // only runs the first time through + // Register bindings wxLuaBindingList::compatibility_iterator node = M_WXLSTATEDATA->m_wxlStateData->m_bindingList.GetFirst(); *************** *** 1876,1962 **** M_WXLSTATEDATA->m_wxlStateData->m_bindings_registered = true; - // setup base class tags, must do it here since we can have many bindings - // that have derived classes and they have to be installed first to get - // their tags initialized. - node = M_WXLSTATEDATA->m_wxlStateData->m_bindingList.GetFirst(); - while (node) - { - wxLuaBinding* binding = node->GetData(); - wxLuaBindClass* wxlClass = binding->GetClassArray(); - size_t i, class_count = binding->GetClassCount(); - - for (i = 0; i < class_count; ++i, ++wxlClass) - { - if (wxlClass->baseclassName) // does it have a name - { - wxLuaBindingList::compatibility_iterator basenode; - for (basenode = M_WXLSTATEDATA->m_wxlStateData->m_bindingList.GetFirst(); basenode; basenode = basenode->GetNext() ) - { - wxLuaBinding* basebinding = basenode->GetData(); - - // found base class in binding? - if (basebinding->SetBaseClass(wxlClass)) - break; - } - } - } - - node = node->GetNext(); - } - - // Link together all of the class member functions with base class functions - // with the same name so the overloads work for them too. - node = M_WXLSTATEDATA->m_wxlStateData->m_bindingList.GetFirst(); - while (node) - { - wxLuaBinding* binding = node->GetData(); - wxLuaBindClass* wxlClass = binding->GetClassArray(); - size_t i, class_count = binding->GetClassCount(); - - for (i = 0; i < class_count; ++i, ++wxlClass) - { - if (wxlClass->baseclass) // does it have a base class at all? - { - wxLuaBindMethod *wxlMethod = wxlClass->methods; - size_t j, method_count = wxlClass->methods_n; - - for (j = 0; j < method_count; ++j, ++wxlMethod) - { - // iterate through the base classes to find if this function is - // an overload, but only if we haven't checked already. - if (!WXLUA_HASBIT(wxlMethod->type, WXLUAMETHOD_OVERLOAD_BASE|WXLUAMETHOD_DELETE)) - { - wxLuaBindClass *baseClass = wxlClass->baseclass; - wxLuaBindMethod *parentMethod = wxlMethod; - - while (baseClass) - { - parentMethod->type |= WXLUAMETHOD_OVERLOAD_BASE; // have checked this - - wxLuaBindMethod* baseMethod = wxLuaBinding::GetClassMethod(baseClass, wxlMethod->name, false); - if (baseMethod) - { - // don't link to base class delete functions - if (!WXLUA_HASBIT(baseMethod->type, WXLUAMETHOD_DELETE)) - { - parentMethod->basemethod = baseMethod; - parentMethod = baseMethod; - } - - // we have already checked the base classes below this - if (WXLUA_HASBIT(baseMethod->type, WXLUAMETHOD_OVERLOAD_BASE)) - break; - } - - baseClass = baseClass->baseclass; - } - } - } - } - } - - node = node->GetNext(); - } - // Create a metatable for our C function wrapper wxLuaFunction g_wxluatag_wxLuaFunction = wxluaT_NewTag(); --- 1881,1884 ---- *************** *** 2172,2176 **** { wxArrayString names; - wxArrayInt counts; wxCHECK_MSG(Ok(), names, wxT("Invalid wxLuaState")); --- 2094,2097 ---- *************** *** 2187,2206 **** name = obj->GetClassInfo()->GetClassName(); ! //name = wxString::Format(wxT("%p "), obj) + name; ! ! int idx = names.Index(name); ! if (idx == wxNOT_FOUND) ! { ! names.Add(name); ! counts.Add(1); ! } ! else ! counts[idx]++; } - size_t n, count = names.GetCount(); - for (n = 0; n < count; ++n) - names[n] += wxString::Format(wxT(" %d"), counts[n]); - names.Sort(); return names; --- 2108,2114 ---- name = obj->GetClassInfo()->GetClassName(); ! names.Add(wxString::Format(wxT("%s %p"), name.c_str(), obj)); } names.Sort(); return names; *************** *** 2258,2262 **** { wxArrayString names; - wxArrayInt counts; wxCHECK_MSG(Ok(), names, wxT("Invalid wxLuaState")); --- 2166,2169 ---- *************** *** 2270,2281 **** { wxString name(win->GetClassInfo()->GetClassName()); ! int idx = names.Index(name); ! if (idx == wxNOT_FOUND) ! { ! names.Add(name); ! counts.Add(1); ! } ! else ! counts[idx]++; } --- 2177,2182 ---- { wxString name(win->GetClassInfo()->GetClassName()); ! ! names.Add(wxString::Format(wxT("%s %p"), name.c_str(), win)); } *************** *** 2283,2290 **** } - size_t n, count = names.GetCount(); - for (n = 0; n < count; ++n) - names[n] += wxString::Format(wxT(" %d"), counts[n]); - names.Sort(); return names; --- 2184,2187 ---- *************** *** 2302,2316 **** { wxCHECK_RET(Ok(), wxT("Invalid wxLuaState")); ! M_WXLSTATEDATA->m_wxlStateData->m_callbackList.Append(callback); } bool wxLuaState::RemoveTrackedCallback(wxLuaCallback* callback) { wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState")); ! return M_WXLSTATEDATA->m_wxlStateData->m_callbackList.DeleteObject(callback); ! } ! wxList* wxLuaState::GetTrackedCallbackList() ! { ! wxCHECK_MSG(Ok(), NULL, wxT("Invalid wxLuaState")); ! return &M_WXLSTATEDATA->m_wxlStateData->m_callbackList; } --- 2199,2228 ---- { wxCHECK_RET(Ok(), wxT("Invalid wxLuaState")); ! lua_State* L = M_WXLSTATEDATA->m_lua_State; ! ! lua_pushlightuserdata(L, &wxlua_lreg_evtcallbacks_key); // push key ! lua_rawget(L, LUA_REGISTRYINDEX); // pop key, push value (table) ! ! lua_pushlightuserdata(L, callback); // push key ! lua_pushlightuserdata(L, callback->GetEvtHandler()); // push value ! lua_rawset(L, -3); // set t[key] = value; pops key and value ! ! lua_pop(L, 1); // pop table } bool wxLuaState::RemoveTrackedCallback(wxLuaCallback* callback) { wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState")); ! lua_State* L = M_WXLSTATEDATA->m_lua_State; ! ! lua_pushlightuserdata(L, &wxlua_lreg_evtcallbacks_key); // push key ! lua_rawget(L, LUA_REGISTRYINDEX); // pop key, push value (table) ! ! lua_pushlightuserdata(L, callback); // push key ! lua_pushnil(L); // push value ! lua_rawset(L, -3); // set t[key] = value; pops key and value ! ! lua_pop(L, 1); // pop table ! ! return true; // FIXME return a real value } *************** *** 2318,2330 **** { wxArrayString names; - wxArrayInt counts; wxCHECK_MSG(Ok(), names, wxT("Invalid wxLuaState")); ! wxList::compatibility_iterator node = GetTrackedCallbackList()->GetFirst(); ! while (node) { ! wxLuaCallback *wxlCallback = (wxLuaCallback *)node->GetData(); ! wxCHECK_MSG(wxlCallback, false, wxT("Invalid wxLuaCallback")); wxString evtName; --- 2230,2246 ---- { wxArrayString names; wxCHECK_MSG(Ok(), names, wxT("Invalid wxLuaState")); + lua_State* L = M_WXLSTATEDATA->m_lua_State; ! lua_pushlightuserdata(L, &wxlua_lreg_evtcallbacks_key); // push key ! lua_rawget(L, LUA_REGISTRYINDEX); // pop key, push value (table) ! ! lua_pushnil(L); ! while (lua_next(L, -2) != 0) { ! // value = -1, key = -2, table = -3 ! wxLuaCallback* wxlCallback = (wxLuaCallback*)lua_touserdata(L, -2); ! wxCHECK_MSG(wxlCallback, names, wxT("Invalid wxLuaCallback")); wxString evtName; *************** *** 2336,2359 **** wxLuaBinding* binding = bindNode->GetData(); evtName = binding->GetEventTypeName(wxlCallback->GetEventType()); ! if (!evtName.IsEmpty()) break; } } ! wxString name = wxString::Format(wxT("%s (%d)"), evtName.c_str(), (int)wxlCallback->GetEventType()); ! int idx = names.Index(name); ! if (idx == wxNOT_FOUND) ! { ! names.Add(name); ! counts.Add(1); ! } ! else ! counts[idx]++; ! ! node = node->GetNext(); } ! size_t n, count = names.GetCount(); ! for (n = 0; n < count; ++n) ! names[n] += wxString::Format(wxT(" %d"), counts[n]); names.Sort(); --- 2252,2266 ---- wxLuaBinding* binding = bindNode->GetData(); evtName = binding->GetEventTypeName(wxlCallback->GetEventType()); ! if (!evtName.IsEmpty()) break; // found event name } } + + names.Add(wxString::Format(wxT("%s (%d) wxEvtHandler(%p)-wxLuacallback(%p)"), + evtName.c_str(), (int)wxlCallback->GetEventType(), wxlCallback->GetEvtHandler(), wxlCallback)); ! lua_pop(L, 1); // pop value, lua_next will pop key at end } ! lua_pop(L, 1); // pop table names.Sort(); *************** *** 2364,2378 **** { wxCHECK_RET(Ok(), wxT("Invalid wxLuaState")); ! M_WXLSTATEDATA->m_wxlStateData->m_winDestroyCallbackList.Append(callback); } bool wxLuaState::RemoveTrackedWinDestroyCallback(wxLuaWinDestroyCallback* callback) { wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState")); ! return M_WXLSTATEDATA->m_wxlStateData->m_winDestroyCallbackList.DeleteObject(callback); ! } ! wxList* wxLuaState::GetTrackedWinDestroyCallbackList() ! { ! wxCHECK_MSG(Ok(), NULL, wxT("Invalid wxLuaState")); ! return &M_WXLSTATEDATA->m_wxlStateData->m_winDestroyCallbackList; } --- 2271,2308 ---- { wxCHECK_RET(Ok(), wxT("Invalid wxLuaState")); ! lua_State* L = M_WXLSTATEDATA->m_lua_State; ! ! lua_pushlightuserdata(L, &wxlua_lreg_windestroycallbacks_key); // push key ! lua_rawget(L, LUA_REGISTRYINDEX); // pop key, push value (table) ! ! lua_pushlightuserdata(L, callback); // push key ! lua_pushnumber(L, 1); // push value ! lua_rawset(L, -3); // set t[key] = value; pops key and value ! ! lua_pushlightuserdata(L, callback->GetWindow()); // push key ! lua_pushlightuserdata(L, callback); // push value ! lua_rawset(L, -3); // set t[key] = value; pops key and value ! ! lua_pop(L, 1); // pop table } bool wxLuaState::RemoveTrackedWinDestroyCallback(wxLuaWinDestroyCallback* callback) { wxCHECK_MSG(Ok(), false, wxT("Invalid wxLuaState")); ! lua_State* L = M_WXLSTATEDATA->m_lua_State; ! ! lua_pushlightuserdata(L, &wxlua_lreg_windestroycallbacks_key); // push key ! lua_rawget(L, LUA_REGISTRYINDEX); // pop key, push value (table) ! ! lua_pushlightuserdata(L, callback); // push key ! lua_pushnil(L); // push value ! lua_rawset(L, -3); // set t[key] = value; pops key and value ! ! lua_pushlightuserdata(L, callback->GetWindow()); // push key ! lua_pushnil(L); // push value ! lua_rawset(L, -3); // set t[key] = value; pops key and value ! ! lua_pop(L, 1); // pop table ! ! return true; // FIXME return if it was here or not } *************** *** 2380,2409 **** { wxArrayString names; - wxArrayInt counts; wxCHECK_MSG(Ok(), names, wxT("Invalid wxLuaState")); ! wxList::compatibility_iterator node = GetTrackedWinDestroyCallbackList()->GetFirst(); ! while (node) { ! wxLuaWinDestroyCallback *wxlDestroyCallBack = (wxLuaWinDestroyCallback *) node->GetData(); ! wxCHECK_MSG(wxlDestroyCallBack, false, wxT("Invalid wxLuaWinDestroyCallback")); ! 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); ! counts.Add(1); ! node = node->GetNext(); } - size_t n, count = names.GetCount(); - for (n = 0; n < count; ++n) - names[n] += wxString::Format(wxT(" %d"), counts[n]); - names.Sort(); return names; --- 2310,2341 ---- { wxArrayString names; wxCHECK_MSG(Ok(), names, wxT("Invalid wxLuaState")); + lua_State* L = M_WXLSTATEDATA->m_lua_State; ! lua_pushlightuserdata(L, &wxlua_lreg_windestroycallbacks_key); // push key ! lua_rawget(L, LUA_REGISTRYINDEX); // pop key, push value (table) ! ! lua_pushnil(L); ! while (lua_next(L, -2) != 0) { ! // value = -1, key = -2, table = -3 ! if (lua_type(L, -1) == LUA_TNUMBER) ! { ! wxLuaWinDestroyCallback* wxlDestroyCallBack = (wxLuaWinDestroyCallback*)lua_touserdata(L, -2); ! wxCHECK_MSG(wxlDestroyCallBack, names, wxT("Invalid wxLuaWinDestroyCallback")); ! wxString name(wxT("Unknown Tracked wxWindow Type")); ! wxWindow* win = wxlDestroyCallBack->GetWindow(); ! if (win && win->GetClassInfo() && win->GetClassInfo()->GetClassName()) ! name = win->GetClassInfo()->GetClassName(); ! names.Add(wxString::Format(wxT("%s(%p) wxLuaDestroyCallback(%p)"), name.c_str(), win, wxlDestroyCallBack)); ! } ! lua_pop(L, 1); } names.Sort(); return names; *************** *** 2557,2573 **** // 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; ! } ! node = node->GetNext(); ! } // Connect an object to the destroy event and this will also set the --- 2489,2503 ---- // check to make sure that we're not trying to attach another destroy callback bool destroy_handled = false; ! lua_pushlightuserdata(L, &wxlua_lreg_windestroycallbacks_key); // push key ! lua_rawget(L, LUA_REGISTRYINDEX); // pop key, push value (table) ! lua_pushlightuserdata(L, win); // push key ! lua_rawget(L, -2); // get t[key] = value; pops key ! ! if (lua_islightuserdata(L, -1)) ! destroy_handled = true; ! ! lua_pop(L, 2); // pop windestroy table and value // Connect an object to the destroy event and this will also set the Index: wxlbind.cpp =================================================================== RCS file: /cvsroot/wxlua/wxLua/modules/wxlua/src/wxlbind.cpp,v retrieving revision 1.97 retrieving revision 1.98 diff -C2 -d -r1.97 -r1.98 *** wxlbind.cpp 4 Dec 2007 05:20:28 -0000 1.97 --- wxlbind.cpp 5 Dec 2007 00:34:46 -0000 1.98 *************** *** 402,409 **** int LUACALL wxluabind__newindex_wxLuaBindClass(lua_State *L) { - wxLuaState wxlState(L); - wxCHECK_MSG(wxlState.Ok(), 0, wxT("Invalid wxLuaState")); - wxLuaBindClass *wxlClass = (wxLuaBindClass *)lua_touserdata(L, lua_upvalueindex(1)); const char *name = lua_tostring(L, 2); bool found = false; --- 402,408 ---- int LUACALL wxluabind__newindex_wxLuaBindClass(lua_State *L) { wxLuaBindClass *wxlClass = (wxLuaBindClass *)lua_touserdata(L, lua_upvalueindex(1)); + wxCHECK_MSG(wxlClass, 0, wxT("Invalid wxLuaBindClass")); + const char *name = lua_tostring(L, 2); bool found = false; *************** *** 440,443 **** --- 439,445 ---- if (!found) { + wxLuaState wxlState(L); + wxCHECK_MSG(wxlState.Ok(), 0, wxT("Invalid wxLuaState")); + void *pObject = wxlua_touserdata(L, 1, false); wxLuaObject* wxlObj = new wxLuaObject(wxlState, 3); *************** *** 565,568 **** --- 567,571 ---- wxLuaBindingList wxLuaBinding::sm_bindingList; + bool wxLuaBinding::sm_bindingList_initialized = false; wxLuaBinding::wxLuaBinding() : wxObject(), *************** *** 688,699 **** } - void wxLuaBinding::UnRegisterBinding(const wxLuaState& wxlState_) - { - wxLuaState wxlState(wxlState_); // unconst the state - wxlState.lua_PushString(m_nameSpace); - wxlState.lua_PushNil(); - wxlState.lua_RawSet(LUA_GLOBALSINDEX); - } - void wxLuaBinding::DoRegisterBinding(const wxLuaState& wxlState_, int tableOffset) { --- 691,694 ---- *************** *** 801,813 **** // add the items to the table as t[first pushed] = second pushed ! lua_pushstring(L, "new"); lua_pushcfunction(L, wxlMethod->funcs[0].func); lua_rawset(L, -3); // same as lua_setfield(L, -2, "key") // Create the metatable for this table - //luaL_newmetatable(L, wxlMethod->func); // we don't need to register it lua_newtable(L); ! lua_pushstring(L, "__call"); lua_pushlightuserdata(L, &wxluabind_checkremovetable); // push tag to recognize table call lua_pushcclosure(L, wxlMethod->funcs[0].func, 1); // push func with tag as upvalue --- 796,807 ---- // add the items to the table as t[first pushed] = second pushed ! lua_pushlstring(L, "new", 3); lua_pushcfunction(L, wxlMethod->funcs[0].func); lua_rawset(L, -3); // same as lua_setfield(L, -2, "key") // Create the metatable for this table lua_newtable(L); ! lua_pushlstring(L, "__call", 6); lua_pushlightuserdata(L, &wxluabind_checkremovetable); // push tag to recognize table call lua_pushcclosure(L, wxlMethod->funcs[0].func, 1); // push func with tag as upvalue *************** *** 821,825 **** // add table to the binding table t[wxlMethod->name] = { this table } ! lua_rawset(L, -3); // same as lua_settable(L, tableOffset); #elif 0 // C++ constructors are userdata, use metatable for access to items. --- 815,819 ---- // add table to the binding table t[wxlMethod->name] = { this table } ! lua_rawset(L, -3); #elif 0 // C++ constructors are userdata, use metatable for access to items. *************** *** 1079,1080 **** --- 1073,1161 ---- } + void wxLuaBinding::InitAllBindings(bool force_update) + { + if (sm_bindingList_initialized && !force_update) return; + + // setup base class tags + wxLuaBindingList::compatibility_iterator node = sm_bindingList.GetFirst(); + while (node) + { + wxLuaBinding* binding = node->GetData(); + wxLuaBindClass* wxlClass = binding->GetClassArray(); + size_t i, class_count = binding->GetClassCount(); + + for (i = 0; i < class_count; ++i, ++wxlClass) + { + if (wxlClass->baseclassName) // does it have a name + { + wxLuaBindingList::compatibility_iterator basenode; + for (basenode = sm_bindingList.GetFirst(); basenode; basenode = basenode->GetNext() ) + { + wxLuaBinding* basebinding = basenode->GetData(); + + // found base class in binding? + if (basebinding->SetBaseClass(wxlClass)) + break; + } + } + } + + node = node->GetNext(); + } + + // Link together all of the class member functions with base class functions + // with the same name so the overloads work for them too. + node = sm_bindingList.GetFirst(); + while (node) + { + wxLuaBinding* binding = node->GetData(); + wxLuaBindClass* wxlClass = binding->GetClassArray(); + size_t i, class_count = binding->GetClassCount(); + + for (i = 0; i < class_count; ++i, ++wxlClass) + { + if (wxlClass->baseclass) // does it have a base class at all? + { + wxLuaBindMethod *wxlMethod = wxlClass->methods; + size_t j, method_count = wxlClass->methods_n; + + for (j = 0; j < method_count; ++j, ++wxlMethod) + { + // iterate through the base classes to find if this function is + // an overload, but only if we haven't checked already. + if (!WXLUA_HASBIT(wxlMethod->type, WXLUAMETHOD_OVERLOAD_BASE|WXLUAMETHOD_DELETE)) + { + wxLuaBindClass *baseClass = wxlClass->baseclass; + wxLuaBindMethod *parentMethod = wxlMethod; + + while (baseClass) + { + parentMethod->type |= WXLUAMETHOD_OVERLOAD_BASE; // have checked this + + wxLuaBindMethod* baseMethod = wxLuaBinding::GetClassMethod(baseClass, wxlMethod->name, false); + if (baseMethod) + { + // don't link to base class delete functions + if (!WXLUA_HASBIT(baseMethod->type, WXLUAMETHOD_DELETE)) + { + parentMethod->basemethod = baseMethod; + parentMethod = baseMethod; + } + + // we have already checked the base classes below this + if (WXLUA_HASBIT(baseMethod->type, WXLUAMETHOD_OVERLOAD_BASE)) + break; + } + + baseClass = baseClass->baseclass; + } + } + } + } + } + + node = node->GetNext(); + } + + sm_bindingList_initialized = true; + } \ No newline at end of file Index: wxlcallb.cpp =================================================================== RCS file: /cvsroot/wxlua/wxLua/modules/wxlua/src/wxlcallb.cpp,v retrieving revision 1.44 retrieving revision 1.45 diff -C2 -d -r1.44 -r1.45 *** wxlcallb.cpp 4 Dec 2007 05:20:28 -0000 1.44 --- wxlcallb.cpp 5 Dec 2007 00:34:46 -0000 1.45 *************** *** 36,43 **** wxCHECK_RET(m_wxlState.Ok(), wxT("Invalid wxLuaState")); - m_wxlState.AddTrackedCallback(this); - m_wxlBindEvent = wxlState.GetLuaEvent(eventType); if (m_wxlBindEvent == NULL) { --- 36,43 ---- wxCHECK_RET(m_wxlState.Ok(), wxT("Invalid wxLuaState")); m_wxlBindEvent = wxlState.GetLuaEvent(eventType); + m_wxlState.AddTrackedCallback(this); + if (m_wxlBindEvent == NULL) { *************** *** 79,96 **** // Ok if !Ok() since the wxLuaState may been cleared during shutdown or after destroy event wxLuaState wxlState(theCallback->GetwxLuaState()); ! if (!wxlState.Ok()) ! return; ! ! wxEventType evtType = event.GetEventType(); ! wxlState.SetInEventType(evtType); ! theCallback->CallFunction(&event); ! // we want the wxLuaWinDestroyCallback to get this too ! if (evtType == wxEVT_DESTROY) ! event.Skip(); ! wxlState.SetInEventType(wxEVT_NULL); } --- 79,96 ---- // Ok if !Ok() since the wxLuaState may been cleared during shutdown or after destroy event wxLuaState wxlState(theCallback->GetwxLuaState()); ! if (wxlState.Ok()) ! { ! wxEventType evtType = event.GetEventType(); ! wxlState.SetInEventType(evtType); ! theCallback->CallFunction(&event); ! // we want the wxLuaWinDestroyCallback to get this too ! if (evtType == wxEVT_DESTROY) ! event.Skip(); ! wxlState.SetInEventType(wxEVT_NULL); ! } } *************** *** 138,141 **** --- 138,142 ---- // don't track this since we didn't create it // Tracking this causes clashes in the object registry table + // since many can be created and deleted and the mem address is resused by C++. wxlState.wxluaT_PushUserTag(event, event_tag, false); wxlState.LuaPCall(1, 0); *************** *** 213,236 **** // and when the dialog is closed the frame below sends an activation event, // but we're right in the middle of being destroyed and we crash. ! wxList::compatibility_iterator node = m_wxlState.GetTrackedCallbackList()->GetFirst(); ! while (node) { ! wxLuaCallback *wxlCallback = (wxLuaCallback *)node->GetData(); if (wxlCallback->GetEvtHandler() == evtHandler) { - // delete the reference to all other handlers that are cleared - wxList::compatibility_iterator pc_node = node; // remember current node - node = node->GetNext(); - m_wxlState.GetTrackedCallbackList()->Erase(pc_node); - // remove the ref to the routine since we're clearing the wxLuaState // See ~wxLuaCallback m_wxlState.wxluaR_Unref(wxlCallback->GetLuaRoutine(), &wxlua_lreg_refs_key); wxlCallback->ClearwxLuaState(); } ! else ! node = node->GetNext(); } } } --- 214,248 ---- // and when the dialog is closed the frame below sends an activation event, // but we're right in the middle of being destroyed and we crash. ! ! lua_State* L = m_wxlState.GetLuaState(); ! ! lua_pushlightuserdata(L, &wxlua_lreg_evtcallbacks_key); // push key ! lua_rawget(L, LUA_REGISTRYINDEX); // pop key, push value (table) ! ! lua_pushnil(L); ! while (lua_next(L, -2) != 0) { ! // value = -1, key = -2, table = -3 ! wxLuaCallback* wxlCallback = (wxLuaCallback*)lua_touserdata(L, -1); ! wxCHECK_RET(wxlCallback, wxT("Invalid wxLuaCallback")); if (wxlCallback->GetEvtHandler() == evtHandler) { // remove the ref to the routine since we're clearing the wxLuaState // See ~wxLuaCallback m_wxlState.wxluaR_Unref(wxlCallback->GetLuaRoutine(), &wxlua_lreg_refs_key); wxlCallback->ClearwxLuaState(); + + 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, lua_next will pop key at end } + + lua_pop(L, 1); // pop table } } Index: wxlua_bind.cpp =================================================================== RCS file: /cvsroot/wxlua/wxLua/modules/wxlua/src/wxlua_bind.cpp,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** wxlua_bind.cpp 4 Dec 2007 05:20:28 -0000 1.10 --- wxlua_bind.cpp 5 Dec 2007 00:34:46 -0000 1.11 *************** *** 1,4 **** // --------------------------------------------------------------------------- ! // This file was generated by genwxbind.lua // // Any changes made to this file may be lost when file is regenerated. --- 1,4 ---- // --------------------------------------------------------------------------- ! // This file was generated by genwxbind.lua // // Any changes made to this file may be lost when file is regenerated. *************** *** 965,969 **** { "wxLUA_CHECK_VERSION_FULL", WXLUAMETHOD_CFUNCTION, s_wxluafunc_wxLua_function_wxLUA_CHECK_VERSION_FULL, 1, NULL }, ! { 0, 0, 0, 0 }, }; count = sizeof(functionList)/sizeof(wxLuaBindMethod) - 1; --- 965,969 ---- { "wxLUA_CHECK_VERSION_FULL", WXLUAMETHOD_CFUNCTION, s_wxluafunc_wxLua_function_wxLUA_CHECK_VERSION_FULL, 1, NULL }, ! { 0, 0, 0, 0 }, }; count = sizeof(functionList)/sizeof(wxLuaBindMethod) - 1; *************** *** 981,988 **** static wxLuaBindClass classList[] = { ! { "wxLuaObject", wxLuaObject_methods, wxLuaObject_methodCount, CLASSINFO(wxLuaObject), &s_wxluatag_wxLuaObject, "wxObject", NULL ,s_wxluadefineArray_None, 0, }, ! { "wxLuaState", wxLuaState_methods, wxLuaState_methodCount, CLASSINFO(wxLuaState), &s_wxluatag_wxLuaState, "wxObject", NULL ,s_wxluadefineArray_None, 0, }, ! { 0, 0, 0, 0, 0, 0, 0 }, }; count = sizeof(classList)/sizeof(wxLuaBindClass) - 1; --- 981,988 ---- static wxLuaBindClass classList[] = { ! { "wxLuaObject", wxLuaObject_methods, wxLuaObject_methodCount, CLASSINFO(wxLuaObject), &s_wxluatag_wxLuaObject, "wxObject", NULL ,s_wxluadefineArray_None, 0, }, ! { "wxLuaState", wxLuaState_methods, wxLuaState_methodCount, CLASSINFO(wxLuaState), &s_wxluatag_wxLuaState, "wxObject", NULL ,s_wxluadefineArray_None, 0, }, ! { 0, 0, 0, 0, 0, 0, 0 }, }; count = sizeof(classList)/sizeof(wxLuaBindClass) - 1; |