+rfc: refactoring of undo/redo and document modify handler

This commit is contained in:
METANEOCORTEX\Kotti 2022-10-29 03:54:59 +02:00
parent fbdd90530f
commit 238111dcd2
4 changed files with 64 additions and 113 deletions

View File

@ -417,7 +417,7 @@ void EditSetNewText(HWND hwnd, const char* lpstrText, DocPosU lenText, bool bCle
UndoRedoReset();
}
//DocChangeTransactionBegin();
//UndoTransActionBegin();
SciCall_Cancel();
if (SciCall_GetReadOnly()) {
@ -434,7 +434,7 @@ void EditSetNewText(HWND hwnd, const char* lpstrText, DocPosU lenText, bool bCle
Sci_GotoPosChooseCaret(0);
//EndDocChangeTransaction();
//EndUndoTransAction();
s_bFreezeAppTitle = false;
}
@ -3346,7 +3346,7 @@ void EditIndentBlock(HWND hwnd, int cmd, bool bFormatIndentation, bool bForceAll
return;
}
DocChangeTransactionBegin()
UndoTransActionBegin()
if (bForceAll) {
SciCall_SelectAll();
@ -3417,7 +3417,7 @@ void EditIndentBlock(HWND hwnd, int cmd, bool bFormatIndentation, bool bForceAll
Sci_ScrollChooseCaret();
}
EndDocChangeTransaction();
EndUndoTransAction();
}
@ -4122,7 +4122,7 @@ void EditStripFirstCharacter(HWND hwnd)
DocLn const iLineStart = SciCall_LineFromPosition(iSelStart);
DocLn const iLineEnd = SciCall_LineFromPosition(iSelEnd);
DocChangeTransactionBegin();
UndoTransActionBegin();
if (SciCall_IsSelectionRectangle()) {
const DocPos selAnchorMainPos = SciCall_GetRectangularSelectionAnchor();
@ -4176,7 +4176,7 @@ void EditStripFirstCharacter(HWND hwnd)
}
}
EndDocChangeTransaction();
EndUndoTransAction();
}
@ -4197,7 +4197,7 @@ void EditStripLastCharacter(HWND hwnd, bool bIgnoreSelection, bool bTrailingBlan
DocLn const iLineStart = SciCall_LineFromPosition(iSelStart);
DocLn const iLineEnd = SciCall_LineFromPosition(iSelEnd);
DocChangeTransactionBegin();
UndoTransActionBegin();
if (Sci_IsMultiOrRectangleSelection() && !bIgnoreSelection) {
if (SciCall_IsSelectionEmpty()) {
@ -4290,7 +4290,7 @@ void EditStripLastCharacter(HWND hwnd, bool bIgnoreSelection, bool bTrailingBlan
}
}
EndDocChangeTransaction();
EndUndoTransAction();
}
@ -4319,7 +4319,7 @@ void EditCompressBlanks()
const DocPos vSpcAnchorMainPos = SciCall_GetRectangularSelectionAnchorVirtualSpace();
const DocPos vSpcCaretMainPos = SciCall_GetRectangularSelectionCaretVirtualSpace();
DocChangeTransactionBegin();
UndoTransActionBegin();
DocPos iMaxLineLen = Sci_GetRangeMaxLineLength(iLineStart, iLineEnd);
char* lineBuffer = AllocMem(iMaxLineLen + 1, HEAP_ZERO_MEMORY);
@ -4372,7 +4372,7 @@ void EditCompressBlanks()
SciCall_SetRectangularSelectionCaretVirtualSpace(vSpcCaretMainPos);
}
EndDocChangeTransaction();
EndUndoTransAction();
} else if (Sci_IsMultiSelection()) {
// @@@ not implemented
@ -4435,7 +4435,7 @@ void EditCompressBlanks()
if (bModified) {
DocChangeTransactionBegin();
UndoTransActionBegin();
if (!SciCall_IsSelectionEmpty()) {
SciCall_TargetFromSelection();
@ -4458,7 +4458,7 @@ void EditCompressBlanks()
EditSetSelectionEx(iNewPos, iNewPos, -1, -1);
}
EndDocChangeTransaction();
EndUndoTransAction();
}
}
FreeMem(pszOut);
@ -4493,7 +4493,7 @@ void EditRemoveBlankLines(HWND hwnd, bool bMerge, bool bRemoveWhiteSpace)
--iEndLine;
}
DocChangeTransactionBegin();
UndoTransActionBegin();
for (DocLn iLine = iBegLine; iLine <= iEndLine; ) {
DocLn nBlanks = 0;
@ -4538,8 +4538,7 @@ void EditRemoveBlankLines(HWND hwnd, bool bMerge, bool bRemoveWhiteSpace)
}
}
EndDocChangeTransaction();
EndUndoTransAction();
}
@ -4694,7 +4693,7 @@ void EditFocusMarkedLinesCmd(HWND hwnd, bool bCopy, bool bDelete)
if (bDelete) {
DocChangeTransactionBegin();
UndoTransActionBegin();
line = 0;
while (line >= 0) {
@ -4712,7 +4711,7 @@ void EditFocusMarkedLinesCmd(HWND hwnd, bool bCopy, bool bDelete)
}
}
EndDocChangeTransaction();
EndUndoTransAction();
}
SciCall_GotoLine(min_ln(curLn, Sci_GetLastDocLineNumber()));
@ -7332,9 +7331,9 @@ void EditSelectionMultiSelectAllEx(HWND hwnd, CLPCEDITFINDREPLACE edFndRpl)
LPCWSTR wchFind = _EditGetFindStrg(hwnd, &efr, false);
if (StrIsNotEmpty(wchFind)) {
DocChangeTransactionBegin();
UndoTransActionBegin();
EditMarkAll(wchFind, efr.fuFlags, 0, Sci_GetDocEndPosition(), true);
EndDocChangeTransaction();
EndUndoTransAction();
}
ReleaseEFR(&efr);
}
@ -7559,7 +7558,7 @@ void EditClearAllOccurrenceMarkers(HWND hwnd)
UNREFERENCED_PARAMETER(hwnd);
Globals.iMarkOccurrencesCount = Globals.iMarkOccurrencesCount = 0;
LimitNotifyEvents(EVM_None);
LimitNotifyEvents();
SciCall_SetIndicatorCurrent(INDIC_NP3_MARK_OCCURANCE);
SciCall_IndicatorClearRange(0, Sci_GetDocEndPosition());
@ -7671,7 +7670,7 @@ void EditMarkAll(LPCWSTR wchFind, int sFlags, DocPos rangeStart, DocPos rangeEnd
DocPos iFindLength = 0;
LimitNotifyEvents(EVM_None);
LimitNotifyEvents();
if (StrIsEmpty(wchFind)) {

View File

@ -416,20 +416,19 @@ static LONG _UndoRedoActionMap(const LONG token, const UndoRedoSelection_t** se
// => EndUndoTransAction();
static volatile LONG UndoActionToken = URTok_NoRecording; // needs UndoRedoRecordingStart()
static volatile int UndoRedoActionStackCount = 0;
static inline bool _InUndoRedoTransaction()
__forceinline bool _InUndoRedoTransaction()
{
return (InterlockedOr(&UndoActionToken, 0L) >= URTok_TokenStart);
return (UndoRedoActionStackCount > 0);
}
static inline void _SplitUndoTransaction()
{
if (!_InUndoRedoTransaction()) {
SciCall_BeginUndoAction();
/* noop */
if (_InUndoRedoTransaction()) {
SciCall_EndUndoAction();
/* noop */
SciCall_BeginUndoAction();
}
}
@ -452,28 +451,23 @@ static __forceinline bool IsEventSignaled() {
// ----------------------------------------------------------------------------
static volatile LONG iNotifyChangeStackCounter = 0L;
static __forceinline bool NotifyDocChanged()
__forceinline bool NotifyDocChanged()
{
return (InterlockedOr(&iNotifyChangeStackCounter, 0L) == 0L);
return ((SciCall_GetModEventMask() & EVM_Default) == EVM_Default);
}
void DisableDocChangeNotification()
int DisableDocChangeNotification()
{
if (NotifyDocChanged()) {
SciCall_SetModEventMask(EVM_None);
}
InterlockedIncrement(&iNotifyChangeStackCounter);
int const currentMask = SciCall_GetModEventMask();
SciCall_SetModEventMask(EVM_None);
return currentMask;
}
void EnableDocChangeNotification()
void EnableDocChangeNotification(const int evm)
{
if (!NotifyDocChanged()) {
InterlockedDecrement(&iNotifyChangeStackCounter);
}
SciCall_SetModEventMask(evm);
if (NotifyDocChanged()) {
SciCall_SetModEventMask(EVM_Default);
EditUpdateVisibleIndicators();
UpdateStatusbar(false);
}
@ -2651,8 +2645,6 @@ LRESULT MsgCreate(HWND hwnd, WPARAM wParam,LPARAM lParam)
SciCall_SetZoom(g_IniWinInfo.zoom ? g_IniWinInfo.zoom : 100);
EnableDocChangeNotification();
return 0LL;
}
@ -10208,6 +10200,7 @@ void UpdateUI() {
//=============================================================================
#if 0
LONG BeginUndoActionEx()
{
if (!_InUndoRedoTransaction()) {
@ -10237,6 +10230,7 @@ void EndUndoActionEx(const LONG token)
assert("No Transaction" && 0);
}
}
#endif
//=============================================================================
//
@ -10454,16 +10448,12 @@ static void _SaveRedoSelection(const LONG token)
//
LONG BeginUndoActionSelection()
{
if (_InUndoRedoTransaction()) {
return URTok_InTransaction;
}
LONG const token = _SaveUndoSelection();
if (token >= URTok_TokenStart) {
InterlockedExchange(&UndoActionToken, token);
SciCall_BeginUndoAction();
++UndoRedoActionStackCount;
if (1 == UndoRedoActionStackCount) {
DisableDocChangeNotification();
SciCall_BeginUndoAction();
}
return token;
return _SaveUndoSelection();
}
@ -10475,26 +10465,18 @@ const char* const _assert_msg = "Broken UndoRedo-Transaction!";
//
void EndUndoActionSelection(const LONG token)
{
switch (token) {
case URTok_InTransaction:
// nothing to do (child transaction)
break;
case URTok_NoTransaction:
assert(_assert_msg && InterlockedOr(&UndoActionToken, 0L) == URTok_NoTransaction);
break;
case URTok_NoRecording:
assert(_assert_msg && InterlockedOr(&UndoActionToken, 0L) == URTok_NoRecording);
break;
default:
if (token == InterlockedOr(&UndoActionToken, 0L)) {
_SaveRedoSelection(token);
SciCall_EndUndoAction();
InterlockedExchange(&UndoActionToken, URTok_NoTransaction);
EnableDocChangeNotification();
if (token >= URTok_TokenStart) {
--UndoRedoActionStackCount;
SciCall_EndUndoAction();
if (0 == UndoRedoActionStackCount) {
EnableDocChangeNotification(EVM_Default);
}
else { assert(_assert_msg && 0); }
break;
_SaveRedoSelection(token);
}
else {
assert(_assert_msg && 0);
}
assert(_assert_msg && (UndoRedoActionStackCount >= 0));
}
//=============================================================================
@ -10512,7 +10494,7 @@ static void _RestoreActionSelection(const LONG token, DoAction doAct)
if ((_UndoRedoActionMap(token, &pSel) >= URTok_TokenStart) && (pSel != NULL)) {
LimitNotifyEvents(EVM_None);
LimitNotifyEvents();
DocPos* pPosAnchor = (DocPos*)((UNDO == doAct) ? utarray_front(pSel->anchorPos_undo) : utarray_front(pSel->anchorPos_redo));
DocPos* pPosCur = (DocPos*)((UNDO == doAct) ? utarray_front(pSel->curPos_undo) : utarray_front(pSel->curPos_redo));
@ -10727,22 +10709,15 @@ static LONG _UndoRedoActionMap(const LONG token, const UndoRedoSelection_t** sel
ULONG utoken = (token >= URTok_TokenStart) ? (ULONG)token : 0UL;
if (selection == NULL) { // reset / clear
LONG const curToken = InterlockedOr(&UndoActionToken, 0L);
if (curToken == URTok_NoTokenFlag) {
EndUndoActionEx(curToken);
InterlockedExchange(&UndoActionToken, URTok_InTransaction);
}
else if (curToken >= URTok_TokenStart) {
EndUndoActionSelection(curToken);
}
else {
InterlockedExchange(&UndoActionToken, URTok_NoTransaction);
while (UndoRedoActionStackCount > 0) {
SciCall_EndUndoAction();
--UndoRedoActionStackCount;
}
utarray_clear(UndoRedoSelectionUTArray);
//~utarray_free(UndoRedoSelectionUTArray);
//~utarray_init(UndoRedoSelectionUTArray, &UndoRedoSelection_icd);
uiTokenCnt = URTok_TokenStart;
return InterlockedOr(&UndoActionToken, 0L);
return URTok_NoTransaction;
}
if (!SciCall_GetUndoCollection()) {
@ -11120,9 +11095,9 @@ bool FileLoad(const HPATHL hfile_pth, const FileLoadFlags fLoadFlags)
if (bCheckEOL && !Style_MaybeBinaryFile(Globals.hwndEdit, Paths.CurrentFile)) {
if (WarnLineEndingDlg(Globals.hwndMain, &fioStatus)) {
DocChangeTransactionBegin();
UndoTransActionBegin();
SciCall_ConvertEOLs(fioStatus.iEOLMode);
EndDocChangeTransaction();
EndUndoTransAction();
Globals.bDocHasInconsistentEOLs = false;
}
SciCall_SetEOLMode(fioStatus.iEOLMode);

View File

@ -197,34 +197,20 @@ LRESULT MsgUahMenuBar(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam);
// ----------------------------------------------------------------------------
#define LimitNotifyEvents(EVM) { int _evm_ = 0; __try { _evm_ = SciCall_GetModEventMask(); SciCall_SetModEventMask(EVM);
#define RestoreNotifyEvents() ;} __finally { SciCall_SetModEventMask(_evm_); } }
int DisableDocChangeNotification();
void EnableDocChangeNotification(const int evm);
void DisableDocChangeNotification();
void EnableDocChangeNotification();
#define LimitNotifyEvents() { int _evm_ = 0; __try { _evm_ = DisableDocChangeNotification();
#define RestoreNotifyEvents() ;} __finally { EnableDocChangeNotification(_evm_); } }
// ----------------------------------------------------------------------------
// none msg change notify, preserve redo-undo selection stack (only in simple, non complex operations)
// none msg change notify, preserve redo-undo selection stack
#define UndoTransActionBegin() { LONG _token_ = 0L; __try { _token_ = BeginUndoActionSelection();
#define EndUndoTransAction() ;} __finally { EndUndoActionSelection(_token_); } }
// ----------------------------------------------------------------------------
LONG BeginUndoActionEx();
void EndUndoActionEx(const LONG token);
// lean msg change notify (preferred) - does not preserve redo-undo selection stack
#define DocChangeTransactionBegin() { LONG _tok_ = 0L; __try { _tok_ = BeginUndoActionEx();
#define EndDocChangeTransaction() ;} __finally { EndUndoActionEx(_tok_); } }
// DEBUG:
//#define DocChangeTransactionBegin() UndoTransActionBegin()
//#define EndDocChangeTransaction() EndUndoTransAction()
//#define UndoTransActionBegin() DocChangeTransactionBegin()
//#define EndUndoTransAction() EndDocChangeTransaction()
// ----------------------------------------------------------------------------
#define BeginWaitCursor(cond, text) { \
if (cond) { \
SciCall_SetCursor(SC_CURSORWAIT); \

View File

@ -700,22 +700,13 @@ DeclareSciCallV1(SetAdditionalCaretsVisible, SETADDITIONALCARETSVISIBLE, bool, f
// Undo/Redo Stack
//
DeclareSciCallV0(EmptyUndoBuffer, EMPTYUNDOBUFFER);
//DeclareSciCallV0(BeginUndoAction, BEGINUNDOACTION);
DeclareSciCallV0(BeginUndoAction, BEGINUNDOACTION);
DeclareSciCallV2(AddUndoAction, ADDUNDOACTION, int, token, int, flags);
//DeclareSciCallV0(EndUndoAction, ENDUNDOACTION);
DeclareSciCallV0(EndUndoAction, ENDUNDOACTION);
DeclareSciCallR0(GetUndoCollection, GETUNDOCOLLECTION, bool);
DeclareSciCallV1(SetUndoCollection, SETUNDOCOLLECTION, bool, bCollectUndo);
inline void SciCall_BeginUndoAction()
{
SciCall(SCI_BEGINUNDOACTION, 0, 0);
}
inline void SciCall_EndUndoAction()
{
SciCall(SCI_ENDUNDOACTION, 0, 0);
}
//=============================================================================
//
// IME