From: Jean-Philippe Bruyère Date: Sun, 9 Mar 2025 22:19:24 +0000 (+0100) Subject: async compile SourceDocument X-Git-Url: https://git.osiis.dedyn.io/?a=commitdiff_plain;h=3c1b42096ed681ed98f80ba6d7bb244285ff1608;p=jp%2Fcrowedit.git async compile SourceDocument --- diff --git a/CrowEditBase/src/Compiler/SourceDocument.cs b/CrowEditBase/src/Compiler/SourceDocument.cs index b4f220b..5db2e43 100644 --- a/CrowEditBase/src/Compiler/SourceDocument.cs +++ b/CrowEditBase/src/Compiler/SourceDocument.cs @@ -10,6 +10,8 @@ using System.Collections; using System.Collections.Generic; using Drawing2D; using System.Security; +using System.Threading; +using System.Threading.Tasks; namespace CrowEditBase { @@ -141,20 +143,33 @@ namespace CrowEditBase //protected abstract Tokenizer CreateTokenizer (); protected abstract SyntaxAnalyser CreateSyntaxAnalyser (); public abstract IList GetSuggestions (int absoluteTextPos, int currentTokenIndex, SyntaxNode currentNode, CharLocation loc); - + CancellationTokenSource cancelSource; + Task backgroundCompilationTask; protected virtual async void parse () { - SyntaxAnalyser syntaxAnalyser = CreateSyntaxAnalyser (); - root = await syntaxAnalyser.Process (); + if (backgroundCompilationTask != null && !backgroundCompilationTask.IsCompleted) { + cancelSource.Cancel(); + await backgroundCompilationTask; + } - NotifyValueChanged("Exceptions", syntaxAnalyser?.Exceptions); - NotifyValueChanged ("SyntaxRootChildNodes", (object)null); - NotifyValueChanged ("SyntaxRootChildNodes", SyntaxRootChildNodes); + cancelSource = new CancellationTokenSource(); + backgroundCompilationTask = Task.Run(()=>parseAssync(cancelSource.Token)); //CurrentNode?.ExpandToTheTop(); //CrowEditBase.App.Log (LogType.Low, $"Syntax Analysis done in {sw.ElapsedMilliseconds}(ms) {sw.ElapsedTicks}(ticks)"); } + async void parseAssync(CancellationToken cancel) { + SyntaxAnalyser syntaxAnalyser = CreateSyntaxAnalyser (); + root = await syntaxAnalyser.Process (cancel); + if (cancel.IsCancellationRequested) + return; + + NotifyValueChanged("Exceptions", syntaxAnalyser?.Exceptions); + NotifyValueChanged ("SyntaxRootChildNodes", (object)null); + NotifyValueChanged ("SyntaxRootChildNodes", SyntaxRootChildNodes); + } + public SyntaxException CurrentException { get => CrowEditBase.App.CurrentException; set { diff --git a/CrowEditBase/src/Compiler/SyntaxAnalyser.cs b/CrowEditBase/src/Compiler/SyntaxAnalyser.cs index 9273fe1..3f95d49 100644 --- a/CrowEditBase/src/Compiler/SyntaxAnalyser.cs +++ b/CrowEditBase/src/Compiler/SyntaxAnalyser.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; using Crow.Text; @@ -16,7 +17,7 @@ namespace CrowEditBase public SyntaxAnalyser (SourceDocument document) { this.document = document; } - public abstract Task Process (); + public abstract Task Process (CancellationToken cancel = default); #region Token handling protected Token curTok => tokIdx < 0 ? default : tokens[tokIdx]; diff --git a/CrowEditBase/src/Compiler/SyntaxNode.cs b/CrowEditBase/src/Compiler/SyntaxNode.cs index 69c73cb..31f70b5 100644 --- a/CrowEditBase/src/Compiler/SyntaxNode.cs +++ b/CrowEditBase/src/Compiler/SyntaxNode.cs @@ -102,6 +102,7 @@ namespace CrowEditBase } } } + public virtual int FoldedLineCount { get { if (isFolded) diff --git a/CrowEditBase/src/Editor.cs b/CrowEditBase/src/Editor.cs index 28175ac..48cc23e 100644 --- a/CrowEditBase/src/Editor.cs +++ b/CrowEditBase/src/Editor.cs @@ -105,7 +105,7 @@ namespace CrowEditBase CMDCopy.CanExecute = CMDCut.CanExecute = !SelectionIsEmpty; } } - public int CurrentColumn { + public int CurrentColumn { get => currentLoc.HasValue ? currentLoc.Value.Column < 0 ? 0 : currentLoc.Value.Column : 0; set { if (CurrentColumn == value) @@ -483,6 +483,8 @@ namespace CrowEditBase } protected int getLineIndexFromMousePosition (Point mouseLocalPos) => (int)Math.Min (Math.Max (0, Math.Floor ((mouseLocalPos.Y + ScrollY)/ lineHeight)), visualLineCount - 1); + protected int getLineIndexFromMousePositionUnchecked (Point mouseLocalPos) => + (int)Math.Max (0, Math.Floor ((mouseLocalPos.Y + ScrollY)/ lineHeight)); protected int getVisualLineIndex (Point mouseLocalPos) => (int)Math.Min (Math.Max (0, Math.Floor (mouseLocalPos.Y / lineHeight)), visibleLines - 1); protected virtual int visualCurrentLine => CurrentLoc.HasValue ? CurrentLoc.Value.Line : 0; diff --git a/CrowEditBase/src/SourceEditor.cs b/CrowEditBase/src/SourceEditor.cs index 4724f9e..e4b7762 100644 --- a/CrowEditBase/src/SourceEditor.cs +++ b/CrowEditBase/src/SourceEditor.cs @@ -13,6 +13,7 @@ using System.Collections.Generic; using System.Linq; using System.Text.Unicode; using System.Text; +using System.Threading.Tasks; namespace CrowEditBase { @@ -27,7 +28,7 @@ namespace CrowEditBase } int currentTokenIndex = -1; SyntaxNode currentNode; -#if DEBUG_NODE +/*#if DEBUG_NODE SyntaxNode _hoverNode; SyntaxNode hoverNode { get =>_hoverNode; @@ -38,7 +39,7 @@ namespace CrowEditBase RegisterForRedraw (); } } -#endif +#endif*/ public SyntaxNode CurrentNode { get => currentNode; set { @@ -211,6 +212,8 @@ namespace CrowEditBase } } + //Task taskFirstVisibleLineIndex; + #region Mouse & Keyboard overrides public override void onMouseDown (object sender, MouseButtonEventArgs e) { hideOverlay (); @@ -240,12 +243,41 @@ namespace CrowEditBase mouseIsInMargin = mouseIsInFoldRect = false; IFace.MouseCursor = MouseCursor.ibeam; } + + int hoverVisualLine = getLineIndexFromMousePositionUnchecked (mLoc); + int hoverLine = getAbsoluteLineFromVisualLine (hoverVisualLine); + + /***************************/ + /*hoverLoc = new CharLocation (hoverLine, -1, mLoc.X + ScrollX - leftMargin); + using (IContext gr = IFace.Backend.CreateContext (IFace.MainSurface)) { + gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight); + gr.SetFontSize (Font.Size); + updateLocation (gr, ref hoverLoc); + }*/ + /***************************/ + + NotifyValueChanged("MouseY", mLoc.Y + ScrollY); + NotifyValueChanged("hoverVisualLine", hoverVisualLine); + NotifyValueChanged("hoverLine", hoverLine); - updateHoverLocation (mLoc); + + if (mouseIsInMargin) { + if (hoverLoc.HasValue) + hoverLoc = new CharLocation (hoverLine, hoverLoc.Value.Column, hoverLoc.Value.VisualCharXPosition); + else + hoverLoc = new CharLocation (hoverLine, 0, 0); + } else { + hoverLoc = new CharLocation (hoverLine, -1, mLoc.X + ScrollX - leftMargin); + using (IContext gr = IFace.Backend.CreateContext (IFace.MainSurface)) { + gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight); + gr.SetFontSize (Font.Size); + updateLocation (gr, ref hoverLoc); + } + } if (mouseIsInMargin) { Rectangle rFold = new Rectangle (leftMargin - foldMargin - leftMarginRightGap, - (int)(lineHeight * getVisualLine(hoverLoc.Value.Line) + lineHeight / 2.0 - foldSize / 2.0) - ScrollY, foldSize, foldSize); + (int)(lineHeight * hoverVisualLine + lineHeight / 2.0 - foldSize / 2.0) - ScrollY, foldSize, foldSize); rFold.Inflate(2); mouseIsInFoldRect = rFold.ContainsOrIsEqual (mLoc); RegisterForRedraw(); @@ -261,12 +293,9 @@ namespace CrowEditBase } } protected override void updateHoverLocation (Point mouseLocalPos) { - int hoverVisualLine = getLineIndexFromMousePosition (mouseLocalPos); - int hoverLine = hoverVisualLine + countFoldedLinesUntil (hoverVisualLine); - NotifyValueChanged("MouseY", mouseLocalPos.Y + ScrollY); - NotifyValueChanged("ScrollY", ScrollY); - NotifyValueChanged("VisibleLines", visibleLines); - NotifyValueChanged("HoverLine", hoverLine); + int hoverVisualLine = getLineIndexFromMousePositionUnchecked (mouseLocalPos); + int hoverLine = getAbsoluteLineFromVisualLine (hoverVisualLine); + if (mouseIsInMargin) { if (hoverLoc.HasValue) hoverLoc = new CharLocation (hoverLine, hoverLoc.Value.Column, hoverLoc.Value.VisualCharXPosition); @@ -280,11 +309,11 @@ namespace CrowEditBase gr.SetFontSize (Font.Size); updateLocation (gr, ref hoverLoc); } -#if DEBUG_NODES +/*#if DEBUG_NODES if (Document is SourceDocument doc) { hoverNode = doc.FindNodeIncludingPosition (lines.GetAbsolutePosition (hoverLoc.Value)); } -#endif +#endif*/ } public override void onKeyDown(object sender, KeyEventArgs e) { @@ -415,7 +444,7 @@ namespace CrowEditBase } } - int getVisualLine (int absoluteLine) { + int getVisualLineFromAboluteLine (int absoluteLine) { if (!(Document is SourceDocument doc)) return absoluteLine; doc.EnterReadLock(); @@ -442,47 +471,32 @@ namespace CrowEditBase doc.ExitReadLock (); } } - int countFoldedLinesUntil (int visualLine) { + int getAbsoluteLineFromVisualLine (int visualLine) { if (!(Document is SourceDocument doc)) return 0; doc.EnterReadLock(); try { - int foldedLines = 0; if (!doc.IsParsed) return 0; - IEnumerator nodeEnum = doc.Root.VisibleFoldableNodes.GetEnumerator (); - if (!nodeEnum.MoveNext()) - return 0; - int l = 0; - while (l < visualLine + foldedLines) { - if (nodeEnum.Current.StartLocation.Line == l) { - if (nodeEnum.Current.isFolded) { - foldedLines += nodeEnum.Current.LineCount - 1; - SyntaxNode nextNode = nodeEnum.Current.NextSiblingOrParentsNextSibling; - if (nextNode == null || !nodeEnum.MoveNext()) - return foldedLines; - - while (nodeEnum.Current.StartLocation.Line < nextNode.StartLocation.Line) { - if (!nodeEnum.MoveNext()) - return foldedLines; - } + int linesToSkip = visualLine; + IEnumerator foldsEnum = doc.Root.VisibleFoldableNodes.GetEnumerator (); + bool notEndOfFolds = foldsEnum.MoveNext(); - } else if (!nodeEnum.MoveNext()) - return foldedLines; - } - l ++; + while (notEndOfFolds && foldsEnum.Current.StartLocation.Line < linesToSkip) { + if (foldsEnum.Current.isFolded) + linesToSkip += foldsEnum.Current.LineCount-1; + notEndOfFolds = foldsEnum.MoveNext(); } - //Console.WriteLine ($"visualLine: {visualLine} foldedLines: {foldedLines}"); - return foldedLines; + return linesToSkip; } finally { doc.ExitReadLock (); } } protected override int getAbsoluteLineIndexFromVisualLineMove (int startLine, int visualLineDiff) { - int newVl = Math.Min (Math.Max (0, getVisualLine (startLine) + visualLineDiff), visualLineCount - 1); - return newVl + countFoldedLinesUntil (newVl); + int newVl = Math.Min (Math.Max (0, getVisualLineFromAboluteLine (startLine) + visualLineDiff), visualLineCount - 1); + return getAbsoluteLineFromVisualLine (newVl); } protected override int visualLineCount @@ -490,10 +504,11 @@ namespace CrowEditBase get { if (!(Document is SourceDocument doc)) return base.visualLineCount; - return Document.LinesCount - countFoldedLinesUntil (Document.LinesCount); + + return Document.LinesCount - doc.Root.FoldedLineCount; } } - protected override int visualCurrentLine => CurrentLoc.HasValue ? getVisualLine (CurrentLoc.Value.Line) : 0; + protected override int visualCurrentLine => CurrentLoc.HasValue ? getVisualLineFromAboluteLine (CurrentLoc.Value.Line) : 0; protected override void updateMaxScrolls (LayoutingType layout) { updateMargin(); Rectangle cb = ClientRectangle; diff --git a/CrowEditBase/ui/sourceEditor.itmp b/CrowEditBase/ui/sourceEditor.itmp index 5444c2d..a8609d6 100644 --- a/CrowEditBase/ui/sourceEditor.itmp +++ b/CrowEditBase/ui/sourceEditor.itmp @@ -31,6 +31,10 @@