Author Topic: cbEVT_PROJECT_OPEN and cbEVT_PROJECT_ACTIVATE  (Read 5098 times)

Offline daniloz

  • Regular
  • ***
  • Posts: 268
cbEVT_PROJECT_OPEN and cbEVT_PROJECT_ACTIVATE
« on: December 01, 2011, 02:25:05 pm »
Hi All,

I'm observing some unexpected behavior when using cbEVT_PROJECT_OPEN and cbEVT_PROJECT_ACTIVATE. Of course, unexpected from the point of view of what "I" was expecting... ;-)

So, I was expecting that cbEVT_PROJECT_OPEN would be fired up when the projects are opening (if we have more than one in the workspace) and just after all projects were loaded cbEVT_PROJECT_ACTIVATE would fire up...

But in my plugin, I'm seeing that cbEVT_PROJECT_ACTIVATE gets fired up before any hit on cbEVT_PROJECT_OPEN...

Any thoughts? Explanations?

Edit:

I found the following code in projectmanager.cpp:
Code: [Select]
        RebuildTree();
        if (m_pActiveProject || m_pProjectToActivate)
        {
            if (m_pProjectToActivate)
            {
                SetProject(m_pProjectToActivate, true);
                m_pProjectToActivate = 0L;
            }
            m_pTree->Expand(m_pActiveProject->GetProjectNode());
        }
        m_pTree->Expand(m_TreeRoot); // make sure the root node is open
        m_pTree->SetItemText(m_TreeRoot, m_pWorkspace->GetTitle());

        UnfreezeTree(true);
        // sort out any global user vars that need to be defined now (in a batch) :)
        Manager::Get()->GetUserVariableManager()->Arrogate();

        int numNotes = 0;

        // and now send the project loaded events
        // since we were loading a workspace, these events were not sent before
        for (size_t i = 0; i < m_pProjects->GetCount(); ++i)
        {
            cbProject* project = m_pProjects->Item(i);

            // notify plugins that the project is loaded
            // moved here from cbProject::Open() because code-completion
            // kicks in too early and the perceived loading time is long...
            CodeBlocksEvent event(cbEVT_PROJECT_OPEN);
            event.SetProject(project);
            Manager::Get()->GetPluginManager()->NotifyPlugins(event);

            // since we 're iterating anyway, let's count the project notes that should be displayed
            if (project->GetShowNotesOnLoad() && !project->GetNotes().IsEmpty())
                ++numNotes;
        }

So, I was right, the project is first activated (SetProject(m_pProjectToActivate, true)) and then the plugins are notified that the project are loaded.

@devs: Is this intended to be so? Any particular reason? I'd do the other way around: first send the LOAD notification to the plugins and then the ACTIVATE...
« Last Edit: December 01, 2011, 03:15:45 pm by daniloz »

Offline Alpha

  • Developer
  • Lives here!
  • *****
  • Posts: 1513
Re: cbEVT_PROJECT_OPEN and cbEVT_PROJECT_ACTIVATE
« Reply #1 on: December 02, 2011, 03:50:56 am »
I think cbEVT_PROJECT_ACTIVATE is supposed to be triggered whenever anything gets bold-ed in the Projects tab of the Management pane.  (I am far from being a developer, so I could be completely wrong.)

(You could optionally do some detective work with the DisplayEvents plugin.)

Offline daniloz

  • Regular
  • ***
  • Posts: 268
Re: cbEVT_PROJECT_OPEN and cbEVT_PROJECT_ACTIVATE
« Reply #2 on: December 02, 2011, 08:38:03 am »
Here is the output of the DisplayEvents plugin for a workspace with 4 projects (I just cut off the non-interesting parts):

