Create EventWrapper
This commit is contained in:
@@ -76,7 +76,7 @@ public class DebuggingService
|
||||
var filePath = dict?["source"]?["path"]!.Value<string>()!;
|
||||
var line = (dict?["line"]?.Value<int>()!).Value;
|
||||
var executionStopInfo = new ExecutionStopInfo { FilePath = filePath, Line = line, ThreadId = @event.ThreadId!.Value };
|
||||
GlobalEvents.Instance.InvokeDebuggerExecutionStopped(executionStopInfo);
|
||||
GlobalEvents.Instance.DebuggerExecutionStopped.InvokeParallelFireAndForget(executionStopInfo);
|
||||
if (@event.Reason is StoppedEvent.ReasonValue.Exception)
|
||||
{
|
||||
Console.WriteLine("Stopped due to exception, continuing");
|
||||
|
||||
29
src/SharpIDE.Application/Features/Events/EventWrapper.cs
Normal file
29
src/SharpIDE.Application/Features/Events/EventWrapper.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
namespace SharpIDE.Application.Features.Events;
|
||||
|
||||
public class EventWrapper<TReturn>(Func<TReturn> @event) : EventWrapperBase<Func<TReturn>>(@event) where TReturn : Task
|
||||
{
|
||||
public void InvokeParallelFireAndForget() => FireAndForget(() => InvokeParallelAsync());
|
||||
|
||||
public async Task InvokeParallelAsync()
|
||||
{
|
||||
await InvokeDelegatesAsync(Event.GetInvocationList(), del => ((Func<TReturn>)del)());
|
||||
}
|
||||
}
|
||||
|
||||
public class EventWrapper<TArg, TReturn>(Func<TArg, TReturn> @event) : EventWrapperBase<Func<TArg, TReturn>>(@event) where TReturn : Task
|
||||
{
|
||||
public void InvokeParallelFireAndForget(TArg arg) => FireAndForget(() => InvokeParallelAsync(arg));
|
||||
public async Task InvokeParallelAsync(TArg arg)
|
||||
{
|
||||
await InvokeDelegatesAsync(Event.GetInvocationList(), del => ((Func<TArg, TReturn>)del)(arg));
|
||||
}
|
||||
}
|
||||
|
||||
public class EventWrapper<TArg1, TArg2, TReturn>(Func<TArg1, TArg2, TReturn> @event) : EventWrapperBase<Func<TArg1, TArg2, TReturn>>(@event) where TReturn : Task
|
||||
{
|
||||
public void InvokeParallelFireAndForget(TArg1 arg1, TArg2 arg2) => FireAndForget(() => InvokeParallelAsync(arg1, arg2));
|
||||
public async Task InvokeParallelAsync(TArg1 arg, TArg2 arg2)
|
||||
{
|
||||
await InvokeDelegatesAsync(Event.GetInvocationList(), del => ((Func<TArg1, TArg2, TReturn>)del)(arg, arg2));
|
||||
}
|
||||
}
|
||||
44
src/SharpIDE.Application/Features/Events/EventWrapperBase.cs
Normal file
44
src/SharpIDE.Application/Features/Events/EventWrapperBase.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
namespace SharpIDE.Application.Features.Events;
|
||||
|
||||
public abstract class EventWrapperBase<TDelegate>(TDelegate @event) where TDelegate : Delegate
|
||||
{
|
||||
protected TDelegate Event = @event;
|
||||
|
||||
public void Subscribe(TDelegate handler) => Event = (TDelegate)Delegate.Combine(Event, handler);
|
||||
public void Unsubscribe(TDelegate handler) => Event = (TDelegate)Delegate.Remove(Event, handler)!;
|
||||
|
||||
protected static async void FireAndForget(Func<Task> action)
|
||||
{
|
||||
try
|
||||
{
|
||||
await action().ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"An exception occurred in an event handler: {ex}");
|
||||
}
|
||||
}
|
||||
|
||||
protected static async Task InvokeDelegatesAsync(IEnumerable<Delegate> invocationList, Func<Delegate, Task> delegateExecutorDelegate)
|
||||
{
|
||||
var tasks = invocationList.Select(async del =>
|
||||
{
|
||||
try
|
||||
{
|
||||
await delegateExecutorDelegate(del).ConfigureAwait(false);
|
||||
return null;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return ex;
|
||||
}
|
||||
});
|
||||
|
||||
var results = await Task.WhenAll(tasks).ConfigureAwait(false);
|
||||
var exceptions = results.Where(r => r is not null).Select(r => r!).ToList();
|
||||
if (exceptions.Count != 0)
|
||||
{
|
||||
throw new AggregateException(exceptions);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,26 +6,13 @@ namespace SharpIDE.Application.Features.Events;
|
||||
public class GlobalEvents
|
||||
{
|
||||
public static GlobalEvents Instance { get; set; } = null!;
|
||||
public event Func<Task> ProjectsRunningChanged = () => Task.CompletedTask;
|
||||
public void InvokeProjectsRunningChanged() => ProjectsRunningChanged?.InvokeParallelFireAndForget();
|
||||
|
||||
public event Func<Task> StartedRunningProject = () => Task.CompletedTask;
|
||||
public void InvokeStartedRunningProject() => StartedRunningProject?.InvokeParallelFireAndForget();
|
||||
|
||||
public event Func<SharpIdeProjectModel, Task> ProjectStartedDebugging = _ => Task.CompletedTask;
|
||||
public void InvokeProjectStartedDebugging(SharpIdeProjectModel project) => ProjectStartedDebugging?.InvokeParallelFireAndForget(project);
|
||||
|
||||
public event Func<SharpIdeProjectModel, Task> ProjectStoppedDebugging = _ => Task.CompletedTask;
|
||||
public void InvokeProjectStoppedDebugging(SharpIdeProjectModel project) => ProjectStoppedDebugging?.InvokeParallelFireAndForget(project);
|
||||
|
||||
public event Func<SharpIdeProjectModel, Task> ProjectStartedRunning = _ => Task.CompletedTask;
|
||||
public void InvokeProjectStartedRunning(SharpIdeProjectModel project) => ProjectStartedRunning?.InvokeParallelFireAndForget(project);
|
||||
|
||||
public event Func<SharpIdeProjectModel, Task> ProjectStoppedRunning = _ => Task.CompletedTask;
|
||||
public void InvokeProjectStoppedRunning(SharpIdeProjectModel project) => ProjectStoppedRunning?.InvokeParallelFireAndForget(project);
|
||||
|
||||
public event Func<ExecutionStopInfo, Task> DebuggerExecutionStopped = _ => Task.CompletedTask;
|
||||
public void InvokeDebuggerExecutionStopped(ExecutionStopInfo executionStopInfo) => DebuggerExecutionStopped?.InvokeParallelFireAndForget(executionStopInfo);
|
||||
public EventWrapper<Task> ProjectsRunningChanged { get; private set; } = new(() => Task.CompletedTask);
|
||||
public EventWrapper<Task> StartedRunningProject { get; private set; } = new(() => Task.CompletedTask);
|
||||
public EventWrapper<SharpIdeProjectModel, Task> ProjectStartedDebugging { get; private set; } = new(_ => Task.CompletedTask);
|
||||
public EventWrapper<SharpIdeProjectModel, Task> ProjectStoppedDebugging { get; private set; } = new(_ => Task.CompletedTask);
|
||||
public EventWrapper<SharpIdeProjectModel, Task> ProjectStartedRunning { get; private set; } = new(_ => Task.CompletedTask);
|
||||
public EventWrapper<SharpIdeProjectModel, Task> ProjectStoppedRunning { get; private set; } = new(_ => Task.CompletedTask);
|
||||
public EventWrapper<ExecutionStopInfo, Task> DebuggerExecutionStopped { get; private set; } = new(_ => Task.CompletedTask);
|
||||
}
|
||||
|
||||
public static class AsyncEventExtensions
|
||||
|
||||
@@ -93,13 +93,13 @@ public class RunService
|
||||
project.OpenInRunPanel = true;
|
||||
if (isDebug)
|
||||
{
|
||||
GlobalEvents.Instance.InvokeProjectStartedDebugging(project);
|
||||
GlobalEvents.Instance.ProjectStartedDebugging.InvokeParallelFireAndForget(project);
|
||||
}
|
||||
else
|
||||
{
|
||||
GlobalEvents.Instance.InvokeProjectsRunningChanged();
|
||||
GlobalEvents.Instance.InvokeStartedRunningProject();
|
||||
GlobalEvents.Instance.InvokeProjectStartedRunning(project);
|
||||
GlobalEvents.Instance.ProjectsRunningChanged.InvokeParallelFireAndForget();
|
||||
GlobalEvents.Instance.StartedRunningProject.InvokeParallelFireAndForget();
|
||||
GlobalEvents.Instance.ProjectStartedRunning.InvokeParallelFireAndForget(project);
|
||||
}
|
||||
project.InvokeProjectStartedRunning();
|
||||
await process.WaitForExitAsync().WaitAsync(project.RunningCancellationTokenSource.Token).ConfigureAwait(ConfigureAwaitOptions.SuppressThrowing);
|
||||
@@ -115,12 +115,12 @@ public class RunService
|
||||
project.Running = false;
|
||||
if (isDebug)
|
||||
{
|
||||
GlobalEvents.Instance.InvokeProjectStoppedDebugging(project);
|
||||
GlobalEvents.Instance.ProjectStoppedDebugging.InvokeParallelFireAndForget(project);
|
||||
}
|
||||
else
|
||||
{
|
||||
GlobalEvents.Instance.InvokeProjectsRunningChanged();
|
||||
GlobalEvents.Instance.InvokeProjectStoppedRunning(project);
|
||||
GlobalEvents.Instance.ProjectsRunningChanged.InvokeParallelFireAndForget();
|
||||
GlobalEvents.Instance.ProjectStoppedRunning.InvokeParallelFireAndForget(project);
|
||||
}
|
||||
|
||||
project.InvokeProjectStoppedRunning();
|
||||
|
||||
@@ -25,7 +25,7 @@ public partial class CodeEditorPanel : MarginContainer
|
||||
var tabBar = _tabContainer.GetTabBar();
|
||||
tabBar.TabCloseDisplayPolicy = TabBar.CloseButtonDisplayPolicy.ShowAlways;
|
||||
tabBar.TabClosePressed += OnTabClosePressed;
|
||||
GlobalEvents.Instance.DebuggerExecutionStopped += OnDebuggerExecutionStopped;
|
||||
GlobalEvents.Instance.DebuggerExecutionStopped.Subscribe(OnDebuggerExecutionStopped);
|
||||
}
|
||||
|
||||
public override void _UnhandledKeyInput(InputEvent @event)
|
||||
|
||||
@@ -22,14 +22,14 @@ public partial class DebugPanel : Control
|
||||
//_tabBar.TabClosePressed
|
||||
_tabBar.TabClicked += OnTabBarTabClicked;
|
||||
_tabsPanel = GetNode<MarginContainer>("%TabsPanel");
|
||||
GlobalEvents.Instance.ProjectStartedDebugging += async projectModel =>
|
||||
GlobalEvents.Instance.ProjectStartedDebugging.Subscribe(async projectModel =>
|
||||
{
|
||||
await this.InvokeAsync(() => ProjectStartedDebugging(projectModel));
|
||||
};
|
||||
GlobalEvents.Instance.ProjectStoppedDebugging += async projectModel =>
|
||||
});
|
||||
GlobalEvents.Instance.ProjectStoppedDebugging.Subscribe(async projectModel =>
|
||||
{
|
||||
await this.InvokeAsync(() => ProjectStoppedDebugging(projectModel));
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
private void OnTabBarTabClicked(long idx)
|
||||
|
||||
@@ -20,7 +20,7 @@ public partial class ThreadsVariablesSubTab : Control
|
||||
_threadsVboxContainer = GetNode<VBoxContainer>("%ThreadsPanel/VBoxContainer");
|
||||
_stackFramesVboxContainer = GetNode<VBoxContainer>("%StackFramesPanel/VBoxContainer");
|
||||
_variablesVboxContainer = GetNode<VBoxContainer>("%VariablesPanel/VBoxContainer");
|
||||
GlobalEvents.Instance.DebuggerExecutionStopped += OnDebuggerExecutionStopped;
|
||||
GlobalEvents.Instance.DebuggerExecutionStopped.Subscribe(OnDebuggerExecutionStopped);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -21,14 +21,14 @@ public partial class RunPanel : Control
|
||||
//_tabBar.TabClosePressed
|
||||
_tabBar.TabClicked += OnTabBarTabClicked;
|
||||
_tabsPanel = GetNode<MarginContainer>("%TabsPanel");
|
||||
GlobalEvents.Instance.ProjectStartedRunning += async projectModel =>
|
||||
GlobalEvents.Instance.ProjectStartedRunning.Subscribe(async projectModel =>
|
||||
{
|
||||
await this.InvokeAsync(() => ProjectStartedRunning(projectModel));
|
||||
};
|
||||
GlobalEvents.Instance.ProjectStoppedRunning += async projectModel =>
|
||||
});
|
||||
GlobalEvents.Instance.ProjectStoppedRunning.Subscribe(async projectModel =>
|
||||
{
|
||||
await this.InvokeAsync(() => ProjectStoppedRunning(projectModel));
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
private void OnTabBarTabClicked(long idx)
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
{
|
||||
var tasks = SolutionModel.AllProjects.Select(p => p.MsBuildEvaluationProjectTask);
|
||||
await Task.WhenAll(tasks);
|
||||
GlobalEvents.Instance.ProjectsRunningChanged += OnProjectsRunningChanged;
|
||||
GlobalEvents.Instance.ProjectsRunningChanged.Subscribe(OnProjectsRunningChanged);
|
||||
}
|
||||
|
||||
private void CloseTab(SharpIdeProjectModel project)
|
||||
@@ -67,7 +67,7 @@
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
|
||||
public void Dispose() => GlobalEvents.Instance.ProjectsRunningChanged -= OnProjectsRunningChanged;
|
||||
public void Dispose() => GlobalEvents.Instance.ProjectsRunningChanged.Unsubscribe(OnProjectsRunningChanged);
|
||||
|
||||
private void SetActiveTab(SharpIdeProjectModel project)
|
||||
{
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
GlobalEvents.Instance.ProjectsRunningChanged += OnProjectsRunningChanged;
|
||||
GlobalEvents.Instance.ProjectsRunningChanged.Subscribe(OnProjectsRunningChanged);
|
||||
}
|
||||
|
||||
protected override async Task OnParametersSetAsync()
|
||||
@@ -73,5 +73,5 @@
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
|
||||
public void Dispose() => GlobalEvents.Instance.ProjectsRunningChanged -= OnProjectsRunningChanged;
|
||||
public void Dispose() => GlobalEvents.Instance.ProjectsRunningChanged.Unsubscribe(OnProjectsRunningChanged);
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@
|
||||
{
|
||||
GlobalEvents.Instance = new GlobalEvents();
|
||||
await LoadSolutionFromInteractivePicker(AppState.IdeSettings.AutoOpenLastSolution);
|
||||
GlobalEvents.Instance.StartedRunningProject += OnStartedRunningProject;
|
||||
GlobalEvents.Instance.StartedRunningProject.Subscribe(OnStartedRunningProject);
|
||||
}
|
||||
|
||||
private void OnProblemSelected(SharpIdeFile file)
|
||||
|
||||
Reference in New Issue
Block a user