When loading a project, I see a lot of wxEVT_SCI_MODIFIED and wxEVT_SCI_CHANGE messages. (You can enable the TRACE of codecompletion.cpp to see them)
I just track down, and I see that: UpdateEditorSyntax(editor); (mostly in CodeCompletion::OnParserEnd()) will cause such message.
Can we avoid them? It's annoying.
Quote from: ollydbg on July 18, 2013, 05:14:50 PM
Can we avoid them? It's annoying.
I think not really. It iterates (only!) across the open editors to update the syntax highlighting. If you skip the call to
UpdateEditorSyntax() or avoid the event the editors won'T be highlighted correctly. IIRC this is needed for the macro and keyword stuff.
The only thing is not to have too many editors open... :-)
It looks like
void SCI_METHOD LexerCPP::Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
call
void SetLevel(int line, int level) {
pAccess->SetLevel(line, level);
}
in a loop, so a lot of wxEVT_SCI_MODIFIED was sent. :(
Quote from: MortenMacFly on July 18, 2013, 05:28:06 PM
Quote from: ollydbg on July 18, 2013, 05:14:50 PM
Can we avoid them? It's annoying.
I think not really. It iterates (only!) across the open editors to update the syntax highlighting. If you skip the call to UpdateEditorSyntax() or avoid the event the editors won'T be highlighted correctly. IIRC this is needed for the macro and keyword stuff.
The only thing is not to have too many editors open... :-)
I have just post an analysis result, and found the source of such annoying message. (even only one editor is opened, there are still many messages sent).
I track down the source, and I see that the flood of wxEVT_SCI_MODIFIED of messages happen at two time.
1, when loading project files
cbEditor* EditorManager::Open(LoaderBase* fileLdr, const wxString& filename, int /*pos*/, ProjectFile* data)
Each line will be set a new level, and those messages will be sent for each lines
int SCI_METHOD Document::SetLevel(int line, int level) {
int prev = static_cast<LineLevels *>(perLineData[ldLevels])->SetLevel(line, level, LinesTotal());
if (prev != level) {
DocModification mh(SC_MOD_CHANGEFOLD | SC_MOD_CHANGEMARKER,
LineStart(line), 0, 0, 0, line);
mh.foldLevelNow = level;
mh.foldLevelPrev = prev;
NotifyModified(mh);
}
return prev;
}
2, when parser done, in void CodeCompletion::OnParserEnd(wxCommandEvent& event)
The call statement
UpdateEditorSyntax(editor);
Some code style will change, so there is also some messages of wxEVT_SCI_MODIFIED.
Ok, I got the correct answer from Scintilla's mail-list, see:
https://groups.google.com/d/msg/scintilla-interest/9Vt8FJFL3CU/aOjLveFw4oAJ
It is by design, but we can filter them(I don't think it is necessary), so leave it as it is. :)
Quote from: ollydbg on July 21, 2013, 05:54:48 PM
It is by design, but we can filter them(I don't think it is necessary), so leave it as it is. :)
Could filtering possibly result in a (small) performance gain?
Quote from: Alpha on July 21, 2013, 06:13:36 PM
Quote from: ollydbg on July 21, 2013, 05:54:48 PM
It is by design, but we can filter them(I don't think it is necessary), so leave it as it is. :)
Could filtering possibly result in a (small) performance gain?
I don't know, maybe we can temporary disable send such message when an editor is created and a file is loaded. To measure performance, there need at least a benchmark test.
I still see many unwanted event sent, so I did some further debugging.
I found that C::B did try to disable the notifications when an editor was initialized, see the code
bool cbEditor::Open(bool detectEncoding)
{
if (m_pProjectFile)
{
if (!wxFileExists(m_Filename))
m_pProjectFile->SetFileState(fvsMissing);
else if (!wxFile::Access(m_Filename.c_str(), wxFile::write)) // readonly
m_pProjectFile->SetFileState(fvsReadOnly);
}
if (!wxFileExists(m_Filename))
return false;
// open file
m_pControl->SetReadOnly(false);
m_pControl->ClearAll();
m_pControl->SetModEventMask(0);
if (!m_pData)
return false;
if (!m_pData->m_pFileLoader)
m_pData->m_pFileLoader = Manager::Get()->GetFileManager()->Load(m_Filename, false);
#ifdef fileload_measuring
wxStopWatch sw;
#endif
EncodingDetector enc((wxByte*)m_pData->m_pFileLoader->GetData(), m_pData->m_pFileLoader->GetLength());
if (detectEncoding)
{
m_pData->m_useByteOrderMark = enc.UsesBOM();
m_pData->m_byteOrderMarkLength = enc.GetBOMSizeInBytes();
m_pData->m_encoding = enc.GetFontEncoding();
SetEncoding(enc.GetFontEncoding());
SetUseBom(m_pData->m_byteOrderMarkLength > 0);
}
ConfigManager* mgr = Manager::Get()->GetConfigManager(_T("editor"));
#ifdef fileload_measuring
Manager::Get()->GetLogManager()->DebugLog(F(_T("cbEditor::Open() => Encoding detection and conversion took : %d ms"),(int)sw.Time()));
sw.Start();
#endif
m_pControl->InsertText(0, enc.GetWxStr());
m_pControl->EmptyUndoBuffer(mgr->ReadBool(_T("/margin/use_changebar"), true));
m_pControl->SetModEventMask(wxSCI_MODEVENTMASKALL);
...
...
It first SetModEventMask to 0 (which disable all the modify notifications), and after loading, it set its value to wxSCI_MODEVENTMASKALL, this looks OK.
But I find that when the first time an OnPaint event is received, it did the following
[debug]> bt 30
[debug]#0 LexAccessor::SetLevel (this=0x22ced4, line=20, level=67109888) at F:\cb_sf_git\trunk\src\sdk\wxscintilla\src\scintilla\lexlib\LexAccessor.h:202
[debug]#1 0x011b722a in LexerCPP::Fold(unsigned int, int, int, IDocument*)@20 (this=0x1a2e54a8, startPos=0, length=6655, initStyle=0, pAccess=0x1a30bb04) at F:\cb_sf_git\trunk\src\sdk\wxscintilla\src\scintilla\lexers\LexCPP.cxx:1217
[debug]#2 0x01243d40 in LexInterface::Colourise (this=0x1a2b27e8, start=0, end=6655) at F:\cb_sf_git\trunk\src\sdk\wxscintilla\src\scintilla\src\Document.cxx:65
[debug]#3 0x0124a527 in Document::EnsureStyledTo (this=0x1a30bb00, pos=6655) at F:\cb_sf_git\trunk\src\sdk\wxscintilla\src\scintilla\src\Document.cxx:1812
[debug]#4 0x01235de2 in Editor::StyleToPositionInView (this=0x1a2fbfb8, pos=6655) at F:\cb_sf_git\trunk\src\sdk\wxscintilla\src\scintilla\src\Editor.cxx:6833
[debug]#5 0x0122514d in Editor::Paint (this=0x1a2fbfb8, surfaceWindow=0x1a1979e8, rcArea=...) at F:\cb_sf_git\trunk\src\sdk\wxscintilla\src\scintilla\src\Editor.cxx:3515
[debug]#6 0x01195377 in ScintillaWX::DoPaint (this=0x1a2fbfb8, dc=0x22f1b0, rect=(0, 0) 968*215) at F:\cb_sf_git\trunk\src\sdk\wxscintilla\src\ScintillaWX.cpp:924
[debug]#7 0x011901a0 in wxScintilla::OnPaint (this=0x1a196900) at F:\cb_sf_git\trunk\src\sdk\wxscintilla\src\wxscintilla.cpp:5211
[debug]#8 0x04c11b0e in wxAppConsole::HandleEvent (this=0x10a24ba8, handler=0x1a196900, func=(void (wxEvtHandler::*)(wxEvtHandler * const, wxEvent &)) 0x119011e <wxScintilla::OnPaint(wxPaintEvent&)>, 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=0x1a196900, 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=0x1518800 <cbStyledTextCtrl::sm_eventHashTable>, event=..., self=0x1a196900) at E:\code\wx-mingw-build-481-dw2\wxWidgets-2.8.12\src\common\event.cpp:906
[debug]#11 0x04c9293a in wxEvtHandler::ProcessEvent (this=0x1a196900, event=...) at E:\code\wx-mingw-build-481-dw2\wxWidgets-2.8.12\src\common\event.cpp:1301
[debug]#12 0x04cdbc20 in wxWindow::HandlePaint (this=0x1a196900) at E:\code\wx-mingw-build-481-dw2\wxWidgets-2.8.12\src\msw\window.cpp:4617
[debug]#13 0x04cd8830 in wxWindow::MSWWindowProc (this=0x1a196900, message=15, wParam=0, lParam=0) at E:\code\wx-mingw-build-481-dw2\wxWidgets-2.8.12\src\msw\window.cpp:2747
[debug]#14 0x04cd8109 in wxWndProc(HWND__*, unsigned int, unsigned int, long)@16 (hWnd=0x709c8, message=15, wParam=0, lParam=0) at E:\code\wx-mingw-build-481-dw2\wxWidgets-2.8.12\src\msw\window.cpp:2618
[debug]#15 0x7e418734 in USER32!GetDC () from C:\WINDOWS\system32\user32.dll
[debug]#16 0x000709c8 in ?? ()
[debug]#17 0x0000000f in ?? ()
[debug]#18 0x00000000 in ?? ()
[debug]>>>>>>cb_gdb:
This try to set the style for each line (when SetLevel() function is called). So, for a large file which contains many lines, C::B will send many wxEVT_SCI_CHANGE events.
Do we need to allow sending all such events? I don't think so.
Hint:
I just found the Codelite's editor filter some events, see:
https://github.com/eranif/codelite/blob/master/LiteEditor/cl_editor.cpp
line 355.
SetModEventMask (wxSTC_MOD_DELETETEXT | wxSTC_MOD_INSERTTEXT | wxSTC_PERFORMED_UNDO | wxSTC_PERFORMED_REDO | wxSTC_MOD_BEFOREDELETE | wxSTC_MOD_CHANGESTYLE);
EDIT:
Below is the backtrace of another source of events. (caused by CodeCompletion::UpdateEditorSyntax())
[debug]> bt 30
[debug]#0 LexAccessor::SetLevel (this=0x22d61c, line=192, level=67175425) at F:\cb_sf_git\trunk\src\sdk\wxscintilla\src\scintilla\lexlib\LexAccessor.h:202
[debug]#1 0x011b722a in LexerCPP::Fold(unsigned int, int, int, IDocument*)@20 (this=0x1a2a90d8, startPos=0, length=81090, initStyle=0, pAccess=0x1a3048bc) at F:\cb_sf_git\trunk\src\sdk\wxscintilla\src\scintilla\lexers\LexCPP.cxx:1217
[debug]#2 0x01243d40 in LexInterface::Colourise (this=0x1a30bf48, start=0, end=81090) at F:\cb_sf_git\trunk\src\sdk\wxscintilla\src\scintilla\src\Document.cxx:65
[debug]#3 0x0124380a in ScintillaBase::WndProc (this=0x1a30a218, iMessage=4003, wParam=0, lParam=-1) at F:\cb_sf_git\trunk\src\sdk\wxscintilla\src\scintilla\src\ScintillaBase.cxx:948
[debug]#4 0x011951aa in ScintillaWX::WndProc (this=0x1a30a218, iMessage=4003, wParam=0, lParam=-1) at F:\cb_sf_git\trunk\src\sdk\wxscintilla\src\ScintillaWX.cpp:898
[debug]#5 0x01184aa9 in wxScintilla::SendMsg (this=0x1a24c918, msg=4003, wp=0, lp=-1) at F:\cb_sf_git\trunk\src\sdk\wxscintilla\src\wxscintilla.cpp:271
[debug]#6 0x0118df1a in wxScintilla::Colourise (this=0x1a24c918, start=0, end=-1) at F:\cb_sf_git\trunk\src\sdk\wxscintilla\src\wxscintilla.cpp:4399
[debug]#7 0x70064b20 in CodeCompletion::UpdateEditorSyntax (this=0x1245dd78, ed=0x1a24cd38) at F:\cb_sf_git\trunk\src\plugins\codecompletion\codecompletion.cpp:3320
[debug]#8 0x700658d8 in CodeCompletion::OnEditorActivatedTimer (this=0x1245dd78, event=...) at F:\cb_sf_git\trunk\src\plugins\codecompletion\codecompletion.cpp:3495
[debug]#9 0x04c11b0e in wxAppConsole::HandleEvent (this=0x10a24ba8, handler=0x1245dd78, func=(void (wxEvtHandler::*)(wxEvtHandler * const, wxEvent &)) 0x70065638 <CodeCompletion::OnEditorActivatedTimer(wxTimerEvent&)>, event=...) at E:\code\wx-mingw-build-481-dw2\wxWidgets-2.8.12\src\common\appbase.cpp:322
[debug]#10 0x04c9273d in wxEvtHandler::ProcessEventIfMatches (entry=..., handler=0x1245dd78, event=...) at E:\code\wx-mingw-build-481-dw2\wxWidgets-2.8.12\src\common\event.cpp:1239
[debug]#11 0x04c92d91 in wxEvtHandler::SearchDynamicEventTable (this=0x1245dd78, event=...) at E:\code\wx-mingw-build-481-dw2\wxWidgets-2.8.12\src\common\event.cpp:1421
[debug]#12 0x04c928f4 in wxEvtHandler::ProcessEvent (this=0x1245dd78, event=...) at E:\code\wx-mingw-build-481-dw2\wxWidgets-2.8.12\src\common\event.cpp:1297
[debug]#13 0x04d911e2 in wxTimerBase::Notify (this=0x1245dff8) at E:\code\wx-mingw-build-481-dw2\wxWidgets-2.8.12\src\common\timercmn.cpp:57
[debug]#14 0x04ccedcb in wxProcessTimer (timer=...) at E:\code\wx-mingw-build-481-dw2\wxWidgets-2.8.12\src\msw\timer.cpp:187
[debug]#15 0x04ccee72 in wxTimerWndProc(HWND__*, unsigned int, unsigned int, long)@16 (hWnd=0x50884, message=275, wParam=11, lParam=0) at E:\code\wx-mingw-build-481-dw2\wxWidgets-2.8.12\src\msw\timer.cpp:200
[debug]#16 0x7e418734 in USER32!GetDC () from C:\WINDOWS\system32\user32.dll
[debug]#17 0x00050884 in ?? ()
[debug]#18 0x00000113 in ?? ()
[debug]#19 0x0000000b in ?? ()
[debug]#20 0x00000000 in ?? ()
[debug]>>>>>>cb_gdb: