using Avalar.Services; using Avalonia.Media.Imaging; using ReactiveUI; using System; using System.ComponentModel; using System.Threading; using System.Threading.Tasks; namespace Avalar.Models { public class PipelineStep : IPipelineStep where T : INotifyPropertyChanged, IProcessor { public PipelineStep(T processor) { m_Processor = processor ?? throw new ArgumentNullException(nameof(processor)); m_Processor.PropertyChanged += OnPropertyChanged; } private void OnPropertyChanged(object sender, PropertyChangedEventArgs e) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Result))); } public void InvalidateResult() { Result = null; } private T m_Processor; public event PropertyChangedEventHandler PropertyChanged; private IBitmap Result { get; set; } public Task Run(IBitmap bitmap, CancellationToken token) { if (Result != null) { return Task.FromResult(Result); } else { return Task.Run(() => { Result = m_Processor.Process(bitmap, token); token.ThrowIfCancellationRequested(); return Result; }); } } } public static class PipelineStep { public static PipelineStep Create(T processor) where T : INotifyPropertyChanged, IProcessor { return new PipelineStep(processor); } public static PipelineStep AsPipelineStep(this T processor) where T : INotifyPropertyChanged, IProcessor { return Create(processor); } } }