diff --git a/src/SharpIDE.Godot/Features/Run/RunPanel.cs b/src/SharpIDE.Godot/Features/Run/RunPanel.cs index 1a6cac5..66d8e6f 100644 --- a/src/SharpIDE.Godot/Features/Run/RunPanel.cs +++ b/src/SharpIDE.Godot/Features/Run/RunPanel.cs @@ -38,6 +38,7 @@ public partial class RunPanel : Control { _tabBar.SetTabIcon(existingRunPanelTab.TabBarTab, RunningIcon); existingRunPanelTab.ClearTerminal(); + existingRunPanelTab.StartWritingFromProjectOutput(); return; } @@ -48,6 +49,7 @@ public partial class RunPanel : Control runPanelTab.TabBarTab = tabIdx; _tabBar.SetTabIcon(runPanelTab.TabBarTab, RunningIcon); _tabsPanel.AddChild(runPanelTab); + runPanelTab.StartWritingFromProjectOutput(); } public void ProjectStoppedRunning(SharpIdeProjectModel projectModel) diff --git a/src/SharpIDE.Godot/Features/Run/RunPanel.tscn b/src/SharpIDE.Godot/Features/Run/RunPanel.tscn index 4c6d435..11f9c7d 100644 --- a/src/SharpIDE.Godot/Features/Run/RunPanel.tscn +++ b/src/SharpIDE.Godot/Features/Run/RunPanel.tscn @@ -14,8 +14,6 @@ script = ExtResource("1_sq1l4") RunningIcon = ExtResource("2_tu4jg") [node name="VBoxContainer" type="VBoxContainer" parent="."] -z_index = 100 -y_sort_enabled = true layout_mode = 1 anchors_preset = 15 anchor_right = 1.0 @@ -27,6 +25,7 @@ theme_override_constants/separation = 0 [node name="TabBar" type="TabBar" parent="VBoxContainer"] unique_name_in_owner = true layout_mode = 2 +focus_mode = 0 current_tab = 0 tab_close_display_policy = 2 tab_count = 1 diff --git a/src/SharpIDE.Godot/Features/Run/RunPanelTab.cs b/src/SharpIDE.Godot/Features/Run/RunPanelTab.cs index c7fc132..96a0c09 100644 --- a/src/SharpIDE.Godot/Features/Run/RunPanelTab.cs +++ b/src/SharpIDE.Godot/Features/Run/RunPanelTab.cs @@ -1,3 +1,6 @@ +using System.Collections.Frozen; +using System.Collections.Generic; +using System.Threading.Tasks; using GDExtensionBindgen; using Godot; using SharpIDE.Application.Features.SolutionDiscovery.VsPersistence; @@ -7,16 +10,36 @@ namespace SharpIDE.Godot.Features.Run; public partial class RunPanelTab : Control { private Terminal _terminal = null!; + private Task _writeTask = Task.CompletedTask; public SharpIdeProjectModel Project { get; set; } = null!; public int TabBarTab { get; set; } public override void _Ready() { - _terminal = new Terminal(); - AddChild(_terminal); + var terminalControl = GetNode("Terminal"); + _terminal = new Terminal(terminalControl); } + public void StartWritingFromProjectOutput() + { + if (_writeTask.IsCompleted is not true) + { + GD.PrintErr("Attempted to start writing from project output, but a write task is already running."); + return; + } + _writeTask = GodotTask.Run(async () => + { + await foreach (var array in Project.RunningOutputChannel!.Reader.ReadAllAsync().ConfigureAwait(false)) + { + //_terminal.Write(array); + //await this.InvokeAsync(() => _terminal.Write(array)); + var str = System.Text.Encoding.UTF8.GetString(array); + await this.InvokeAsync(() => _terminal.Write(str)); + } + }); + } + public void ClearTerminal() { _terminal.Clear(); diff --git a/src/SharpIDE.Godot/NodeExtensions.cs b/src/SharpIDE.Godot/NodeExtensions.cs index 3ca88c5..05bb877 100644 --- a/src/SharpIDE.Godot/NodeExtensions.cs +++ b/src/SharpIDE.Godot/NodeExtensions.cs @@ -43,4 +43,37 @@ public static class NodeExtensions }).CallDeferred(); return taskCompletionSource.Task; } +} + +public static class GodotTask +{ + public static async Task Run(Action action) + { + await Task.Run(() => + { + try + { + action(); + } + catch (Exception ex) + { + GD.PrintErr($"Error: {ex}"); + } + }); + } + + public static async Task Run(Func action) + { + await Task.Run(async () => + { + try + { + await action(); + } + catch (Exception ex) + { + GD.PrintErr($"Error: {ex}"); + } + }); + } } \ No newline at end of file