From f5aabc5f6223c84d85cf3650358bc50f8359ab1c Mon Sep 17 00:00:00 2001 From: Robin Dunn Date: Tue, 29 Aug 2017 15:28:17 -0700 Subject: [PATCH] Fix bad interaction between wxpTag and how wxmodules are reinitialized now. Change wxPyHtmlTagsModule to be a normal wxModule that is created and initialized by the system, and track all the tag handler classes in a static member so they can be found again after modules are reinitialized again in the future. --- etg/htmlwinpars.py | 82 +++++++++++++++++++++++++++------------------- 1 file changed, 48 insertions(+), 34 deletions(-) diff --git a/etg/htmlwinpars.py b/etg/htmlwinpars.py index 6c1e8f31..6c7bec05 100644 --- a/etg/htmlwinpars.py +++ b/etg/htmlwinpars.py @@ -61,64 +61,78 @@ def run(): module.addCppCode("""\ class wxPyHtmlTagsModule : public wxHtmlTagsModule { public: - wxPyHtmlTagsModule(PyObject* thc) : wxHtmlTagsModule() { - m_tagHandlerClass = thc; - wxPyThreadBlocker blocker; - Py_INCREF(m_tagHandlerClass); - RegisterModule(this); + wxPyHtmlTagsModule() : wxHtmlTagsModule() { + } + + bool OnInit() { wxHtmlWinParser::AddModule(this); + return true; } void OnExit() { wxPyThreadBlocker blocker; - Py_DECREF(m_tagHandlerClass); - m_tagHandlerClass = NULL; - for (size_t x=0; x < m_objArray.GetCount(); x++) { - PyObject* obj = (PyObject*)m_objArray.Item(x); + for (size_t x=0; x < m_tagHandlersArray.GetCount(); x++) { + PyObject* obj = (PyObject*)m_tagHandlersArray.Item(x); Py_DECREF(obj); } + m_tagHandlersArray.Clear(); + wxHtmlWinParser::RemoveModule(this); } void FillHandlersTable(wxHtmlWinParser *parser) { wxPyThreadBlocker blocker; - wxHtmlWinTagHandler* thPtr = 0; - // First, make a new instance of the tag handler - PyObject* arg = PyTuple_New(0); - PyObject* obj = PyObject_CallObject(m_tagHandlerClass, arg); - Py_DECREF(arg); - // Make sure it succeeded - if (!obj) { - PyErr_Print(); - return; + // make a new instance of each handler class and register it with the parser + for (size_t cls=0; cls < s_tagHandlerClasses.GetCount(); cls++) { + PyObject* pyClass = (PyObject*)s_tagHandlerClasses.Item(cls); + + wxHtmlWinTagHandler* thPtr = NULL; + + PyObject* arg = PyTuple_New(0); + PyObject* obj = PyObject_CallObject(pyClass, arg); + Py_DECREF(arg); + + // Make sure it succeeded + if (!obj) { + PyErr_Print(); + return; + } + + // now figure out where it's C++ object is... + if (! wxPyConvertWrappedPtr(obj, (void **)&thPtr, wxT("wxHtmlWinTagHandler"))) { + return; + } + + // add it, + parser->AddTagHandler(thPtr); + + // and track it + m_tagHandlersArray.Add(obj); } + } - // now figure out where it's C++ object is... - if (! wxPyConvertWrappedPtr(obj, (void **)&thPtr, wxT("wxHtmlWinTagHandler"))) { - return; - } - - // add it, - parser->AddTagHandler(thPtr); - - // and track it. - m_objArray.Add(obj); + static void AddPyTagHandler(PyObject* tagHandlerClass) { + wxPyThreadBlocker blocker; + Py_INCREF(tagHandlerClass); + s_tagHandlerClasses.Add(tagHandlerClass); } private: - PyObject* m_tagHandlerClass; - wxArrayPtrVoid m_objArray; + wxDECLARE_DYNAMIC_CLASS(wxPyHtmlTagsModule); + static wxArrayPtrVoid s_tagHandlerClasses; + wxArrayPtrVoid m_tagHandlersArray; }; + + wxIMPLEMENT_DYNAMIC_CLASS(wxPyHtmlTagsModule, wxHtmlTagsModule) + wxArrayPtrVoid wxPyHtmlTagsModule::s_tagHandlerClasses; """) module.addCppFunction('void', 'HtmlWinParser_AddTagHandler', '(PyObject* tagHandlerClass)', body="""\ - // Dynamically create a new wxModule. Refcounts tagHandlerClass - // and adds itself to the wxModules list and to the wxHtmlWinParser. - new wxPyHtmlTagsModule(tagHandlerClass); - wxModule::InitializeModules(); + wxPyHtmlTagsModule::AddPyTagHandler(tagHandlerClass); + wxPyReinitializeModules(); """)