Author Topic: issue in the event handler of the workspace changed event  (Read 10236 times)

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 6023
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
issue in the event handler of the workspace changed event
« on: June 11, 2014, 04:37:33 pm »
When reviewing the CC code, I see some comments here:
Code
void CodeCompletion::OnWorkspaceChanged(CodeBlocksEvent& event)
{
    // EVT_WORKSPACE_CHANGED is a powerful event, it's sent after any project
    // has finished loading or closing. It's the *LAST* event to be sent when
    // the workspace has been changed, and it's not sent if the application is
    // shutting down. So it's the ideal time to parse files and update your
    // widgets.
    if (IsAttached() && m_InitDone)
It said that WorkspaceChanged event does not sent when application is shutting down, but on my test, it did send.
I set a breakpoint, and I just close the application, now it hits the breakpoint. The bt is below:

Code
[debug]> bt 30
[debug]#0  CodeCompletion::OnWorkspaceChanged (this=0x1243c008, event=...) at F:\cb_sf_git\trunk\src\plugins\codecompletion\codecompletion.cpp:2280
[debug]#1  0x700b9063 in cbEventFunctor<CodeCompletion, CodeBlocksEvent>::Call (this=0x1243ae90, event=...) at F:\cb_sf_git\trunk\src\include\cbfunctor.h:49
[debug]#2  0x0112a626 in Manager::ProcessEvent (this=0x10a5bf78, event=...) at F:\cb_sf_git\trunk\src\sdk\manager.cpp:261
[debug]#3  0x0113c2af in PluginManager::NotifyPlugins (this=0x124164c0, event=...) at F:\cb_sf_git\trunk\src\sdk\pluginmanager.cpp:1445
[debug]#4  0x011553db in ProjectManager::WorkspaceChanged (this=0x1101a600) at F:\cb_sf_git\trunk\src\sdk\projectmanager.cpp:927
[debug]#5  0x011540f4 in ProjectManager::CloseWorkspace (this=0x1101a600) at F:\cb_sf_git\trunk\src\sdk\projectmanager.cpp:599
[debug]#6  0x0044deb2 in MainFrame::DoCloseCurrentWorkspace (this=0x10a91cb0) at F:\cb_sf_git\trunk\src\src\main.cpp:1877
[debug]#7  0x00452d08 in MainFrame::OnApplicationClose (this=0x10a91cb0, event=...) at F:\cb_sf_git\trunk\src\src\main.cpp:2725
[debug]#8  0x04c11b0e in wxAppConsole::HandleEvent (this=0x10a24ba8, handler=0x10a91cb0, func=(void (wxEvtHandler::*)(wxEvtHandler * const, wxEvent &)) 0x452b32 <MainFrame::OnApplicationClose(wxCloseEvent&)>, event=...) at E:\code\wx-mingw-build-481-dw2\wxWidgets-2.8.12\src\common\appbase.cpp:322
[debug]#9  0x04c9273d in wxEvtHandler::ProcessEventIfMatches (entry=..., handler=0x10a91cb0, event=...) at E:\code\wx-mingw-build-481-dw2\wxWidgets-2.8.12\src\common\event.cpp:1239
[debug]#10 0x04c91d53 in wxEventHashTable::HandleEvent (this=0x541854 <MainFrame::sm_eventHashTable>, event=..., self=0x10a91cb0) at E:\code\wx-mingw-build-481-dw2\wxWidgets-2.8.12\src\common\event.cpp:906
[debug]#11 0x04c9293a in wxEvtHandler::ProcessEvent (this=0x10a91cb0, event=...) at E:\code\wx-mingw-build-481-dw2\wxWidgets-2.8.12\src\common\event.cpp:1301
[debug]#12 0x04c92976 in wxEvtHandler::ProcessEvent (this=0x10a91e50, event=...) at E:\code\wx-mingw-build-481-dw2\wxWidgets-2.8.12\src\common\event.cpp:1308
[debug]#13 0x04c92976 in wxEvtHandler::ProcessEvent (this=0x1101a604, event=...) at E:\code\wx-mingw-build-481-dw2\wxWidgets-2.8.12\src\common\event.cpp:1308
[debug]#14 0x04c92976 in wxEvtHandler::ProcessEvent (this=0x10aa68c8, event=...) at E:\code\wx-mingw-build-481-dw2\wxWidgets-2.8.12\src\common\event.cpp:1308
[debug]#15 0x04c92976 in wxEvtHandler::ProcessEvent (this=0x1105bd58, event=...) at E:\code\wx-mingw-build-481-dw2\wxWidgets-2.8.12\src\common\event.cpp:1308
[debug]#16 0x04c92976 in wxEvtHandler::ProcessEvent (this=0x10ac2a58, event=...) at E:\code\wx-mingw-build-481-dw2\wxWidgets-2.8.12\src\common\event.cpp:1308
[debug]#17 0x04c92976 in wxEvtHandler::ProcessEvent (this=0x1105c810, event=...) at E:\code\wx-mingw-build-481-dw2\wxWidgets-2.8.12\src\common\event.cpp:1308
[debug]#18 0x04c92976 in wxEvtHandler::ProcessEvent (this=0x10abf56c, event=...) at E:\code\wx-mingw-build-481-dw2\wxWidgets-2.8.12\src\common\event.cpp:1308
[debug]#19 0x04c92976 in wxEvtHandler::ProcessEvent (this=0x124164c4, event=...) at E:\code\wx-mingw-build-481-dw2\wxWidgets-2.8.12\src\common\event.cpp:1308
[debug]#20 0x04c92976 in wxEvtHandler::ProcessEvent (this=0x1241655c, event=...) at E:\code\wx-mingw-build-481-dw2\wxWidgets-2.8.12\src\common\event.cpp:1308
[debug]#21 0x04c92976 in wxEvtHandler::ProcessEvent (this=0x1243c008, event=...) at E:\code\wx-mingw-build-481-dw2\wxWidgets-2.8.12\src\common\event.cpp:1308
[debug]#22 0x04c92976 in wxEvtHandler::ProcessEvent (this=0x12441ff8, event=...) at E:\code\wx-mingw-build-481-dw2\wxWidgets-2.8.12\src\common\event.cpp:1308
[debug]#23 0x04c92976 in wxEvtHandler::ProcessEvent (this=0x1394ba68, event=...) at E:\code\wx-mingw-build-481-dw2\wxWidgets-2.8.12\src\common\event.cpp:1308
[debug]#24 0x04c92976 in wxEvtHandler::ProcessEvent (this=0x126aaf18, event=...) at E:\code\wx-mingw-build-481-dw2\wxWidgets-2.8.12\src\common\event.cpp:1308
[debug]#25 0x04c92976 in wxEvtHandler::ProcessEvent (this=0x12639100, event=...) at E:\code\wx-mingw-build-481-dw2\wxWidgets-2.8.12\src\common\event.cpp:1308
[debug]#26 0x04c92976 in wxEvtHandler::ProcessEvent (this=0x12645a50, event=...) at E:\code\wx-mingw-build-481-dw2\wxWidgets-2.8.12\src\common\event.cpp:1308
[debug]#27 0x04c92976 in wxEvtHandler::ProcessEvent (this=0x146c4848, event=...) at E:\code\wx-mingw-build-481-dw2\wxWidgets-2.8.12\src\common\event.cpp:1308
[debug]#28 0x04c92976 in wxEvtHandler::ProcessEvent (this=0x10de527c, event=...) at E:\code\wx-mingw-build-481-dw2\wxWidgets-2.8.12\src\common\event.cpp:1308
[debug]#29 0x04d95f28 in wxWindowBase::Close (this=0x10a91cb0, force=false) at E:\code\wx-mingw-build-481-dw2\wxWidgets-2.8.12\src\common\wincmn.cpp:428
[debug](More stack frames follow...)
[debug]>>>>>>cb_gdb:

Further debugging found that in this case when the event handler is called, all the projects are already closed, so the active project is NULL.

Here is the patch to fix this issue:
Code
 src/plugins/codecompletion/codecompletion.cpp | 26 +++++++++++++++-----------
 1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/src/plugins/codecompletion/codecompletion.cpp b/src/plugins/codecompletion/codecompletion.cpp
index c5da8e9..795355d 100644
--- a/src/plugins/codecompletion/codecompletion.cpp
+++ b/src/plugins/codecompletion/codecompletion.cpp
@@ -2274,22 +2274,26 @@ void CodeCompletion::OnWorkspaceChanged(CodeBlocksEvent& event)
 {
     // EVT_WORKSPACE_CHANGED is a powerful event, it's sent after any project
     // has finished loading or closing. It's the *LAST* event to be sent when
-    // the workspace has been changed, and it's not sent if the application is
-    // shutting down. So it's the ideal time to parse files and update your
-    // widgets.
+    // the workspace has been changed. So it's the ideal time to parse files
+    // and update your widgets.
     if (IsAttached() && m_InitDone)
     {
         cbProject* project = Manager::Get()->GetProjectManager()->GetActiveProject();
-        if (project && !m_NativeParser.GetParserByProject(project))
-            m_NativeParser.CreateParser(project);
+        // if we receive a workspace changed event, but the project is NULL, this means the user
+        // try to close the application, so we don't need to update the UI here.
+        if (project)
+        {
+            if (!m_NativeParser.GetParserByProject(project))
+                m_NativeParser.CreateParser(project);
 
-        // Update the Function toolbar
-        TRACE(_T("CodeCompletion::OnWorkspaceChanged: Starting m_TimerToolbar."));
-        m_TimerToolbar.Start(TOOLBAR_REFRESH_DELAY, wxTIMER_ONE_SHOT);
+            // Update the Function toolbar
+            TRACE(_T("CodeCompletion::OnWorkspaceChanged: Starting m_TimerToolbar."));
+            m_TimerToolbar.Start(TOOLBAR_REFRESH_DELAY, wxTIMER_ONE_SHOT);
 
-        // Update the class browser
-        if (m_NativeParser.GetParser().ClassBrowserOptions().displayFilter == bdfProject)
-            m_NativeParser.UpdateClassBrowser();
+            // Update the class browser
+            if (m_NativeParser.GetParser().ClassBrowserOptions().displayFilter == bdfProject)
+                m_NativeParser.UpdateClassBrowser();
+        }
     }
     event.Skip();
 }


Please help to review, and if no objections for several days, I will commit.  ;)
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.

Offline ollydbg

  • Developer
  • Lives here!
  • *****
  • Posts: 6023
  • OpenCV and Robotics
    • Chinese OpenCV forum moderator
Re: issue in the event handler of the workspace changed event
« Reply #1 on: June 19, 2014, 03:41:23 pm »
In trunk now(rev9817).
If some piece of memory should be reused, turn them to variables (or const variables).
If some piece of operations should be reused, turn them to functions.
If they happened together, then turn them to classes.