Code: [Select]
08:31:13,688  =>  cbEVT_WORKSPACE_CHANGED
Loading workspace "C:\Data\GPA\FW-DSP\Flexus.workspace"
Loading project file...
Parsing project file...
[...]
Loading project files...
[...]
261 files loaded
Done loading project in 423ms
08:31:14,137  =>  cbEVT_BUILDTARGET_SELECTED
Loading project file...
Parsing project file...
[...]
Loading project files...
[...]
202 files loaded
Done loading project in 379ms
08:31:14,528  =>  cbEVT_BUILDTARGET_SELECTED
Loading project file...
Parsing project file...
[...]
2 files loaded
Done loading project in 8ms
[...]
08:31:14,540  =>  cbEVT_BUILDTARGET_SELECTED
Loading project file...
Parsing project file...
[...]
2 files loaded
Done loading project in 8ms
[...]
08:31:14,553  =>  cbEVT_BUILDTARGET_SELECTED
08:31:15,165  =>  cbEVT_COMPILER_SET_BUILD_OPTIONS
08:31:15,166  =>  cbEVT_COMPILER_SET_BUILD_OPTIONS
08:31:15,167  =>  cbEVT_COMPILER_SET_BUILD_OPTIONS
08:31:15,184  =>  cbEVT_PROJECT_ACTIVATE
08:31:15,188  =>  cbEVT_PROJECT_OPEN
08:31:15,189  =>  cbEVT_PROJECT_OPEN
08:31:15,190  =>  cbEVT_PROJECT_OPEN
08:31:15,191  =>  cbEVT_PROJECT_OPEN
08:31:15,192  =>  cbEVT_WORKSPACE_CHANGED
08:31:15,193  =>  cbEVT_WORKSPACE_LOADING_COMPLETE

Note at the end, that as I've reported the cbEVT_PROJECT_ACTIVATE occurs before the four cbEVT_PROJECT_OPEN.

Offline Alpha

  • Developer
  • Lives here!
  • *****
  • Posts: 1513
Re: cbEVT_PROJECT_OPEN and cbEVT_PROJECT_ACTIVATE
« Reply #3 on: December 03, 2011, 09:06:41 pm »
I would guess that the purpose of cbEVT_PROJECT_ACTIVATE is to notify at the beginning of any process that will change which project is the active project.
Code: [Select]
[... open workspace, read stuff ...]
14:32:25,785  =>  cbEVT_PROJECT_ACTIVATE
14:32:25,795  =>  cbEVT_PROJECT_OPEN
14:32:25,805  =>  cbEVT_PROJECT_OPEN
14:32:25,805  =>  cbEVT_PROJECT_OPEN
14:32:25,805  =>  cbEVT_PROJECT_OPEN
14:32:25,805  =>  cbEVT_PROJECT_OPEN
14:32:25,805  =>  cbEVT_PROJECT_OPEN
14:32:25,815  =>  cbEVT_WORKSPACE_CHANGED
[... parse files, set compiler options ...]
[... double click on a different project in the workspace ...]
14:33:26,512  =>  cbEVT_PROJECT_ACTIVATE
[... double click on the first project in the workspace ...]
14:37:35,601  =>  cbEVT_PROJECT_ACTIVATE
[... close a project ...]
14:40:57,381  =>  cbEVT_PROJECT_CLOSE
14:40:57,391  =>  cbEVT_BUILDTARGET_SELECTED
14:40:57,391  =>  cbEVT_WORKSPACE_CHANGED
[... close the active project ...]
Removed StringCtrl from all deps
15:01:53,086  =>  cbEVT_PROJECT_CLOSE
15:01:58,134  =>  cbEVT_PROJECT_ACTIVATE
15:01:58,134  =>  cbEVT_BUILDTARGET_SELECTED
15:01:58,134  =>  cbEVT_WORKSPACE_CHANGED
Delete parser for project 'StringCtrl'!
(Log output has been trimmed.)

Offline daniloz

  • Regular
  • ***
  • Posts: 268
Re: cbEVT_PROJECT_OPEN and cbEVT_PROJECT_ACTIVATE
« Reply #4 on: December 05, 2011, 09:49:25 pm »
I would guess that the purpose of cbEVT_PROJECT_ACTIVATE is to notify at the beginning of any process that will change which project is the active project.
I don't agree, because the event carries the active project, so I'd expect (apart from the name itself) that the event would be triggered when a new project just became active. Moreover, it's trigered from ProjectManager::SetProject() just after a project has become active...

