namespace Automata.Screen; public class FramePipeline : IDisposable { private readonly IScreenCapture _capture; private readonly List _consumers = []; public FramePipeline(IScreenCapture capture) { _capture = capture; } public IScreenCapture Capture => _capture; public void AddConsumer(IFrameConsumer consumer) => _consumers.Add(consumer); public void RemoveConsumer(IFrameConsumer consumer) => _consumers.Remove(consumer); /// /// Capture one frame, dispatch to all consumers in parallel, then dispose frame. /// public async Task ProcessOneFrame() { using var frame = _capture.CaptureFrame(); if (frame == null) return; if (_consumers.Count == 1) { _consumers[0].Process(frame); } else { var tasks = _consumers.Select(c => Task.Run(() => c.Process(frame))); await Task.WhenAll(tasks); } } public void Dispose() => _capture.Dispose(); }