using System.Reactive.Linq; using System.Reactive.Subjects; using System.Reactive.Threading.Tasks; using CliWrap; namespace InnovEnergy.Lib.Utils.WIP; using Data = IReadOnlyList; public class ObservableProcess { private readonly Command _Command; private readonly CancellationTokenSource _Kill = new CancellationTokenSource(); private readonly CancellationTokenSource _Interrupt = new CancellationTokenSource(); private readonly ObserverPipeSource _StdIn = new ObserverPipeSource(); private readonly ReadablePipeTarget _StdOut = new ReadablePipeTarget(); private readonly ReadablePipeTarget _StdErr = new ReadablePipeTarget(); public IObserver StdIn => _StdIn; private readonly Subject _Pid = new Subject(); private readonly Subject _ExitCode = new Subject(); public Task Pid { get; } public Task ExitCode { get; } public Task Read(Int32 nBytes) => _StdOut.Read(nBytes); public ObservableProcess(Command command) { _Command = command; Pid = _Pid.ToTask(); ExitCode = _ExitCode.ToTask(); } public void Start() { var commandTask = _Command .WithStandardInputPipe(_StdIn) .WithStandardOutputPipe(_StdOut) .WithStandardErrorPipe(_StdErr) .ExecuteAsync(_Kill.Token, _Interrupt.Token); _Pid.OnNext(commandTask.ProcessId); commandTask.Task .ToObservable() .Select(t => t.ExitCode) .Subscribe(_ExitCode); } public void Kill() => _Kill.Cancel(); public void Interrupt() => _Interrupt.Cancel(); }