From 36b9343269d10497ea5adb39911543616a17f08e Mon Sep 17 00:00:00 2001 From: unclshura Date: Sun, 21 Jun 2026 13:16:40 +0100 Subject: [PATCH] Compact observable property wrapper forwarder --- Splitter-UI/Controls/PreviewSlider.cs | 3 +- Splitter-UI/Program.cs | 1 + Splitter-UI/ViewModels/JobViewModel.cs | 165 ++----------------- Splitter-UI/ViewModels/ViewModelForwarder.cs | 34 ++++ splitter-cli/DebugOverlay.cs | 6 +- splitter-cli/algo/IdentityCache.cs | 6 +- 6 files changed, 54 insertions(+), 161 deletions(-) create mode 100644 Splitter-UI/ViewModels/ViewModelForwarder.cs diff --git a/Splitter-UI/Controls/PreviewSlider.cs b/Splitter-UI/Controls/PreviewSlider.cs index f9a4604..401259f 100644 --- a/Splitter-UI/Controls/PreviewSlider.cs +++ b/Splitter-UI/Controls/PreviewSlider.cs @@ -1,5 +1,4 @@ -using System; -using Avalonia; +using Avalonia; using Avalonia.Controls; using Avalonia.Input; using Avalonia.Interactivity; diff --git a/Splitter-UI/Program.cs b/Splitter-UI/Program.cs index 2d7633a..71bc897 100644 --- a/Splitter-UI/Program.cs +++ b/Splitter-UI/Program.cs @@ -34,6 +34,7 @@ internal sealed class Program // splitter services services.AddSingleton(); services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); diff --git a/Splitter-UI/ViewModels/JobViewModel.cs b/Splitter-UI/ViewModels/JobViewModel.cs index f65ca28..3e18b11 100644 --- a/Splitter-UI/ViewModels/JobViewModel.cs +++ b/Splitter-UI/ViewModels/JobViewModel.cs @@ -10,7 +10,8 @@ namespace Splitter_UI.ViewModels; public partial class JobViewModel : ObservableObject { - private SingleJob Job { get; } + private SingleJob Job => _f.Model; + private ViewModelForwarder _f; public SingleJob GetJob() => Job; @@ -128,115 +129,6 @@ public partial class JobViewModel : ObservableObject } } - public string? Detect - { - get => Job.Detect; - set - { - if (Job.Detect == value) - return; - Job.Detect = value; - OnPropertyChanged(); - } - } - - public float ScoreThreshold - { - get => Job.ScoreThreshold; - set - { - if (Math.Abs(Job.ScoreThreshold - value) < 0.001) - return; - Job.ScoreThreshold = value; - OnPropertyChanged(); - Task.Run(CreatePreview); - } - } - - public float IdentityThreshold - { - get => Job.IdentityThreshold; - set - { - if (Math.Abs(Job.IdentityThreshold - value) < 0.001) - return; - Job.IdentityThreshold = value; - OnPropertyChanged(); - Task.Run(CreatePreview); - } - } - - public string? Mask - { - get => Job.Mask; - set - { - if (Job.Mask == value) - return; - Job.Mask = value; - OnPropertyChanged(); - } - } - - public string OutputFolder - { - get => Job.OutputFolder; - set - { - if (Job.OutputFolder == value) - return; - Job.OutputFolder = value; - OnPropertyChanged(); - } - } - - public bool ForceFixed - { - get => Job.ForceFixed; - set - { - if (Job.ForceFixed == value) - return; - Job.ForceFixed = value; - OnPropertyChanged(); - } - } - - public bool Debug - { - get => Job.Debug; - set - { - if (Job.Debug == value) - return; - Job.Debug = value; - OnPropertyChanged(); - } - } - - public bool Enhance - { - get => Job.Enhance; - set - { - if (Job.Enhance == value) - return; - Job.Enhance = value; - OnPropertyChanged(); - } - } - - public int? Rotate - { - get => Job.Rotate; - set - { - Job.Rotate = value; - OnPropertyChanged(); - Task.Run(CreatePreview); - } - } - public Point2f GravitateTo { get => Job.GravitateTo; @@ -251,49 +143,24 @@ public partial class JobViewModel : ObservableObject } } - public float DetectAbove - { - get => Job.DetectAbove; - set - { - if (Math.Abs(Job.DetectAbove - value) < 0.001 ) - return; - Job.DetectAbove = value; - OnPropertyChanged(); - Task.Run(CreatePreview); - } - } - - public ulong? DetectId - { - get => Job.DetectId; - set - { - if (DetectId == value) - return; - Job.DetectId = value; - OnPropertyChanged(); - Task.Run(CreatePreview); - } - } - - public double? OverrideTargetDuration - { - get => Job.OverrideTargetDuration; - set - { - if (Job.OverrideTargetDuration != null && value != null && Math.Abs(Job.OverrideTargetDuration.Value - value.Value) < 0.01) - return; - Job.OverrideTargetDuration = value; - OnPropertyChanged(); - } - } + public string? Detect { get => Job.Detect; set => _f.Forward(value); } + public string? Mask { get => Job.Mask; set => _f.Forward(value); } + public string OutputFolder { get => Job.OutputFolder; set => _f.Forward(value); } + public bool ForceFixed { get => Job.ForceFixed; set => _f.Forward(value); } + public bool Debug { get => Job.Debug; set => _f.Forward(value); } + public bool Enhance { get => Job.Enhance; set => _f.Forward(value); } + public double? OverrideTargetDuration { get => Job.OverrideTargetDuration; set => _f.Forward(value); } + public float ScoreThreshold { get => Job.ScoreThreshold; set { _f.Forward(value); Task.Run(CreatePreview); } } + public float IdentityThreshold { get => Job.IdentityThreshold; set { _f.Forward(value); Task.Run(CreatePreview); } } + public int? Rotate { get => Job.Rotate; set { _f.Forward(value); Task.Run(CreatePreview); } } + public float DetectAbove { get => Job.DetectAbove; set { _f.Forward(value); Task.Run(CreatePreview); } } + public ulong? DetectId { get => Job.DetectId; set { _f.Forward(value); Task.Run(CreatePreview); } } public JobViewModel(SingleJob job, IThumbnailService thumbnails, Func trackerFactory, ILogger log) { - Job = job; + _f = new ViewModelForwarder(job, this.OnPropertyChanged); _thumbnails = thumbnails; - _trackerFactory = trackerFactory; + _trackerFactory = trackerFactory; _log = log; ParametersList.Add(new ParameterEntry("DropoutToleranceFrames" , "")); diff --git a/Splitter-UI/ViewModels/ViewModelForwarder.cs b/Splitter-UI/ViewModels/ViewModelForwarder.cs new file mode 100644 index 0000000..950b048 --- /dev/null +++ b/Splitter-UI/ViewModels/ViewModelForwarder.cs @@ -0,0 +1,34 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +namespace Splitter_UI.ViewModels; + +internal class ViewModelForwarder +{ + public readonly TModel Model; + private readonly Action _onPropertyChanged; + + public ViewModelForwarder(TModel model, Action onPropertyChanged) + { + Model = model; + _onPropertyChanged = onPropertyChanged; + } + + public void Forward( + T newValue, + [CallerMemberName] string? propertyName = null) + { + var modelType = typeof(TModel); + var prop = modelType.GetProperty(propertyName!, BindingFlags.Public | BindingFlags.Instance); + if (prop == null) + return; + + var oldValue = (T)prop.GetValue(Model)!; + + if (EqualityComparer.Default.Equals(oldValue, newValue)) + return; + + prop.SetValue(Model, newValue); + _onPropertyChanged(propertyName!); + } +} \ No newline at end of file diff --git a/splitter-cli/DebugOverlay.cs b/splitter-cli/DebugOverlay.cs index 4296ea5..ea28ce6 100644 --- a/splitter-cli/DebugOverlay.cs +++ b/splitter-cli/DebugOverlay.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace splitter; +namespace splitter; public static class DebugOverlay { diff --git a/splitter-cli/algo/IdentityCache.cs b/splitter-cli/algo/IdentityCache.cs index 4444afe..c03252b 100644 --- a/splitter-cli/algo/IdentityCache.cs +++ b/splitter-cli/algo/IdentityCache.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace splitter.algo; +namespace splitter.algo; public sealed class IdentityCache {