diff --git a/.idea/.idea.HopFrame/.idea/workspace.xml b/.idea/.idea.HopFrame/.idea/workspace.xml index bd6cb12..041222e 100644 --- a/.idea/.idea.HopFrame/.idea/workspace.xml +++ b/.idea/.idea.HopFrame/.idea/workspace.xml @@ -12,33 +12,12 @@ - - - - - - - - - - - - - - - - - - - - - - - - + + + @@ -599,7 +589,6 @@ \ No newline at end of file diff --git a/src/HopFrame.Web/Components/Dialogs/HopFrameEditor.razor b/src/HopFrame.Web/Components/Dialogs/HopFrameEditor.razor index 5b157d5..279fccd 100644 --- a/src/HopFrame.Web/Components/Dialogs/HopFrameEditor.razor +++ b/src/HopFrame.Web/Components/Dialogs/HopFrameEditor.razor @@ -1,5 +1,6 @@ @rendermode InteractiveServer @implements IDialogContentComponent +@implements IDisposable @using System.Collections @using HopFrame.Core.Config @@ -184,6 +185,7 @@ private ITableManager? _manager; private readonly Dictionary> _validationErrors = new(); private readonly List _changes = new(); + private readonly CancellationTokenSource _tokenSource = new(); protected override void OnInitialized() { _currentlyEditing = Content.CurrentObject is not null; @@ -382,7 +384,7 @@ Errors = errorList, Property = property, Table = Content.Config - }); + }, _tokenSource.Token); if (eventResult.IsCanceled) return false; } @@ -400,7 +402,11 @@ ApplyChanges(Content.CurrentObject!); return true; } - + + public void Dispose() { + _tokenSource.Dispose(); + } + private enum InputType { Number, Switch, diff --git a/src/HopFrame.Web/Components/Pages/HopFrameTablePage.razor b/src/HopFrame.Web/Components/Pages/HopFrameTablePage.razor index 39ad6da..63fc4c0 100644 --- a/src/HopFrame.Web/Components/Pages/HopFrameTablePage.razor +++ b/src/HopFrame.Web/Components/Pages/HopFrameTablePage.razor @@ -158,6 +158,8 @@ private bool _allSelected; + private readonly CancellationTokenSource _tokenSource = new(); + protected override void OnInitialized() { _config ??= Explorer.GetTable(TableDisplayName); @@ -206,7 +208,7 @@ var eventResult = await PluginOrchestrator.DispatchEvent(new SearchEvent(this) { SearchTerm = _searchTerm, Table = _config! - }); + }, _tokenSource.Token); if (eventResult.IsCanceled) return; _searchTerm = eventResult.SearchTerm; @@ -218,7 +220,7 @@ var eventResult = await PluginOrchestrator.DispatchEvent(new ReloadEvent(this) { Table = _config! - }); + }, _tokenSource.Token); if (eventResult.IsCanceled) { _loading = false; return; @@ -240,7 +242,7 @@ NewPage = page, TotalPages = _totalPages, Table = _config! - }); + }, _tokenSource.Token); if (eventResult.IsCanceled) return; page = eventResult.NewPage; @@ -258,7 +260,7 @@ var eventResult = await PluginOrchestrator.DispatchEvent(new DeleteEntryEvent(this) { Entity = element, Table = _config! - }); + }, _tokenSource.Token); if (eventResult.IsCanceled) return; var dialog = await Dialogs.ShowConfirmationAsync("Do you really want to delete this entry?"); @@ -289,7 +291,7 @@ }; } - var eventResult = await PluginOrchestrator.DispatchEvent(eventArgs); + var eventResult = await PluginOrchestrator.DispatchEvent(eventArgs, _tokenSource.Token); if (eventResult.IsCanceled) return; var panel = await Dialogs.ShowPanelAsync(new EditorDialogData(_config!, element), new DialogParameters { @@ -317,7 +319,7 @@ Entity = item, Selected = selected, Table = _config! - }).Result; + }, _tokenSource.Token).Result; if (eventResult.IsCanceled) return; selected = eventResult.Selected; diff --git a/src/HopFrame.Web/Plugins/IPluginOrchestrator.cs b/src/HopFrame.Web/Plugins/IPluginOrchestrator.cs index 22b5cac..b711bd7 100644 --- a/src/HopFrame.Web/Plugins/IPluginOrchestrator.cs +++ b/src/HopFrame.Web/Plugins/IPluginOrchestrator.cs @@ -1,5 +1,7 @@ -namespace HopFrame.Web.Plugins; +using HopFrame.Web.Plugins.Events; + +namespace HopFrame.Web.Plugins; public interface IPluginOrchestrator { - public Task DispatchEvent(TEvent @event, CancellationToken ct = new()); + public Task DispatchEvent(TEvent @event, CancellationToken ct = new()) where TEvent : HopFrameEventArgs; } \ No newline at end of file diff --git a/src/HopFrame.Web/Plugins/Internal/PluginOrchestrator.cs b/src/HopFrame.Web/Plugins/Internal/PluginOrchestrator.cs index d0920b4..ad2fe03 100644 --- a/src/HopFrame.Web/Plugins/Internal/PluginOrchestrator.cs +++ b/src/HopFrame.Web/Plugins/Internal/PluginOrchestrator.cs @@ -28,13 +28,25 @@ internal sealed class PluginOrchestrator(IServiceProvider services) : IPluginOrc } } - public async Task DispatchEvent(TEvent @event, CancellationToken ct = new()) { + public async Task DispatchEvent(TEvent @event, CancellationToken ct = new()) where TEvent : HopFrameEventArgs { var eventContainers = services.GetRequiredService>() .Where(container => container.EventType == typeof(TEvent)); + var eventType = typeof(TEvent); + var tokenType = typeof(CancellationToken); foreach (var container in eventContainers) { var plugin = services.GetRequiredService(container.Handler.DeclaringType!); - var result = container.Handler.Invoke(plugin, [@event]); + var parameters = new List(); + + foreach (var parameter in container.Handler.GetParameters()) { + if (parameter.ParameterType == eventType) + parameters.Add(@event); + else if (parameter.ParameterType == tokenType) + parameters.Add(ct); + else parameters.Add(null); + } + + var result = container.Handler.Invoke(plugin, parameters.ToArray()); if (container.IsAwaitable) await (Task)result!;