Merge pull request #44107 from neikeq/fix-slow-build-log-update

C#: Fix very slow build log update in the editor
This commit is contained in:
Rémi Verschelde 2020-12-05 16:41:24 +01:00 committed by GitHub
commit af61ad5e36
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 30 additions and 6 deletions

View File

@ -2,6 +2,7 @@ using Godot;
using System; using System;
using Godot.Collections; using Godot.Collections;
using GodotTools.Internals; using GodotTools.Internals;
using JetBrains.Annotations;
using File = GodotTools.Utils.File; using File = GodotTools.Utils.File;
using Path = System.IO.Path; using Path = System.IO.Path;
@ -26,6 +27,9 @@ namespace GodotTools.Build
private TextEdit buildLog; private TextEdit buildLog;
private PopupMenu issuesListContextMenu; private PopupMenu issuesListContextMenu;
private readonly object pendingBuildLogTextLock = new object();
[NotNull] private string pendingBuildLogText = string.Empty;
[Signal] public event Action BuildStateChanged; [Signal] public event Action BuildStateChanged;
public bool HasBuildExited { get; private set; } = false; public bool HasBuildExited { get; private set; } = false;
@ -240,16 +244,34 @@ namespace GodotTools.Build
EmitSignal(nameof(BuildStateChanged)); EmitSignal(nameof(BuildStateChanged));
} }
private void UpdateBuildLogText()
{
lock (pendingBuildLogTextLock)
{
buildLog.Text += pendingBuildLogText;
pendingBuildLogText = string.Empty;
ScrollToLastNonEmptyLogLine();
}
}
private void StdOutputReceived(string text) private void StdOutputReceived(string text)
{ {
buildLog.Text += text + "\n"; lock (pendingBuildLogTextLock)
ScrollToLastNonEmptyLogLine(); {
if (pendingBuildLogText.Length == 0)
CallDeferred(nameof(UpdateBuildLogText));
pendingBuildLogText += text + "\n";
}
} }
private void StdErrorReceived(string text) private void StdErrorReceived(string text)
{ {
buildLog.Text += text + "\n"; lock (pendingBuildLogTextLock)
ScrollToLastNonEmptyLogLine(); {
if (pendingBuildLogText.Length == 0)
CallDeferred(nameof(UpdateBuildLogText));
pendingBuildLogText += text + "\n";
}
} }
private void ScrollToLastNonEmptyLogLine() private void ScrollToLastNonEmptyLogLine()
@ -377,12 +399,14 @@ namespace GodotTools.Build
BuildManager.BuildStarted += BuildStarted; BuildManager.BuildStarted += BuildStarted;
BuildManager.BuildFinished += BuildFinished; BuildManager.BuildFinished += BuildFinished;
// StdOutput/Error can be received from different threads, so we need to use CallDeferred // StdOutput/Error can be received from different threads, so we need to use CallDeferred
BuildManager.StdOutputReceived += line => CallDeferred(nameof(StdOutputReceived), line); BuildManager.StdOutputReceived += StdOutputReceived;
BuildManager.StdErrorReceived += line => CallDeferred(nameof(StdErrorReceived), line); BuildManager.StdErrorReceived += StdErrorReceived;
} }
public void OnBeforeSerialize() public void OnBeforeSerialize()
{ {
// In case it didn't update yet. We don't want to have to serialize any pending output.
UpdateBuildLogText();
} }
public void OnAfterDeserialize() public void OnAfterDeserialize()