User forums > Using Code::Blocks

Hiccups while typing (continuation)

<< < (5/8) > >>

ollydbg:
I'm not fully understand the patch, it looks like all the Parser instance will share the same "option".

If you set a breakpoint(BP) in the file: parser.cpp, in the function body: void Parser::WriteOptions()

Then do something like below:

1, start C::B, this will hit the BP
2, when you open a project, the BP will hit again, at this time, "ReadOptions()" will be called, and returned without writing to the configure file.
3, when you change the classbrowser's option, from current "project" to "everything", the BP will hit again, and "ReadOptions()" will be called again, but still not write to the configure file.

From my point of view, this is not correct.

As Tim said, we should use "../xxxxx.h" include directive, thanks.

Pecan:

--- Quote from: ollydbg on February 05, 2025, 09:42:56 am ---I'm not fully understand the patch, it looks like all the Parser instance will share the same "option".

If you set a breakpoint(BP) in the file: parser.cpp, in the function body: void Parser::WriteOptions()

Then do something like below:

1, start C::B, this will hit the BP
2, when you open a project, the BP will hit again, at this time, "ReadOptions()" will be called, and returned without writing to the configure file.
3, when you change the classbrowser's option, from current "project" to "everything", the BP will hit again, and "ReadOptions()" will be called again, but still not write to the configure file.

From my point of view, this is not correct.

As Tim said, we should use "../xxxxx.h" include directive, thanks.

--- End quote ---

I can't find a "Class browser's option. Where is that?
I can possible make those options "always write" if I could figure out where that is.

As it is with the patch:
If no changes were ever made to settings, why should anything be written to the .conf?

The write to .conf takes place when a user changes an item in MainMenu>settings>CodeCompletion.

@parser.cpp void Parser::WriteOptions()
WriteOptions take place on CB startup but changes nothing because active parser is null and m_pOptsChangerProject is null.

Any change made while no project is active gets written to .conf

When a project is loaded nothing has changed in .conf, so no write options need to be done.

If changes are made to settings (OnApply is entered), the active parser that made the changes
is recorded by OnApply().
Those changes are then written to the .conf, and only the settings made by that
active project are written to the .conf. all other projects read those settings.

If no user setting are made via settings, no need to care about writing the .conf.]

--- Code: ---ActiveProject   OnAppy project  ActiveProject != OnApplyProject     action
--------------  --------------  -------------------------------    ----------
nullptr          nullptr        False,  will write                  .conf written at startup
nullptr          nullptr        False,  will write                  no projects,.option changed, .conf wrtten
Nullptr          Not null       Does not happen                     Can't happen, no project to record
Not null         nullptr        True,   no write                    no setting changed, no writes
Not null         not null       False,  will write                  option changed, .conf written
nullptr          nullptr        False,  will write                  project closed but no options change, no write
nullptr          not null       True,   no write                    project closed, .conf written for matching project

--- End code ---

Writes to the .conf take place only when there is no project or when a project changes options.
when a project changes options, only that project is allow to write the .conf

ollydbg:

--- Quote from: Pecan on February 05, 2025, 06:57:53 pm ---I can't find a "Class browser's option. Where is that?
I can possible make those options "always write" if I could figure out where that is.

--- End quote ---

If you look at this function: void Parser::WriteOptions(), you will see that it actually save two member variables: one is the m_Options, and the other is the m_BrowserOptions.
In my mind, it looks like the "m_BrowserOptions" is shared by all the Parser instances. But the "m_Options" is not, so each Parser instance has its own "m_Options". So, switch the Parser won't switch the browser options, instead, it keep the browser options, but the "m_Options" need to be changed if different Parsers have different m_Options.

So, when a Parser is constructed, it first read the "m_BrowserOptions" and "m_Options" from the configure file, and later user can adjust its own options.

When we switch cbp in a workspace, one Parser get active, so its "m_Options" get active, at this time, the configure file is updated, I mean the active parser's "m_Options" is saved to the configure file.

But if you look at the function: void ClassBrowser::SetParser(ParserBase* parser), you will see:


--- Code: ---// ----------------------------------------------------------------------------
void ClassBrowser::SetParser(ParserBase* parser)
// ----------------------------------------------------------------------------
{
    if (m_Parser == parser)
        return;

    m_Parser = parser;
    if (m_Parser)
    {
        const int sel = XRCCTRL(*this, "cmbView", wxChoice)->GetSelection();
        BrowserDisplayFilter filter = static_cast<BrowserDisplayFilter>(sel);
        if (!m_ParseManager->IsParserPerWorkspace() && filter == bdfWorkspace)
            filter = bdfProject;

        m_Parser->ClassBrowserOptions().displayFilter = filter;
        m_Parser->WriteOptions();
        UpdateClassBrowserView();
    }
    else
        CCLogger::Get()->DebugLog("SetParser: No parser available.");
}

--- End code ---

You see the "m_Parser->WriteOptions();" also get called.