@devs any feedback?

Offline MortenMacFly

  • Administrator
  • Lives here!
  • *****
  • Posts: 9592
Re: cbEVT_PROJECT_OPEN and cbEVT_PROJECT_ACTIVATE
« Reply #5 on: December 06, 2011, 04:36:44 pm »
@devs any feedback?
I'm afraid this might be caused due to a change in the logic how projects are processed in combination with (re-)building the visual project tree. This change was done to speed-up the process and this event might not have been considered. You could check this by compiling the DisplayEvents plugin against 10.05 (for example) and see if the order was really different.

However, it really means to inform whenever a project is activated which is what it does. That the order is now after the project open event maybe something to fix by moving the project open event before activate, but this needs to be done with care.

I wonder why you need both: Open and Activate. Usually you only need one of these depending on what you have in mind and then the order becomes not important. Is there a particular reason why you need the Open before the Avtivate event?
Compiler logging: Settings->Compiler & Debugger->tab "Other"->Compiler logging="Full command line"
C::B Manual: http://www.codeblocks.org/docs/main_codeblocks_en.html
C::B FAQ: http://wiki.codeblocks.org/index.php?title=FAQ

Offline daniloz

  • Regular
  • ***
  • Posts: 268
Re: cbEVT_PROJECT_OPEN and cbEVT_PROJECT_ACTIVATE
« Reply #6 on: December 06, 2011, 05:37:47 pm »
@devs any feedback?
I'm afraid this might be caused due to a change in the logic how projects are processed in combination with (re-)building the visual project tree. This change was done to speed-up the process and this event might not have been considered. You could check this by compiling the DisplayEvents plugin against 10.05 (for example) and see if the order was really different.
Thanks for the reply, Morten.

I've tried with 10.05 and it's even worst (from my point of view). From the log below, you'll see that the cbEVT_PROJECT_ACTIVATE is triggered after loading the first project, which is the active one. But the four cbEVT_PROJECT_OPEN just come at the end of the workspace loading.

So, to answer your question... it's different, but not yet what I'd expect...

Code: [Select]
17:21:24,622  =>  cbEVT_WORKSPACE_CHANGED
17:21:24,626  =>  cbEVT_EDITOR_CLOSE
Loading workspace "C:\Data\GPA\FW-DSP\Flexus.workspace"
Loading project file...
Parsing project file...
[...]
261 files loaded
Done loading project in 41ms
[...]
17:21:24,859  =>  cbEVT_PROJECT_ACTIVATE
Loading project file...
Parsing project file...
[...]
202 files loaded
Done loading project in 47ms
[...]
2 files loaded
Done loading project in 13ms
Loading project file...
Parsing project file...
[...]
2 files loaded
Done loading project in 12ms
[...]
17:21:25,261  =>  cbEVT_PROJECT_OPEN
17:21:25,262  =>  cbEVT_PROJECT_OPEN
17:21:25,263  =>  cbEVT_PROJECT_OPEN
17:21:25,267  =>  cbEVT_PROJECT_OPEN
[...]
Updating class browser...
Class browser updated.
17:21:25,939  =>  cbEVT_WORKSPACE_CHANGED

However, it really means to inform whenever a project is activated which is what it does. That the order is now after the project open event maybe something to fix by moving the project open event before activate, but this needs to be done with care.
That's what I'd do, if I knew the code better... but I understand that this has to be done with extra care to avoid breaking something else...

I wonder why you need both: Open and Activate. Usually you only need one of these depending on what you have in mind and then the order becomes not important. Is there a particular reason why you need the Open before the Avtivate event?
Maybe there's a clever way of doing things, but I'm writing a source control plugin for MS Visual SourceSafe and I get the config information from the project on Open. And whenever then user activate another project, I use this information to display the actual files in check-out for the active project on Activate.

It all works well, expect when loading a workspace with more than one project. Then, I hit the Activate before having seen the Open and I don't have the config information to access the SourceSafe DataBase...