wire up debug panel
This commit is contained in:
@@ -12,6 +12,12 @@ public static class GlobalEvents
|
||||
public static event Func<Task> StartedRunningProject = () => Task.CompletedTask;
|
||||
public static void InvokeStartedRunningProject() => StartedRunningProject?.InvokeParallelFireAndForget();
|
||||
|
||||
public static event Func<SharpIdeProjectModel, Task> ProjectStartedDebugging = _ => Task.CompletedTask;
|
||||
public static void InvokeProjectStartedDebugging(SharpIdeProjectModel project) => ProjectStartedDebugging?.InvokeParallelFireAndForget(project);
|
||||
|
||||
public static event Func<SharpIdeProjectModel, Task> ProjectStoppedDebugging = _ => Task.CompletedTask;
|
||||
public static void InvokeProjectStoppedDebugging(SharpIdeProjectModel project) => ProjectStoppedDebugging?.InvokeParallelFireAndForget(project);
|
||||
|
||||
public static event Func<SharpIdeProjectModel, Task> ProjectStartedRunning = _ => Task.CompletedTask;
|
||||
public static void InvokeProjectStartedRunning(SharpIdeProjectModel project) => ProjectStartedRunning?.InvokeParallelFireAndForget(project);
|
||||
|
||||
|
||||
@@ -15,9 +15,8 @@ public class RunService
|
||||
private readonly ConcurrentDictionary<SharpIdeProjectModel, SemaphoreSlim> _projectLocks = [];
|
||||
public ConcurrentDictionary<SharpIdeFile, List<Breakpoint>> Breakpoints { get; } = [];
|
||||
private Debugger? _debugger; // TODO: Support multiple debuggers for multiple running projects
|
||||
public async Task RunProject(SharpIdeProjectModel project)
|
||||
public async Task RunProject(SharpIdeProjectModel project, bool isDebug = false)
|
||||
{
|
||||
var isDebug = true;
|
||||
Guard.Against.Null(project, nameof(project));
|
||||
Guard.Against.NullOrWhiteSpace(project.FilePath, nameof(project.FilePath), "Project file path cannot be null or empty.");
|
||||
await Task.CompletedTask.ConfigureAwait(ConfigureAwaitOptions.ForceYielding);
|
||||
@@ -92,9 +91,16 @@ public class RunService
|
||||
|
||||
project.Running = true;
|
||||
project.OpenInRunPanel = true;
|
||||
GlobalEvents.InvokeProjectsRunningChanged();
|
||||
GlobalEvents.InvokeStartedRunningProject();
|
||||
GlobalEvents.InvokeProjectStartedRunning(project);
|
||||
if (isDebug)
|
||||
{
|
||||
GlobalEvents.InvokeProjectStartedDebugging(project);
|
||||
}
|
||||
else
|
||||
{
|
||||
GlobalEvents.InvokeProjectsRunningChanged();
|
||||
GlobalEvents.InvokeStartedRunningProject();
|
||||
GlobalEvents.InvokeProjectStartedRunning(project);
|
||||
}
|
||||
project.InvokeProjectStartedRunning();
|
||||
await process.WaitForExitAsync().WaitAsync(project.RunningCancellationTokenSource.Token).ConfigureAwait(ConfigureAwaitOptions.SuppressThrowing);
|
||||
if (project.RunningCancellationTokenSource.IsCancellationRequested)
|
||||
@@ -107,8 +113,16 @@ public class RunService
|
||||
project.RunningCancellationTokenSource.Dispose();
|
||||
project.RunningCancellationTokenSource = null;
|
||||
project.Running = false;
|
||||
GlobalEvents.InvokeProjectsRunningChanged();
|
||||
GlobalEvents.InvokeProjectStoppedRunning(project);
|
||||
if (isDebug)
|
||||
{
|
||||
GlobalEvents.InvokeProjectStoppedDebugging(project);
|
||||
}
|
||||
else
|
||||
{
|
||||
GlobalEvents.InvokeProjectsRunningChanged();
|
||||
GlobalEvents.InvokeProjectStoppedRunning(project);
|
||||
}
|
||||
|
||||
project.InvokeProjectStoppedRunning();
|
||||
|
||||
Console.WriteLine("Project finished running");
|
||||
@@ -133,6 +147,11 @@ public class RunService
|
||||
await _debugger!.StepOver(threadId);
|
||||
}
|
||||
|
||||
public async Task GetInfoAtStopPoint()
|
||||
{
|
||||
await _debugger!.GetInfoAtStopPoint();
|
||||
}
|
||||
|
||||
private string GetRunArguments(SharpIdeProjectModel project)
|
||||
{
|
||||
var dllFullPath = ProjectEvaluation.GetOutputDllFullPath(project);
|
||||
|
||||
@@ -13,27 +13,28 @@ public partial class DebugPanel : Control
|
||||
[Export]
|
||||
public Texture2D RunningIcon { get; set; } = null!;
|
||||
|
||||
private PackedScene _runPanelTabScene = GD.Load<PackedScene>("res://Features/Run/RunPanelTab.tscn");
|
||||
private PackedScene _debugPanelTabScene = GD.Load<PackedScene>("res://Features/Debug_/DebugPanelTab.tscn");
|
||||
public override void _Ready()
|
||||
{
|
||||
if (RunningIcon is null) throw new Exception("RunningIcon is null in DebugPanel");
|
||||
_tabBar = GetNode<TabBar>("%TabBar");
|
||||
_tabBar.ClearTabs();
|
||||
//_tabBar.TabClosePressed
|
||||
_tabBar.TabClicked += OnTabBarTabClicked;
|
||||
_tabsPanel = GetNode<Panel>("%TabsPanel");
|
||||
GlobalEvents.ProjectStartedRunning += async projectModel =>
|
||||
GlobalEvents.ProjectStartedDebugging += async projectModel =>
|
||||
{
|
||||
await this.InvokeAsync(() => ProjectStartedRunning(projectModel));
|
||||
await this.InvokeAsync(() => ProjectStartedDebugging(projectModel));
|
||||
};
|
||||
GlobalEvents.ProjectStoppedRunning += async projectModel =>
|
||||
GlobalEvents.ProjectStoppedDebugging += async projectModel =>
|
||||
{
|
||||
await this.InvokeAsync(() => ProjectStoppedRunning(projectModel));
|
||||
await this.InvokeAsync(() => ProjectStoppedDebugging(projectModel));
|
||||
};
|
||||
}
|
||||
|
||||
private void OnTabBarTabClicked(long idx)
|
||||
{
|
||||
var children = _tabsPanel.GetChildren().OfType<RunPanelTab>().ToList();
|
||||
var children = _tabsPanel.GetChildren().OfType<DebugPanelTab>().ToList();
|
||||
foreach (var child in children)
|
||||
{
|
||||
child.Visible = false;
|
||||
@@ -43,9 +44,9 @@ public partial class DebugPanel : Control
|
||||
tab.Visible = true;
|
||||
}
|
||||
|
||||
public void ProjectStartedRunning(SharpIdeProjectModel projectModel)
|
||||
public void ProjectStartedDebugging(SharpIdeProjectModel projectModel)
|
||||
{
|
||||
var existingRunPanelTab = _tabsPanel.GetChildren().OfType<RunPanelTab>().SingleOrDefault(s => s.Project == projectModel);
|
||||
var existingRunPanelTab = _tabsPanel.GetChildren().OfType<DebugPanelTab>().SingleOrDefault(s => s.Project == projectModel);
|
||||
if (existingRunPanelTab != null)
|
||||
{
|
||||
_tabBar.SetTabIcon(existingRunPanelTab.TabBarTab, RunningIcon);
|
||||
@@ -56,21 +57,21 @@ public partial class DebugPanel : Control
|
||||
return;
|
||||
}
|
||||
|
||||
var runPanelTab = _runPanelTabScene.Instantiate<RunPanelTab>();
|
||||
runPanelTab.Project = projectModel;
|
||||
var debugPanelTab = _debugPanelTabScene.Instantiate<DebugPanelTab>();
|
||||
debugPanelTab.Project = projectModel;
|
||||
_tabBar.AddTab(projectModel.Name);
|
||||
var tabIdx = _tabBar.GetTabCount() - 1;
|
||||
runPanelTab.TabBarTab = tabIdx;
|
||||
_tabBar.SetTabIcon(runPanelTab.TabBarTab, RunningIcon);
|
||||
_tabBar.CurrentTab = runPanelTab.TabBarTab;
|
||||
_tabsPanel.AddChild(runPanelTab);
|
||||
OnTabBarTabClicked(runPanelTab.TabBarTab);
|
||||
runPanelTab.StartWritingFromProjectOutput();
|
||||
debugPanelTab.TabBarTab = tabIdx;
|
||||
_tabBar.SetTabIcon(debugPanelTab.TabBarTab, RunningIcon);
|
||||
_tabBar.CurrentTab = debugPanelTab.TabBarTab;
|
||||
_tabsPanel.AddChild(debugPanelTab);
|
||||
OnTabBarTabClicked(debugPanelTab.TabBarTab);
|
||||
debugPanelTab.StartWritingFromProjectOutput();
|
||||
}
|
||||
|
||||
public void ProjectStoppedRunning(SharpIdeProjectModel projectModel)
|
||||
public void ProjectStoppedDebugging(SharpIdeProjectModel projectModel)
|
||||
{
|
||||
var runPanelTab = _tabsPanel.GetChildren().OfType<RunPanelTab>().Single(s => s.Project == projectModel);
|
||||
_tabBar.SetTabIcon(runPanelTab.TabBarTab, null);
|
||||
var debugPanelTab = _tabsPanel.GetChildren().OfType<DebugPanelTab>().Single(s => s.Project == projectModel);
|
||||
_tabBar.SetTabIcon(debugPanelTab.TabBarTab, null);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://dkjips8oudqou"]
|
||||
[gd_scene load_steps=3 format=3 uid="uid://dkjips8oudqou"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://ddyadu54qitw4" path="res://Features/Debug_/DebugPanel.cs" id="1_h4rcc"]
|
||||
[ext_resource type="Texture2D" uid="uid://0digl54lqm6p" path="res://Features/Run/Resources/Running.svg" id="2_pub1e"]
|
||||
|
||||
[node name="DebugPanel" type="Control"]
|
||||
layout_mode = 3
|
||||
@@ -10,6 +11,7 @@ anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_h4rcc")
|
||||
RunningIcon = ExtResource("2_pub1e")
|
||||
|
||||
[node name="Label" type="Label" parent="."]
|
||||
layout_mode = 1
|
||||
|
||||
5
src/SharpIDE.Godot/Features/Run/Resources/Debug.svg
Normal file
5
src/SharpIDE.Godot/Features/Run/Resources/Debug.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="mud-icon-root mud-svg-icon mud-icon-size-medium" focusable="false" viewBox="0 0 24 24" aria-hidden="true" role="img" style="fill: rgb(11, 186, 131);">
|
||||
<path d="M0 0h24v24H0z" fill="none"/>
|
||||
<path d="M20 8h-2.81c-.45-.78-1.07-1.45-1.82-1.96L17 4.41 15.59 3l-2.17 2.17C12.96 5.06 12.49 5 12 5c-.49 0-.96.06-1.41.17L8.41 3 7 4.41l1.62 1.63C7.88 6.55 7.26 7.22 6.81 8H4v2h2.09c-.05.33-.09.66-.09 1v1H4v2h2v1c0 .34.04.67.09 1H4v2h2.81c1.04 1.79 2.97 3 5.19 3s4.15-1.21 5.19-3H20v-2h-2.09c.05-.33.09-.66.09-1v-1h2v-2h-2v-1c0-.34-.04-.67-.09-1H20V8zm-6 8h-4v-2h4v2zm0-4h-4v-2h4v2z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 672 B |
37
src/SharpIDE.Godot/Features/Run/Resources/Debug.svg.import
Normal file
37
src/SharpIDE.Godot/Features/Run/Resources/Debug.svg.import
Normal file
@@ -0,0 +1,37 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://c7cmou8hipsvc"
|
||||
path="res://.godot/imported/Debug.svg-ae946e7dd0fbc448ad458ff70295702c.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://Features/Run/Resources/Debug.svg"
|
||||
dest_files=["res://.godot/imported/Debug.svg-ae946e7dd0fbc448ad458ff70295702c.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
svg/scale=1.0
|
||||
editor/scale_with_editor_scale=false
|
||||
editor/convert_colors_with_editor_theme=false
|
||||
@@ -9,6 +9,7 @@ public partial class RunMenuItem : HBoxContainer
|
||||
public SharpIdeProjectModel Project { get; set; } = null!;
|
||||
private Label _label = null!;
|
||||
private Button _runButton = null!;
|
||||
private Button _debugButton = null!;
|
||||
private Button _stopButton = null!;
|
||||
public override void _Ready()
|
||||
{
|
||||
@@ -18,6 +19,8 @@ public partial class RunMenuItem : HBoxContainer
|
||||
_runButton.Pressed += OnRunButtonPressed;
|
||||
_stopButton = GetNode<Button>("StopButton");
|
||||
_stopButton.Pressed += OnStopButtonPressed;
|
||||
_debugButton = GetNode<Button>("DebugButton");
|
||||
_debugButton.Pressed += OnDebugButtonPressed;
|
||||
Project.ProjectStartedRunning += OnProjectStartedRunning;
|
||||
Project.ProjectStoppedRunning += OnProjectStoppedRunning;
|
||||
}
|
||||
@@ -27,6 +30,7 @@ public partial class RunMenuItem : HBoxContainer
|
||||
await this.InvokeAsync(() =>
|
||||
{
|
||||
_stopButton.Visible = false;
|
||||
_debugButton.Visible = true;
|
||||
_runButton.Visible = true;
|
||||
});
|
||||
}
|
||||
@@ -36,6 +40,7 @@ public partial class RunMenuItem : HBoxContainer
|
||||
await this.InvokeAsync(() =>
|
||||
{
|
||||
_runButton.Visible = false;
|
||||
_debugButton.Visible = false;
|
||||
_stopButton.Visible = true;
|
||||
});
|
||||
}
|
||||
@@ -50,4 +55,10 @@ public partial class RunMenuItem : HBoxContainer
|
||||
GodotGlobalEvents.InvokeBottomPanelTabExternallySelected(BottomPanelType.Run);
|
||||
await Singletons.RunService.RunProject(Project).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private async void OnDebugButtonPressed()
|
||||
{
|
||||
GodotGlobalEvents.InvokeBottomPanelTabExternallySelected(BottomPanelType.Debug);
|
||||
await Singletons.RunService.RunProject(Project, true).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
[gd_scene load_steps=4 format=3 uid="uid://d2ewm2lajutpv"]
|
||||
[gd_scene load_steps=5 format=3 uid="uid://d2ewm2lajutpv"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://btsnapfx0dlbb" path="res://Features/Run/RunMenuItem.cs" id="1_syj0f"]
|
||||
[ext_resource type="Texture2D" uid="uid://bkty6563cthj8" path="res://Features/Run/Resources/Run.svg" id="2_hxkig"]
|
||||
[ext_resource type="Texture2D" uid="uid://c7cmou8hipsvc" path="res://Features/Run/Resources/Debug.svg" id="3_cd138"]
|
||||
[ext_resource type="Texture2D" uid="uid://debdmtqgw5dhf" path="res://Features/Run/Resources/Stop.svg" id="3_hxkig"]
|
||||
|
||||
[node name="RunMenuItem" type="HBoxContainer"]
|
||||
@@ -22,6 +23,11 @@ layout_mode = 2
|
||||
size_flags_vertical = 4
|
||||
icon = ExtResource("2_hxkig")
|
||||
|
||||
[node name="DebugButton" type="Button" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 4
|
||||
icon = ExtResource("3_cd138")
|
||||
|
||||
[node name="StopButton" type="Button" parent="."]
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
|
||||
@@ -18,6 +18,7 @@ public partial class RunPanel : Control
|
||||
private PackedScene _runPanelTabScene = GD.Load<PackedScene>("res://Features/Run/RunPanelTab.tscn");
|
||||
public override void _Ready()
|
||||
{
|
||||
if (RunningIcon is null) throw new Exception("RunningIcon is null in RunPanel");
|
||||
_tabBar = GetNode<TabBar>("%TabBar");
|
||||
_tabBar.ClearTabs();
|
||||
//_tabBar.TabClosePressed
|
||||
|
||||
Reference in New Issue
Block a user