So, maybe, it looks like we may need to call the "WriteClassBrowserOptions()" like function here inside the "void ClassBrowser::SetParser(ParserBase* parser)", because this class only response for the ClassBrowser related options.

ollydbg:

--- Quote ---Any change made while no project is active gets written to .conf
--- End quote ---

I agree, this include the m_Options and the m_BrowserOptions.


--- Quote ---When a project is loaded nothing has changed in .conf, so no write options need to be done.
--- End quote ---

I agree.


--- Quote ---If changes are made to settings (OnApply is entered), the active parser that made the changes is recorded by OnApply().
Those changes are then written to the .conf, and only the settings made by that active project are written to the .conf.
all other projects read those settings.
--- End quote ---

I agree that the writing of m_Options to the configure file should only happens inside the OnApply() function.
When user tweak the Class browser GUI options, it should always to saved to configure file.

But, I think the last sentence ("all other projects read those settings") is not correct. When we switch the Parser, the other Parser should read the m_BrowserOptions, because this is a global setting.
But we don't need to "re-read" the m_Options from the configure file, because different Parsers may have different parsing options.



--- Quote ---If no user setting are made via settings, no need to care about writing the .conf.
--- End quote ---
I agree.

Pecan:
@ ollydbg

Please evaluate this patch.
I've tested it with single and mult-project workspaces, Single file workspace and empty ones as well.

I think I've followed your outline (previous msg) to guard against stowing any stale global status while always allowing ClassBrowser status to be updated.



--- Code: ---Index: ccoptionsdlg.cpp
===================================================================
--- ccoptionsdlg.cpp (revision 13610)
+++ ccoptionsdlg.cpp (working copy)
@@ -183,6 +183,12 @@
 
 void CCOptionsDlg::OnApply()
 {
+    cbProject* pProject = Manager::Get()->GetProjectManager()->GetActiveProject();
+     // Remember the project that changed the .conf data //(ph 2025/02/04)
+    m_ParseManager->SetOptsChangedByProject(pProject);
+    // Renember the Parser that changed the .conf data //(ph 2025/02/04)
+    m_ParseManager->SetOptsChangedByParser(&(m_ParseManager->GetParser())); //(ph 2025/02/07)
+
     ConfigManager* cfg = Manager::Get()->GetConfigManager(_T("code_completion"));
 
     // -----------------------------------------------------------------------
Index: parsemanager.h
===================================================================
--- parsemanager.h (revision 13610)
+++ parsemanager.h (working copy)
@@ -9,8 +9,8 @@
 #include "parsemanager_base.h"
 #include "parser/parser.h"
 
-#include <queue>
-#include <map>
+//unused #include <queue>
+// unused #include <map>
 #include <memory>
 #include <unordered_map>
 
@@ -258,6 +258,14 @@
     void SetSymbolsWindowHasFocus(bool trueOrFalse){ m_SymbolsWindowHasFocus = trueOrFalse;}
     bool GetSymbolsWindowHasFocus(){return m_SymbolsWindowHasFocus;}
 
+    // Set or return Project that changed "Global setting" in workspace
+    cbProject* GetOptsChangedByProject(){ return m_pOptsChangedProject;}
+    void SetOptsChangedByProject(cbProject* pProject){m_pOptsChangedProject = pProject;}
+    // Set or return Parser that changed "Global setting" in Single File workspace
+    ParserBase* GetTempParser(){return m_TempParser;}
+    ParserBase* GetOptsChangedByParser(){ return m_pOptsChangedParser;}
+    void SetOptsChangedByParser(ParserBase* pParserBase){m_pOptsChangedParser = &(GetParser());}
+
 protected:
     /** When a Parser is created, we need a full parsing stage including:
      * 1, parse the priority header files firstly.
@@ -474,11 +482,12 @@
      */
     bool RemoveProjectFromParser(cbProject* project);
 
+
 private:
     typedef std::pair<cbProject*, ParserBase*> ProjectParserPair;
     typedef std::list<ProjectParserPair>       ParserList;
 
-    /** a list holing all the cbp->parser pairs, if in one parser per project mode, there are many
+    /** a list holding all the cbp->parser pairs, if in one parser per project mode, there are many
      * many pairs in this list. In one parser per workspace mode, there is only one pair, and the
      * m_ParserList.begin()->second is the common parser for all the projects in workspace.
      */
@@ -527,6 +536,11 @@
     bool m_ClassBrowserViewIsStale = true;
     bool m_SymbolsWindowHasFocus = false;
 
+    //The latest project to change the .conf file //(ph 2025/02/04)
+    cbProject* m_pOptsChangedProject = nullptr;
+    //The latest parser to change the .conf file //(ph 2025/02/04)
+    ParserBase* m_pOptsChangedParser = nullptr;
+
 };
 
 #endif // PARSEMANAGER_H
Index: parser/parser.cpp
===================================================================
--- parser/parser.cpp (revision 13610)
+++ parser/parser.cpp (working copy)
@@ -32,9 +32,10 @@
 
 #include "parser.h"
 #include "parserthreadedtask.h"
