C#: Fix very slow build log update in the editor

(cherry picked from commit b0eb9061e4)
This commit is contained in:
Ignacio Etcheverry 2020-12-05 00:43:24 +01:00 committed by Rémi Verschelde
parent 9d2c012f23
commit c5acdfb5f5
No known key found for this signature in database
GPG key ID: C3336907360768E1

View file

@ -2,6 +2,7 @@ using Godot;
using System;
using Godot.Collections;
using GodotTools.Internals;
using JetBrains.Annotations;
using File = GodotTools.Utils.File;
using Path = System.IO.Path;
@ -26,8 +27,10 @@ namespace GodotTools.Build
private TextEdit buildLog;
private PopupMenu issuesListContextMenu;
[Signal]
public delegate void BuildStateChanged();
private readonly object pendingBuildLogTextLock = new object();
[NotNull] private string pendingBuildLogText = string.Empty;
[Signal] public event Action BuildStateChanged;
public bool HasBuildExited { get; private set; } = false;
@ -241,16 +244,34 @@ namespace GodotTools.Build
EmitSignal(nameof(BuildStateChanged));
}
private void UpdateBuildLogText()
{
lock (pendingBuildLogTextLock)
{
buildLog.Text += pendingBuildLogText;
pendingBuildLogText = string.Empty;
ScrollToLastNonEmptyLogLine();
}
}
private void StdOutputReceived(string text)
{
buildLog.Text += text + "\n";
ScrollToLastNonEmptyLogLine();
lock (pendingBuildLogTextLock)
{
if (pendingBuildLogText.Length == 0)
CallDeferred(nameof(UpdateBuildLogText));
pendingBuildLogText += text + "\n";
}
}
private void StdErrorReceived(string text)
{
buildLog.Text += text + "\n";
ScrollToLastNonEmptyLogLine();
lock (pendingBuildLogTextLock)
{
if (pendingBuildLogText.Length == 0)
CallDeferred(nameof(UpdateBuildLogText));
pendingBuildLogText += text + "\n";
}
}
private void ScrollToLastNonEmptyLogLine()
@ -378,12 +399,14 @@ namespace GodotTools.Build
BuildManager.BuildStarted += BuildStarted;
BuildManager.BuildFinished += BuildFinished;
// StdOutput/Error can be received from different threads, so we need to use CallDeferred
BuildManager.StdOutputReceived += line => CallDeferred(nameof(StdOutputReceived), line);
BuildManager.StdErrorReceived += line => CallDeferred(nameof(StdErrorReceived), line);
BuildManager.StdOutputReceived += StdOutputReceived;
BuildManager.StdErrorReceived += StdErrorReceived;
}
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()