From b4dae7c7749bfb5740e4245f10ad857706cf7401 Mon Sep 17 00:00:00 2001 From: Flaky Date: Sun, 8 Feb 2026 16:18:05 +0000 Subject: [PATCH] implement record event TagsWritten, deprecate WriteTagToDatabase (singular) --- .../TagDatabase/TagDatabase.WriteMethods.cs | 1 + UI/TagDatabaseService.cs | 20 +++--- UI/ViewModels/HierarchyTreeViewModel.cs | 68 ++++--------------- UI/ViewModels/MainWindowViewModel.cs | 19 +++--- UI/ViewModels/SearchViewModel.cs | 19 ++++-- 5 files changed, 50 insertions(+), 77 deletions(-) diff --git a/Core/Models/TagDatabase/TagDatabase.WriteMethods.cs b/Core/Models/TagDatabase/TagDatabase.WriteMethods.cs index d24575f..2c758dd 100644 --- a/Core/Models/TagDatabase/TagDatabase.WriteMethods.cs +++ b/Core/Models/TagDatabase/TagDatabase.WriteMethods.cs @@ -6,6 +6,7 @@ namespace TagHierarchyManager.Models; public partial class TagDatabase { + // DEPRECATED: move to WriteTagsToDatabase. /// /// Saves the tag object to the database. /// diff --git a/UI/TagDatabaseService.cs b/UI/TagDatabaseService.cs index 4f3a0a7..6a84469 100644 --- a/UI/TagDatabaseService.cs +++ b/UI/TagDatabaseService.cs @@ -17,10 +17,8 @@ public class TagDatabaseService : ObservableObject { public event EventHandler? InitialisationComplete; - public event EventHandler? TagAdded; - public event EventHandler<(int id, string name)>? TagDeleted; - public event EventHandler>? TagsAdded; - public event EventHandler>? TagsUpdated; + + public event EventHandler? TagsWritten; public string DatabaseName => this.Database?.Name ?? string.Empty; public int DatabaseVersion => this.Database?.Version ?? 0; @@ -31,6 +29,12 @@ public class TagDatabaseService : ObservableObject public int TagCount => this.Database?.Tags.Count ?? 0; public int TagRelationshipCount => this.Database?.GetTagRelationshipCount() ?? 0; + public sealed record TagWriteResult( + IReadOnlyList Added, + IReadOnlyList Updated, + IReadOnlyList<(int id, string name)> Deleted + ); + private TagDatabase? Database { get; set; } public void CloseDatabase() @@ -210,25 +214,25 @@ public class TagDatabaseService : ObservableObject private void TagDatabase_OnTagAdded(object? sender, Tag newTag) { - this.TagAdded?.Invoke(this, newTag); + this.TagsWritten?.Invoke(this, new TagWriteResult(new List {newTag}, [], [])); this.NotifyDatabasePropertiesChanged(); } private void TagDatabase_OnTagDeleted(object? sender, (int id, string name) deletedTag) { - this.TagDeleted?.Invoke(this, deletedTag); + this.TagsWritten?.Invoke(this, new TagWriteResult([], [], [deletedTag])); this.NotifyDatabasePropertiesChanged(); } private void TagDatabase_OnTagsAdded(object? sender, List newTags) { - this.TagsAdded?.Invoke(this, newTags); + this.TagsWritten?.Invoke(this, new TagWriteResult(newTags, [], [])); this.NotifyDatabasePropertiesChanged(); } private void TagDatabase_OnTagsUpdated(object? sender, List updatedTags) { - this.TagsUpdated?.Invoke(this, updatedTags); + this.TagsWritten?.Invoke(this, new TagWriteResult([], updatedTags, [])); this.NotifyDatabasePropertiesChanged(); } diff --git a/UI/ViewModels/HierarchyTreeViewModel.cs b/UI/ViewModels/HierarchyTreeViewModel.cs index 08b8d05..80f5d40 100644 --- a/UI/ViewModels/HierarchyTreeViewModel.cs +++ b/UI/ViewModels/HierarchyTreeViewModel.cs @@ -33,10 +33,7 @@ public partial class HierarchyTreeViewModel : ViewModelBase, IDisposable { if (!this._mainWindow.TagDatabaseService.IsDatabaseOpen) return; - this._mainWindow.TagDatabaseService.TagsUpdated -= this.TagDatabase_OnTagsUpdated; - this._mainWindow.TagDatabaseService.TagAdded -= this.TagDatabase_OnTagAdded; - this._mainWindow.TagDatabaseService.TagDeleted -= this.TagDatabase_OnTagDeleted; - this._mainWindow.TagDatabaseService.TagsAdded -= this.TagDatabase_OnTagsAdded; + this._mainWindow.TagDatabaseService.TagsWritten -= this.TagDatabaseService_OnTagsWritten; GC.SuppressFinalize(this); } @@ -191,7 +188,7 @@ public partial class HierarchyTreeViewModel : ViewModelBase, IDisposable this._mainWindow.SelectedTag = value; } - private async Task ProcessTagAdditions(List newTags) + private async Task ProcessTagAdditions(IReadOnlyList newTags) { foreach (var newTag in newTags) { @@ -207,43 +204,25 @@ public partial class HierarchyTreeViewModel : ViewModelBase, IDisposable private void SubscribeToEvents() { if (!this._mainWindow.TagDatabaseService.IsDatabaseOpen) return; - this._mainWindow.TagDatabaseService.TagsUpdated += this.TagDatabase_OnTagsUpdated; - this._mainWindow.TagDatabaseService.TagAdded += this.TagDatabase_OnTagAdded; - this._mainWindow.TagDatabaseService.TagDeleted += this.TagDatabase_OnTagDeleted; - this._mainWindow.TagDatabaseService.TagsAdded += this.TagDatabase_OnTagsAdded; + this._mainWindow.TagDatabaseService.TagsWritten += this.TagDatabaseService_OnTagsWritten; } - private async void TagDatabase_OnTagAdded(object? sender, Tag newTag) + private async void TagDatabaseService_OnTagsWritten(object? sender, TagDatabaseService.TagWriteResult result) { try { - await Dispatcher.UIThread.InvokeAsync(async () => await this.ProcessTagAdditions([newTag])); - } - catch (Exception e) - { - var error = new ErrorDialogViewModel(e.Message); - error.ShowDialog(); - } - } - - private async void TagDatabase_OnTagDeleted(object? sender, (int id, string name) deletedTag) - { - try - { - await Dispatcher.UIThread.InvokeAsync(async () => await this.WipeTagNodes(deletedTag.id)); - } - catch (Exception e) - { - var error = new ErrorDialogViewModel(e.Message); - error.ShowDialog(); - } - } + if (sender is not TagDatabaseService { IsDatabaseOpen: true }) return; + + if (result.Updated.Count > 0) + foreach (var updatedTag in result.Updated) + await Dispatcher.UIThread.InvokeAsync(async () => await this.HandleTagUpdate(updatedTag)); + + if (result.Added.Count > 0) + await Dispatcher.UIThread.InvokeAsync(async () => await this.ProcessTagAdditions(result.Added)); - private async void TagDatabase_OnTagsAdded(object? sender, List newTags) - { - try - { - await this.ProcessTagAdditions(newTags); + if (result.Deleted.Count > 0) + foreach (var deletedTag in result.Deleted) + await Dispatcher.UIThread.InvokeAsync(async () => await this.WipeTagNodes(deletedTag.id)); } catch (Exception e) { @@ -252,23 +231,6 @@ public partial class HierarchyTreeViewModel : ViewModelBase, IDisposable } } - private void TagDatabase_OnTagsUpdated(object? sender, List updatedTags) - { - Dispatcher.UIThread.Post(async void () => - { - try - { - foreach (var updatedTag in updatedTags) - await this.HandleTagUpdate(updatedTag); - } - catch (Exception e) - { - var error = new ErrorDialogViewModel(e.Message); - error.ShowDialog(); - } - }); - } - private async Task HandleTagUpdate(Tag updatedTag) { if (!this.ViewModelMap.TryGetValue(updatedTag.Id, out var tagViewModels)) return; diff --git a/UI/ViewModels/MainWindowViewModel.cs b/UI/ViewModels/MainWindowViewModel.cs index bb0f028..7e4c523 100644 --- a/UI/ViewModels/MainWindowViewModel.cs +++ b/UI/ViewModels/MainWindowViewModel.cs @@ -40,8 +40,7 @@ public partial class MainWindowViewModel : ViewModelBase { this.TagDatabaseService = tagDatabaseService; this.TagDatabaseService.InitialisationComplete += this.TagDatabaseService_OnInitalisationComplete; - this.TagDatabaseService.TagAdded += this.TagDatabaseService_TagAdded; - this.TagDatabaseService.TagDeleted += this.TagDatabaseService_TagDeleted; + this.TagDatabaseService.TagsWritten += this.TagDatabaseService_TagsWritten; this.TagDatabaseService.PropertyChanged += (_, args) => { if (args.PropertyName == nameof(this.TagDatabaseService.TagCount)) @@ -437,14 +436,14 @@ public partial class MainWindowViewModel : ViewModelBase }); } - private void TagDatabaseService_TagAdded(object? sender, Tag _) + private void TagDatabaseService_TagsWritten(object? sender, TagDatabaseService.TagWriteResult result) { - this.OnPropertyChanged(nameof(this.TotalTags)); - this.SelectedTag!.SyncId(); - } - - private void TagDatabaseService_TagDeleted(object? sender, (int id, string name) _) - { - this.OnPropertyChanged(nameof(this.TotalTags)); + if (result.Added.Count > 0) + { + this.SelectedTag?.SyncId(); + this.OnPropertyChanged(nameof(this.TotalTags)); + } + + if (result.Deleted.Count > 0) this.OnPropertyChanged(nameof(this.TotalTags)); } } \ No newline at end of file diff --git a/UI/ViewModels/SearchViewModel.cs b/UI/ViewModels/SearchViewModel.cs index 7a1c6bf..46dc2e8 100644 --- a/UI/ViewModels/SearchViewModel.cs +++ b/UI/ViewModels/SearchViewModel.cs @@ -21,12 +21,12 @@ public partial class SearchViewModel : ViewModelBase, IDisposable { this._mainWindow = mainWindow; this._getParentNamesById = mainWindow.TagDatabaseService.GetParentNamesByIds; - mainWindow.TagDatabaseService.TagDeleted += this.TagDatabase_OnTagDeleted; + mainWindow.TagDatabaseService.TagsWritten += this.TagDatabase_OnTagsWritten; } public void Dispose() { - this._mainWindow.TagDatabaseService.TagDeleted -= this.TagDatabase_OnTagDeleted; + this._mainWindow.TagDatabaseService.TagsWritten -= this.TagDatabase_OnTagsWritten; } public void Search(string searchQuery, TagDatabaseSearchMode mode, bool searchAliases) @@ -60,10 +60,17 @@ public partial class SearchViewModel : ViewModelBase, IDisposable this._mainWindow.SelectedTag = value; } - private void TagDatabase_OnTagDeleted(object? sender, (int id, string name) deletedTag) + private void TagDatabase_OnTagsWritten(object? sender, TagDatabaseService.TagWriteResult result) { - var deletedTagItemVm = this.SearchResults.FirstOrDefault(item => item.Tag.Id == deletedTag.id); - if (deletedTagItemVm is null) return; - this.SearchResults.Remove(deletedTagItemVm); + if (sender is not TagDatabaseService { IsDatabaseOpen: true }) return; + if (result.Deleted.Count == 0) return; + + foreach (var deletedTag in result.Deleted) + { + var deletedTagItemVm = this.SearchResults.FirstOrDefault(item => item.Tag.Id == deletedTag.id); + if (deletedTagItemVm is null) return; + this.SearchResults.Remove(deletedTagItemVm); + } + } } \ No newline at end of file -- 2.51.2