+#include "../parsemanager.h" //(ph 2025/02/04)
 
 #include "../classbrowser.h"
-#include "../classbrowserbuilderthread.h"
+//unused - #include "../classbrowserbuilderthread.h"
 
 
 #ifndef CB_PRECOMP
@@ -921,19 +922,59 @@
 
 void Parser::WriteOptions()
 {
+     //(ph 2025/02/06)
+    // Assemble status to determine if a Parser or Project changed a global setting.
+    ProjectManager* pPrjMgr = Manager::Get()->GetProjectManager();
+    cbProject*      pActiveProject = pPrjMgr->GetActiveProject();
+    ParseManager*   pParseMgr = (ParseManager*)m_Parent;
+    ParserBase*     pParser = &(pParseMgr->GetParser());
+    ParserBase*     pTempParser = pParseMgr->GetTempParser();
+    cbProject*      pOptsChangerProject = pParseMgr->GetOptsChangedByProject();
+
+    int  projectsCount = pPrjMgr->GetProjects()->size();
+    bool isTempParser  = (pParser == pTempParser);
+    bool globalOptionChanged = pParseMgr->GetOptsChangedByParser() or pParseMgr->GetOptsChangedByProject();
+
     ConfigManager* cfg = Manager::Get()->GetConfigManager(_T("code_completion"));
 
-    // Page "Code Completion"
-    cfg->Write(_T("/use_SmartSense"),                m_Options.useSmartSense);
-    cfg->Write(_T("/while_typing"),                  m_Options.whileTyping);
+    // **Debugging** use this global to verify logic
+    // bool parseWhileTypingStatus = m_Options.whileTyping;
 
-    // Page "C / C++ parser"
-    cfg->Write(_T("/parser_follow_local_includes"),  m_Options.followLocalIncludes);
-    cfg->Write(_T("/parser_follow_global_includes"), m_Options.followGlobalIncludes);
-    cfg->Write(_T("/want_preprocessor"),             m_Options.wantPreprocessor);
-    cfg->Write(_T("/parse_complex_macros"),          m_Options.parseComplexMacros);
-    cfg->Write(_T("/platform_check"),                m_Options.platformCheck);
+    // Do not allow stale parser settings to change the global settings
+    bool allowGlobalUpdate = false;
+    if ( (projectsCount == 0) and globalOptionChanged)
+        allowGlobalUpdate = true;   //Single file settings changes
+    if (projectsCount and (pOptsChangerProject == pActiveProject) )
+        allowGlobalUpdate = true;   // changes made by a project
+    if ( (projectsCount==0) and isTempParser and globalOptionChanged)
+        allowGlobalUpdate = false; // TempParser has stale settings on Close()
+    if (not globalOptionChanged)
+        allowGlobalUpdate = false; // no global settings have changed
 
+    if (allowGlobalUpdate)
+    {
+        // Page "Code Completion"
+        cfg->Write(_T("/use_SmartSense"),                m_Options.useSmartSense);
+        cfg->Write(_T("/while_typing"),                  m_Options.whileTyping);
+
+        // Page "C / C++ parser"
+        cfg->Write(_T("/parser_follow_local_includes"),  m_Options.followLocalIncludes);
+        cfg->Write(_T("/parser_follow_global_includes"), m_Options.followGlobalIncludes);
+        cfg->Write(_T("/want_preprocessor"),             m_Options.wantPreprocessor);
+        cfg->Write(_T("/parse_complex_macros"),          m_Options.parseComplexMacros);
+        cfg->Write(_T("/platform_check"),                m_Options.platformCheck);
+    }
+    if ((projectsCount == 0) and isTempParser and globalOptionChanged)
+    {
+        // When no projects exists but the CB main settings have been changed,
+        // force the TempParser to reread settings/options else stale ones
+        // will be displayed on the next use of MenuBar/Settings/Editor/CodeCompletion dialog
+        ReadOptions();
+        // The global settings changed status can now be reset
+        pParseMgr->SetOptsChangedByParser(nullptr);
+        pParseMgr->SetOptsChangedByProject(nullptr);
+    }
+
     // Page "Symbol browser"
     cfg->Write(_T("/browser_show_inheritance"),      m_BrowserOptions.showInheritance);
     cfg->Write(_T("/browser_expand_ns"),             m_BrowserOptions.expandNS);
Index: resources/manifest.xml
===================================================================
--- resources/manifest.xml (revision 13610)
+++ resources/manifest.xml (working copy)
@@ -3,7 +3,7 @@
     <SdkVersion major="1" minor="10" release="0" />
     <Plugin name="CodeCompletion">
         <Value title="Code completion" />
-        <Value version="1.0.5 24/01/29" />
+        <Value version="1.0.6 25/02/7" />
         <Value description="This plugin provides a symbols browser for your projects and code-completion inside the editor.
 
 


--- End code ---

Navigation

[0] Message Index

[#] Next page

[*] Previous page

Go to full version