From 3f9d6bf78f2dd07437d8dac645c2f3ccec0b1c7a Mon Sep 17 00:00:00 2001 From: TheXamlGuy Date: Tue, 2 Jul 2024 23:38:52 +0100 Subject: [PATCH] Fixed perf issues --- Toolkit.Avalonia/ImageResizer.cs | 80 ++++++++++--------- Toolkit.Foundation/Activation.cs | 9 +++ Toolkit.Foundation/ActivationBuilder.cs | 3 + Toolkit.Foundation/ActivationEventArgs.cs | 7 ++ .../{ISynchronize.cs => IActivation.cs} | 2 +- Toolkit.Foundation/Observable.cs | 6 ++ Toolkit.Foundation/ObservableCollection.cs | 26 +++--- Toolkit.Foundation/Synchronize.cs | 9 --- Toolkit.Foundation/SynchronizeEventArgs.cs | 7 -- Toolkit.Foundation/SynchronizeExpression.cs | 3 - 10 files changed, 86 insertions(+), 66 deletions(-) create mode 100644 Toolkit.Foundation/Activation.cs create mode 100644 Toolkit.Foundation/ActivationBuilder.cs create mode 100644 Toolkit.Foundation/ActivationEventArgs.cs rename Toolkit.Foundation/{ISynchronize.cs => IActivation.cs} (53%) delete mode 100644 Toolkit.Foundation/Synchronize.cs delete mode 100644 Toolkit.Foundation/SynchronizeEventArgs.cs delete mode 100644 Toolkit.Foundation/SynchronizeExpression.cs diff --git a/Toolkit.Avalonia/ImageResizer.cs b/Toolkit.Avalonia/ImageResizer.cs index 3f62be8..fbfcfdd 100644 --- a/Toolkit.Avalonia/ImageResizer.cs +++ b/Toolkit.Avalonia/ImageResizer.cs @@ -6,48 +6,56 @@ namespace Toolkit.Avalonia; public class ImageResizer : IImageResizer { - public Bitmap Resize(Stream stream, - int targetWidth, - int targetHeight, + public Bitmap Resize(Stream stream, + int targetWidth, + int targetHeight, bool maintainAspectRatio) { - using SKBitmap original = SKBitmap.Decode(stream); + Bitmap bitmap = new(stream); - float widthRatio = (float)targetWidth / original.Width; - float heightRatio = (float)targetHeight / original.Height; - float scale = maintainAspectRatio ? Math.Max(widthRatio, heightRatio) : Math.Min(widthRatio, heightRatio); - - int newWidth = (int)(original.Width * scale); - int newHeight = (int)(original.Height * scale); - - using SKBitmap resized = new(newWidth, newHeight); - using SKCanvas canvas = new(resized); - - canvas.Clear(SKColors.Transparent); - canvas.DrawBitmap(original, new SKRect(0, 0, newWidth, newHeight)); - - SKBitmap cropped; - if (maintainAspectRatio) + if (bitmap.Size.Width != targetWidth || bitmap.Size.Height != targetHeight) { - int cropX = (newWidth - targetWidth) / 2; - int cropY = (newHeight - targetHeight) / 2; + using SKBitmap sKBitmap = SKBitmap.Decode(stream); + SKBitmap? cropped = null; + bitmap.Dispose(); - cropped = new SKBitmap(targetWidth, targetHeight); - using SKCanvas croppedCanvas = new(cropped); - SKRect cropRect = new(cropX, cropY, cropX + targetWidth, cropY + targetHeight); - croppedCanvas.Clear(SKColors.Transparent); - croppedCanvas.DrawBitmap(resized, cropRect, new SKRect(0, 0, targetWidth, targetHeight)); - } - else - { - cropped = resized; + float widthRatio = (float)targetWidth / sKBitmap.Width; + float heightRatio = (float)targetHeight / sKBitmap.Height; + float scale = maintainAspectRatio ? Math.Max(widthRatio, heightRatio) : Math.Min(widthRatio, heightRatio); + + int newWidth = (int)(sKBitmap.Width * scale); + int newHeight = (int)(sKBitmap.Height * scale); + + using SKBitmap resized = new(newWidth, newHeight); + using SKCanvas canvas = new(resized); + + canvas.Clear(SKColors.Transparent); + canvas.DrawBitmap(sKBitmap, new SKRect(0, 0, newWidth, newHeight)); + + if (maintainAspectRatio) + { + int cropX = (newWidth - targetWidth) / 2; + int cropY = (newHeight - targetHeight) / 2; + + cropped = new SKBitmap(targetWidth, targetHeight); + using SKCanvas croppedCanvas = new(cropped); + SKRect cropRect = new(cropX, cropY, cropX + targetWidth, cropY + targetHeight); + croppedCanvas.Clear(SKColors.Transparent); + croppedCanvas.DrawBitmap(resized, cropRect, new SKRect(0, 0, targetWidth, targetHeight)); + } + else + { + cropped = resized; + } + + using SKImage image = SKImage.FromBitmap(cropped); + using MemoryStream outputStream = new(); + image.Encode(SKEncodedImageFormat.Png, 100).SaveTo(outputStream); + outputStream.Seek(0, SeekOrigin.Begin); + + return new Bitmap(outputStream); } - using SKImage image = SKImage.FromBitmap(cropped); - using MemoryStream outputStream = new(); - image.Encode(SKEncodedImageFormat.Png, 100).SaveTo(outputStream); - outputStream.Seek(0, SeekOrigin.Begin); - - return new Bitmap(outputStream); + return bitmap; } } \ No newline at end of file diff --git a/Toolkit.Foundation/Activation.cs b/Toolkit.Foundation/Activation.cs new file mode 100644 index 0000000..bcec601 --- /dev/null +++ b/Toolkit.Foundation/Activation.cs @@ -0,0 +1,9 @@ +namespace Toolkit.Foundation; + +public record Activation +{ + public static ActivationEventArgs As(TValue value) => new(value); + + public static ActivationEventArgs As() => + new(); +} diff --git a/Toolkit.Foundation/ActivationBuilder.cs b/Toolkit.Foundation/ActivationBuilder.cs new file mode 100644 index 0000000..deb8498 --- /dev/null +++ b/Toolkit.Foundation/ActivationBuilder.cs @@ -0,0 +1,3 @@ +namespace Toolkit.Foundation; + +public record ActivationBuilder(IActivation Value, object? Key = null); diff --git a/Toolkit.Foundation/ActivationEventArgs.cs b/Toolkit.Foundation/ActivationEventArgs.cs new file mode 100644 index 0000000..a13d81d --- /dev/null +++ b/Toolkit.Foundation/ActivationEventArgs.cs @@ -0,0 +1,7 @@ +namespace Toolkit.Foundation; + +public record ActivationEventArgs(TValue? Value = default) : + IActivation; + +public record ActivationEventArgs() : + IActivation; \ No newline at end of file diff --git a/Toolkit.Foundation/ISynchronize.cs b/Toolkit.Foundation/IActivation.cs similarity index 53% rename from Toolkit.Foundation/ISynchronize.cs rename to Toolkit.Foundation/IActivation.cs index b75dcb4..26c23c8 100644 --- a/Toolkit.Foundation/ISynchronize.cs +++ b/Toolkit.Foundation/IActivation.cs @@ -1,3 +1,3 @@ namespace Toolkit.Foundation; -public interface ISynchronize; \ No newline at end of file +public interface IActivation; \ No newline at end of file diff --git a/Toolkit.Foundation/Observable.cs b/Toolkit.Foundation/Observable.cs index 38ee961..d399959 100644 --- a/Toolkit.Foundation/Observable.cs +++ b/Toolkit.Foundation/Observable.cs @@ -74,6 +74,11 @@ public partial class Observable(IServiceProvider provider, Disposer.Dispose(this); } + public virtual void OnInitialize() + { + + } + public virtual void Initialize() { if (IsInitialized) @@ -83,6 +88,7 @@ public partial class Observable(IServiceProvider provider, IsInitialized = true; Subscriber.Subscribe(this); + OnInitialize(); } public void Revert() diff --git a/Toolkit.Foundation/ObservableCollection.cs b/Toolkit.Foundation/ObservableCollection.cs index aadb608..b9ca223 100644 --- a/Toolkit.Foundation/ObservableCollection.cs +++ b/Toolkit.Foundation/ObservableCollection.cs @@ -266,7 +266,7 @@ public partial class ObservableCollection : Disposer.Dispose(this); } - public void Fetch(Func aggregateDelegate, + public void Activate(Func aggregateDelegate, bool reset = false) { if (reset) @@ -274,8 +274,8 @@ public partial class ObservableCollection : Clear(); } - SynchronizeExpression expression = aggregateDelegate.Invoke(); - Publisher.PublishUI(expression.Value, expression.Key); + ActivationBuilder expression = aggregateDelegate.Invoke(); + Publisher.Publish(expression.Value, expression.Key); } public IEnumerator GetEnumerator() => @@ -415,6 +415,11 @@ public partial class ObservableCollection : IsCompatibleObject(value) ? IndexOf((TItem)value!) : -1; + public virtual void OnInitialize() + { + + } + public virtual void Initialize() { if (IsInitialized) @@ -423,9 +428,10 @@ public partial class ObservableCollection : } IsInitialized = true; - Subscriber.Subscribe(this); - Synchronize(); + OnInitialize(); + + Activate(); } public TItem Insert(int index = 0, @@ -570,15 +576,15 @@ public partial class ObservableCollection : } } - public void Synchronize(bool reset = false) + public void Activate(bool reset = false) { if (reset) { Clear(); } - SynchronizeExpression expression = BuildAggregateExpression(); - Publisher.PublishUI(expression.Value, expression.Key); + ActivationBuilder builder = ActivationBuilder(); + Publisher.PublishUI(builder.Value, builder.Key); } public void Track(string propertyName, Func getter, Action setter) @@ -590,8 +596,8 @@ public partial class ObservableCollection : } } - protected virtual SynchronizeExpression BuildAggregateExpression() => - new(new SynchronizeEventArgs()); + protected virtual ActivationBuilder ActivationBuilder() => + new(new ActivationEventArgs()); protected virtual void ClearItems() => collection.Clear(); diff --git a/Toolkit.Foundation/Synchronize.cs b/Toolkit.Foundation/Synchronize.cs deleted file mode 100644 index 5de0d4d..0000000 --- a/Toolkit.Foundation/Synchronize.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Toolkit.Foundation; - -public record Synchronize -{ - public static SynchronizeEventArgs As(TOptions options) => new(options); - - public static SynchronizeEventArgs As() => - new(); -} diff --git a/Toolkit.Foundation/SynchronizeEventArgs.cs b/Toolkit.Foundation/SynchronizeEventArgs.cs deleted file mode 100644 index 909575e..0000000 --- a/Toolkit.Foundation/SynchronizeEventArgs.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Toolkit.Foundation; - -public record SynchronizeEventArgs(TValue? Value = default) : - ISynchronize; - -public record SynchronizeEventArgs() : - ISynchronize; \ No newline at end of file diff --git a/Toolkit.Foundation/SynchronizeExpression.cs b/Toolkit.Foundation/SynchronizeExpression.cs deleted file mode 100644 index a3106aa..0000000 --- a/Toolkit.Foundation/SynchronizeExpression.cs +++ /dev/null @@ -1,3 +0,0 @@ -namespace Toolkit.Foundation; - -public record SynchronizeExpression(ISynchronize Value, object? Key = null);