From 3900be8c68c7dcd7358e6f342af00a6b91b7a132 Mon Sep 17 00:00:00 2001 From: Rainer Kottenhoff Date: Thu, 5 Apr 2018 18:36:50 +0200 Subject: [PATCH] + opt: optimization of delayed "mark occurrences" multi-triggering --- src/Edit.c | 81 ++++++++++++++++++++++++++--------------------- src/Notepad3.c | 85 +++++++++++++++++++++++++++++++++----------------- src/resource.h | 38 +++++++++++----------- 3 files changed, 119 insertions(+), 85 deletions(-) diff --git a/src/Edit.c b/src/Edit.c index bcfca5c5c..152440314 100644 --- a/src/Edit.c +++ b/src/Edit.c @@ -163,10 +163,12 @@ extern bool bMarkOccurrencesMatchWords; // Timer bitfield static volatile LONG g_lTargetTransactionBits = 0; -#define TIMER_BIT_MARK_OCC 1L -#define BLOCK_BIT_TARGET_TRANSACTION 2L -#define TEST_AND_SET(B) InterlockedBitTestAndSet(&g_lTargetTransactionBits, B) -#define TEST_AND_RESET(B) InterlockedBitTestAndReset(&g_lTargetTransactionBits, B) +#define BIT_TIMER_MARK_OCC 1L +#define BIT_MARK_OCC_IN_PROGRESS 2L +#define BLOCK_BIT_TARGET_TRANSACTION 4L + +#define TEST_AND_SET(BIT) InterlockedBitTestAndSet(&g_lTargetTransactionBits, BIT) +#define TEST_AND_RESET(BIT) InterlockedBitTestAndReset(&g_lTargetTransactionBits, BIT) //============================================================================= @@ -4739,14 +4741,19 @@ static RegExResult_t __fastcall _FindHasMatch(HWND hwnd, LPCEDITFINDREPLACE lpef // static void __fastcall _SetTimerMarkAll(HWND hwnd, int delay) { + if (TEST_AND_RESET(BIT_TIMER_MARK_OCC)) { + TEST_AND_SET(BIT_TIMER_MARK_OCC); // in progress + return; + } + + TEST_AND_SET(BIT_TIMER_MARK_OCC); // raise flag to swollow next calls + if (delay < USER_TIMER_MINIMUM) { - TEST_AND_RESET(TIMER_BIT_MARK_OCC); - KillTimer(hwnd, IDT_TIMER_MRKALL); - SendMessage(hwnd, WM_COMMAND, MAKELONG(IDC_MARKALL_OCC, 1), 0); - return; + SendMessage(hwnd, WM_TIMER, MAKELONG(IDT_TIMER_MRKALL, 1), 0); // direct timer event + } + else { + SetTimer(hwnd, IDT_TIMER_MRKALL, delay, NULL); } - TEST_AND_SET(TIMER_BIT_MARK_OCC); - SetTimer(hwnd, IDT_TIMER_MRKALL, delay, NULL); } @@ -4963,12 +4970,33 @@ INT_PTR CALLBACK EditFindReplaceDlgProcW(HWND hwnd,UINT umsg,WPARAM wParam,LPARA case WM_TIMER: { + // The KillTimer function does not remove WM_TIMER messages already posted to the message queue. if (LOWORD(wParam) == IDT_TIMER_MRKALL) { - if (TEST_AND_RESET(TIMER_BIT_MARK_OCC)) { - KillTimer(hwnd, IDT_TIMER_MRKALL); - PostMessage(hwnd, WM_COMMAND, MAKELONG(IDC_MARKALL_OCC, 1), 0); + KillTimer(hwnd, IDT_TIMER_MRKALL); + if (!TEST_AND_RESET(BIT_MARK_OCC_IN_PROGRESS)) // stay in progress + { + TEST_AND_SET(BIT_MARK_OCC_IN_PROGRESS); // start progress + iMarkOccurrencesCount = 0; + _SetSearchFlags(hwnd, lpefr); + if (lpefr->bMarkOccurences) { + if (bFlagsChanged || (StringCchCompareXA(g_lastFind, lpefr->szFind) != 0)) { + StringCchCopyA(g_lastFind, COUNTOF(g_lastFind), lpefr->szFind); + RegExResult_t match = _FindHasMatch(g_hwndEdit, lpefr, (lpefr->bMarkOccurences), false); + if (regexMatch != match) { + regexMatch = match; + } + // we have to set Sci's regex instance to first find (have substitution in place) + _FindHasMatch(g_hwndEdit, lpefr, false, true); + bFlagsChanged = false; + InvalidateRect(GetDlgItem(hwnd, IDC_FINDTEXT), NULL, true); + UpdateToolbar(); + UpdateStatusbar(); + } + } + TEST_AND_RESET(BIT_MARK_OCC_IN_PROGRESS); // done } + TEST_AND_RESET(BIT_TIMER_MARK_OCC); // ready for new events return true; } } @@ -5112,29 +5140,6 @@ INT_PTR CALLBACK EditFindReplaceDlgProcW(HWND hwnd,UINT umsg,WPARAM wParam,LPARA } break; - // called on timer trigger - case IDC_MARKALL_OCC: - { - iMarkOccurrencesCount = 0; - _SetSearchFlags(hwnd, lpefr); - if (lpefr->bMarkOccurences) { - if (bFlagsChanged || (StringCchCompareXA(g_lastFind, lpefr->szFind) != 0)) { - StringCchCopyA(g_lastFind, COUNTOF(g_lastFind), lpefr->szFind); - RegExResult_t match = _FindHasMatch(g_hwndEdit, lpefr, (lpefr->bMarkOccurences), false); - if (regexMatch != match) { - regexMatch = match; - } - // we have to set Sci's regex instance to first find (have substitution in place) - _FindHasMatch(g_hwndEdit, lpefr, false, true); - bFlagsChanged = false; - InvalidateRect(GetDlgItem(hwnd, IDC_FINDTEXT), NULL, true); - UpdateToolbar(); - UpdateStatusbar(); - } - } - } - break; - case IDC_FINDREGEXP: if (IsDlgButtonChecked(hwnd, IDC_FINDREGEXP) == BST_CHECKED) @@ -5727,6 +5732,7 @@ void EditMarkAllOccurrences() if (EditIsInTargetTransaction()) { return; } // do not block, next event occurs for sure + BeginWaitCursor(NULL); IgnoreNotifyChangeEvent(); EditEnterTargetTransaction(); @@ -5751,6 +5757,7 @@ void EditMarkAllOccurrences() } EditLeaveTargetTransaction(); ObserveNotifyChangeEvent(); + EndWaitCursor(); } else { @@ -5769,6 +5776,7 @@ void EditUpdateVisibleUrlHotspot(bool bEnabled) { if (EditIsInTargetTransaction()) { return; } // do not block, next event occurs for sure + BeginWaitCursor(NULL); EditEnterTargetTransaction(); // get visible lines for update @@ -5783,6 +5791,7 @@ void EditUpdateVisibleUrlHotspot(bool bEnabled) EditUpdateUrlHotspots(g_hwndEdit, iPosStart, iPosEnd, bEnabled); EditLeaveTargetTransaction(); + EndWaitCursor(); } } diff --git a/src/Notepad3.c b/src/Notepad3.c index 3a13f3823..558a4116e 100644 --- a/src/Notepad3.c +++ b/src/Notepad3.c @@ -342,9 +342,14 @@ static DWORD DropFilesProc(CLIPFORMAT cf, HGLOBAL hData, HWND hWnd, DWORD dwKeyS // Timer bitfield static volatile LONG g_lInterlockBits = 0; -#define TIMER_BIT_MARK_OCC 1L -#define TIMER_BIT_UPDATE_HYPER 2L -#define LOCK_NOTIFY_CHANGE 4L +#define BIT_TIMER_MARK_OCC 1L +#define BIT_MARK_OCC_IN_PROGRESS 2L + +#define BIT_TIMER_UPDATE_HYPER 4L +#define BIT_UPDATE_HYPER_IN_PROGRESS 8L + +#define LOCK_NOTIFY_CHANGE 16L + #define TEST_AND_SET(B) InterlockedBitTestAndSet(&g_lInterlockBits, B) #define TEST_AND_RESET(B) InterlockedBitTestAndReset(&g_lInterlockBits, B) @@ -1071,23 +1076,38 @@ LRESULT CALLBACK MainWndProc(HWND hwnd,UINT umsg,WPARAM wParam,LPARAM lParam) UpdateVisibleUrlHotspot(0); return DefWindowProc(hwnd,umsg,wParam,lParam); + case WM_TIMER: - if (LOWORD(wParam) == IDT_TIMER_MAIN_MRKALL) { - if (TEST_AND_RESET(TIMER_BIT_MARK_OCC)) { + { + // The KillTimer function does not remove WM_TIMER messages already posted to the message queue. + if (LOWORD(wParam) == IDT_TIMER_MAIN_MRKALL) + { KillTimer(hwnd, IDT_TIMER_MAIN_MRKALL); - PostMessage(hwnd, WM_COMMAND, MAKELONG(IDC_MAIN_MARKALL_OCC, 1), 0); + if (!TEST_AND_RESET(BIT_MARK_OCC_IN_PROGRESS)) // stay in progress + { + TEST_AND_SET(BIT_MARK_OCC_IN_PROGRESS); // start progress + EditMarkAllOccurrences(); + TEST_AND_RESET(BIT_MARK_OCC_IN_PROGRESS); // done + } + TEST_AND_RESET(BIT_TIMER_MARK_OCC); // ready for new events + return true; } - return true; - } - else if (LOWORD(wParam) == IDT_TIMER_UPDATE_HOTSPOT) { - if (TEST_AND_RESET(TIMER_BIT_UPDATE_HYPER)) { + else if (LOWORD(wParam) == IDT_TIMER_UPDATE_HOTSPOT) + { KillTimer(hwnd, IDT_TIMER_UPDATE_HOTSPOT); - PostMessage(hwnd, WM_COMMAND, MAKELONG(IDC_CALL_UPDATE_HOTSPOT, 1), 0); + if (!TEST_AND_RESET(BIT_UPDATE_HYPER_IN_PROGRESS)) // stay in progress + { + TEST_AND_SET(BIT_UPDATE_HYPER_IN_PROGRESS); // start progress + EditUpdateVisibleUrlHotspot(bHyperlinkHotspot); + TEST_AND_RESET(BIT_UPDATE_HYPER_IN_PROGRESS); // done + } + TEST_AND_RESET(BIT_TIMER_UPDATE_HYPER); // ready for new events + return true; } - return true; } break; + case WM_SIZE: MsgSize(hwnd,wParam,lParam); break; @@ -2552,14 +2572,6 @@ LRESULT MsgCommand(HWND hwnd, WPARAM wParam, LPARAM lParam) { switch(LOWORD(wParam)) { - case IDC_MAIN_MARKALL_OCC: - EditMarkAllOccurrences(); - break; - - case IDC_CALL_UPDATE_HOTSPOT: - EditUpdateVisibleUrlHotspot(bHyperlinkHotspot); - break; - case IDM_FILE_NEW: FileLoad(false,true,false,bSkipUnicodeDetection,bSkipANSICodePageDetection,L""); break; @@ -5465,7 +5477,7 @@ LRESULT MsgNotify(HWND hwnd,WPARAM wParam,LPARAM lParam) } else if (scn->updated & SC_UPDATE_V_SCROLL) { - if (iMarkOccurrences > 0) { + if ((iMarkOccurrences > 0) && bMarkOccurrencesMatchVisible) { MarkAllOccurrences(iUpdateDelayMarkAllCoccurrences); } if (bHyperlinkHotspot) { @@ -7052,26 +7064,41 @@ int CreateIniFileEx(LPCWSTR lpszIniFile) { // void MarkAllOccurrences(int delay) { - if (delay < USER_TIMER_MINIMUM) { - EditMarkAllOccurrences(); + if (TEST_AND_RESET(BIT_TIMER_MARK_OCC)) { + TEST_AND_SET(BIT_TIMER_MARK_OCC); // in progress return; } - TEST_AND_SET(TIMER_BIT_MARK_OCC); - SetTimer(g_hwndMain, IDT_TIMER_MAIN_MRKALL, delay, NULL); + + TEST_AND_SET(BIT_TIMER_MARK_OCC); // raise flag to swollow next calls + + if (delay < USER_TIMER_MINIMUM) { + SendMessage(g_hwndMain, WM_TIMER, MAKELONG(IDT_TIMER_MAIN_MRKALL, 1), 0); // direct timer event + } + else { + SetTimer(g_hwndMain, IDT_TIMER_MAIN_MRKALL, delay, NULL); + } } + //============================================================================= // // UpdateVisibleUrlHotspot() // void UpdateVisibleUrlHotspot(int delay) { - if (delay < USER_TIMER_MINIMUM) { - EditUpdateVisibleUrlHotspot(bHyperlinkHotspot); + if (TEST_AND_RESET(BIT_TIMER_UPDATE_HYPER)) { + TEST_AND_SET(BIT_TIMER_UPDATE_HYPER); // in progress return; } - TEST_AND_SET(TIMER_BIT_UPDATE_HYPER); - SetTimer(g_hwndMain, IDT_TIMER_UPDATE_HOTSPOT, delay, NULL); + + TEST_AND_SET(BIT_TIMER_UPDATE_HYPER); // raise flag to swollow next calls + + if (delay < USER_TIMER_MINIMUM) { + SendMessage(g_hwndMain, WM_TIMER, MAKELONG(IDT_TIMER_UPDATE_HOTSPOT, 1), 0); // direct timer event + } + else { + SetTimer(g_hwndMain, IDT_TIMER_UPDATE_HOTSPOT, delay, NULL); + } } diff --git a/src/resource.h b/src/resource.h index 9138fb8f4..7323f69a5 100644 --- a/src/resource.h +++ b/src/resource.h @@ -118,26 +118,24 @@ #define IDD_INFOBOX3 214 #define IDT_TIMER_MRKALL 215 #define IDC_ALL_OCCURRENCES 216 -#define IDC_MARKALL_OCC 217 -#define IDC_DOT_MATCH_ALL 218 -#define IDT_TIMER_MAIN_MRKALL 219 -#define IDC_MAIN_MARKALL_OCC 220 -#define IDT_TIMER_UPDATE_HOTSPOT 221 -#define IDC_CALL_UPDATE_HOTSPOT 222 -#define IDC_BACKSLASHHELP 223 -#define IDC_REGEXPHELP 224 -#define IDC_WILDCARDHELP 225 -#define IDC_WILDCARDSEARCH 226 -#define IDC_SCI_VERSION 227 -#define IDR_MAINWNDTB 228 -#define IDC_REMOVE 229 -#define IDC_SWAPSTRG 230 -#define IDC_CHECK_OCC 231 -#define IDC_PRINTER 232 -#define IDC_USEASREADINGFALLBACK 233 -#define IDR_ACCCUSTOMSCHEMES 234 -#define IDC_NOANSICPDETECTION 235 -#define IDC_REMEMBERSEARCHPATTERN 236 +#define IDC_DOT_MATCH_ALL 217 +#define IDT_TIMER_MAIN_MRKALL 218 +#define IDT_TIMER_UPDATE_HOTSPOT 219 +#define IDC_BACKSLASHHELP 220 +#define IDC_REGEXPHELP 221 +#define IDC_WILDCARDHELP 222 +#define IDC_WILDCARDSEARCH 223 +#define IDC_SCI_VERSION 224 +#define IDR_MAINWNDTB 225 +#define IDC_REMOVE 226 +#define IDC_SWAPSTRG 227 +#define IDC_CHECK_OCC 228 +#define IDC_PRINTER 229 +#define IDC_USEASREADINGFALLBACK 230 +#define IDR_ACCCUSTOMSCHEMES 231 +#define IDC_NOANSICPDETECTION 232 +#define IDC_REMEMBERSEARCHPATTERN 233 +#define IDC_TOGGLE_VISIBILITY 234 #define IDACC_FIND 302 #define IDACC_REPLACE 303 #define IDACC_SAVEPOS 304