From 2eb9ca99e9153434d7b229556a8e2f8d62746822 Mon Sep 17 00:00:00 2001 From: Ionite Date: Sun, 10 Sep 2023 21:00:54 -0400 Subject: [PATCH] Fix cached image appearing after deletion --- .../FallbackRamCachedWebImageLoader.cs | 21 +++++- .../Inference/ImageFolderCardViewModel.cs | 5 +- .../Extensions/ObjectExtensions.cs | 68 ++++++++++++------- 3 files changed, 65 insertions(+), 29 deletions(-) diff --git a/StabilityMatrix.Avalonia/FallbackRamCachedWebImageLoader.cs b/StabilityMatrix.Avalonia/FallbackRamCachedWebImageLoader.cs index 9dbe6ef9..f8ae8235 100644 --- a/StabilityMatrix.Avalonia/FallbackRamCachedWebImageLoader.cs +++ b/StabilityMatrix.Avalonia/FallbackRamCachedWebImageLoader.cs @@ -75,12 +75,27 @@ public class FallbackRamCachedWebImageLoader : RamCachedWebImageLoader } } - public void RemoveFromCache(string url) + public void RemovePathFromCache(string filePath) { - // ConcurrentDictionary> _memoryCache var cache = this.GetPrivateField>>("_memoryCache") ?? throw new NullReferenceException("Memory cache not found"); - cache.TryRemove(url, out _); + + cache.TryRemove(filePath, out _); + } + + public void RemoveAllNamesFromCache(string fileName) + { + var cache = + this.GetPrivateField>>("_memoryCache") + ?? throw new NullReferenceException("Memory cache not found"); + + foreach (var (key, _) in cache) + { + if (Path.GetFileName(key) == fileName) + { + cache.TryRemove(key, out _); + } + } } } diff --git a/StabilityMatrix.Avalonia/ViewModels/Inference/ImageFolderCardViewModel.cs b/StabilityMatrix.Avalonia/ViewModels/Inference/ImageFolderCardViewModel.cs index 3ef00b3b..cdbd9642 100644 --- a/StabilityMatrix.Avalonia/ViewModels/Inference/ImageFolderCardViewModel.cs +++ b/StabilityMatrix.Avalonia/ViewModels/Inference/ImageFolderCardViewModel.cs @@ -133,7 +133,8 @@ public partial class ImageFolderCardViewModel : ViewModelBase } // Delete the file - var result = await notificationService.TryAsync(new FilePath(imagePath).DeleteAsync()); + var imageFile = new FilePath(imagePath); + var result = await notificationService.TryAsync(imageFile.DeleteAsync()); if (!result.IsSuccessful) { @@ -149,7 +150,7 @@ public partial class ImageFolderCardViewModel : ViewModelBase // Invalidate cache if (ImageLoader.AsyncImageLoader is FallbackRamCachedWebImageLoader loader) { - loader.RemoveFromCache(imagePath); + loader.RemoveAllNamesFromCache(imageFile.Name); } } diff --git a/StabilityMatrix.Core/Extensions/ObjectExtensions.cs b/StabilityMatrix.Core/Extensions/ObjectExtensions.cs index af9668b2..9cbd9923 100644 --- a/StabilityMatrix.Core/Extensions/ObjectExtensions.cs +++ b/StabilityMatrix.Core/Extensions/ObjectExtensions.cs @@ -3,19 +3,24 @@ using RockLib.Reflection.Optimized; namespace StabilityMatrix.Core.Extensions; - public static class ObjectExtensions { /// /// Cache of Types to named field getters /// - private static readonly Dictionary>> FieldGetterTypeCache = new(); - + private static readonly Dictionary< + Type, + Dictionary> + > FieldGetterTypeCache = new(); + /// /// Cache of Types to named field setters /// - private static readonly Dictionary>> FieldSetterTypeCache = new(); - + private static readonly Dictionary< + Type, + Dictionary> + > FieldSetterTypeCache = new(); + /// /// Get the value of a named private field from an object /// @@ -27,22 +32,29 @@ public static class ObjectExtensions if (!fieldGetterCache.TryGetValue(fieldName, out var fieldGetter)) { // Get the field - var field = obj.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic); + var field = obj.GetType() + .GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic); + // Try get from parent + field ??= obj.GetType() + .BaseType?.GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic); + if (field is null) { - throw new ArgumentException($"Field {fieldName} not found on type {obj.GetType().Name}"); + throw new ArgumentException( + $"Field {fieldName} not found on type {obj.GetType().Name}" + ); } - + // Create a getter for the field fieldGetter = field.CreateGetter(); - + // Add to cache fieldGetterCache.Add(fieldName, fieldGetter); } - return (T?) fieldGetter(obj); + return (T?)fieldGetter(obj); } - + /// /// Set the value of a named private field on an object /// @@ -54,25 +66,29 @@ public static class ObjectExtensions if (!fieldSetterCache.TryGetValue(fieldName, out var fieldSetter)) { // Get the field - var field = obj.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic); + var field = obj.GetType() + .GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic); // Try get from parent - field ??= obj.GetType().BaseType?.GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic); - + field ??= obj.GetType() + .BaseType?.GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic); + if (field is null) { - throw new ArgumentException($"Field {fieldName} not found on type {obj.GetType().Name}"); + throw new ArgumentException( + $"Field {fieldName} not found on type {obj.GetType().Name}" + ); } - + // Create a setter for the field fieldSetter = field.CreateSetter(); - + // Add to cache fieldSetterCache.Add(fieldName, fieldSetter); } fieldSetter(obj, value); } - + /// /// Set the value of a named private field on an object /// @@ -84,18 +100,22 @@ public static class ObjectExtensions if (!fieldSetterCache.TryGetValue(fieldName, out var fieldSetter)) { // Get the field - var field = obj.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic); + var field = obj.GetType() + .GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic); // Try get from parent - field ??= obj.GetType().BaseType?.GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic); - + field ??= obj.GetType() + .BaseType?.GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic); + if (field is null) { - throw new ArgumentException($"Field {fieldName} not found on type {obj.GetType().Name}"); + throw new ArgumentException( + $"Field {fieldName} not found on type {obj.GetType().Name}" + ); } - + // Create a setter for the field fieldSetter = field.CreateSetter(); - + // Add to cache fieldSetterCache.Add(fieldName, fieldSetter); }