public PatcherRunVM(PatchersRunVM parent, PatcherVM config, IPatcherRun run) { Run = run; Config = config; _IsSelected = parent.WhenAnyValue(x => x.SelectedPatcher) .Select(x => x == this) .ToGuiProperty(this, nameof(IsSelected)); OutputLineDisplay = Observable.Merge( run.Output, run.Error, this.WhenAnyValue(x => x.State) .Where(x => x.Value == RunState.Error) .Select(x => x.Reason)) .ToObservableChangeSet() .Buffer(TimeSpan.FromMilliseconds(250), RxApp.TaskpoolScheduler) .Where(l => l.Count > 0) .FlattenBufferResult() .ToObservableCollection(this); _IsRunning = this.WhenAnyValue(x => x.State) .Select(x => x.Value == RunState.Started) .ToGuiProperty(this, nameof(IsRunning)); _IsErrored = this.WhenAnyValue(x => x.State) .Select(x => x.Value == RunState.Error) .ToGuiProperty(this, nameof(IsErrored)); var runTime = Noggog.ObservableExt.TimePassed(TimeSpan.FromMilliseconds(100), RxApp.MainThreadScheduler) .FilterSwitch(this.WhenAnyValue(x => x.IsRunning)) .Publish() .RefCount(); _RunTime = runTime .ToProperty(this, nameof(RunTime)); _RunTimeString = runTime .Select(time => { if (time.TotalDays > 1) { return($"{time.TotalDays:n1}d"); } if (time.TotalHours > 1) { return($"{time.TotalHours:n1}h"); } if (time.TotalMinutes > 1) { return($"{time.TotalMinutes:n1}m"); } return($"{time.TotalSeconds:n1}s"); }) .ToGuiProperty <string>(this, nameof(RunTimeString), string.Empty); }
public PatcherRunVM(PatchersRunVM parent, PatcherVM config, IPatcherRun run) { Run = run; Config = config; _IsSelected = parent.WhenAnyValue(x => x.SelectedPatcher) .Select(x => x == this) .ToGuiProperty(this, nameof(IsSelected)); Observable.Merge( run.Output, run.Error, this.WhenAnyValue(x => x.State) .Where(x => x.Value == RunState.Error) .Select(x => x.Reason)) .Buffer(TimeSpan.FromMilliseconds(250), count: 1000, RxApp.TaskpoolScheduler) .Where(b => b.Count > 0) .ObserveOnGui() .Subscribe(output => { StringBuilder sb = new(); foreach (var line in output) { sb.AppendLine(line); } OutputDisplay.Insert(OutputDisplay.TextLength, sb.ToString()); }) .DisposeWith(this); _IsRunning = this.WhenAnyValue(x => x.State) .Select(x => x.Value == RunState.Started) .ToGuiProperty(this, nameof(IsRunning)); _IsErrored = this.WhenAnyValue(x => x.State) .Select(x => x.Value == RunState.Error) .ToGuiProperty(this, nameof(IsErrored)); var runTime = Noggog.ObservableExt.TimePassed(TimeSpan.FromMilliseconds(100), RxApp.MainThreadScheduler) .FilterSwitch(this.WhenAnyValue(x => x.IsRunning)) .Publish() .RefCount(); _RunTime = runTime .ToProperty(this, nameof(RunTime)); _RunTimeString = runTime .Select(time => { if (time.TotalDays > 1) { return($"{time.TotalDays:n1}d"); } if (time.TotalHours > 1) { return($"{time.TotalHours:n1}h"); } if (time.TotalMinutes > 1) { return($"{time.TotalMinutes:n1}m"); } return($"{time.TotalSeconds:n1}s"); }) .ToGuiProperty <string>(this, nameof(RunTimeString), string.Empty); this.WhenAnyValue(x => x.State) .Where(x => x.Succeeded && x.Value == RunState.Finished) .Subscribe(_ => config.SuccessfulRunCompleted()) .DisposeWith(this); }
public PatcherSettingsVM( ILogger logger, PatcherVM parent, IObservable <GetResponse <string> > projPath, bool needBuild) { Logger = logger; _SettingsConfiguration = projPath .Select(i => { return(Observable.Create <SettingsConfiguration>(async(observer, cancel) => { observer.OnNext(new SettingsConfiguration(SettingsStyle.None, Array.Empty <ReflectionSettingsConfig >())); if (i.Failed) { return; } try { var result = await Synthesis.Bethesda.Execution.CLI.Commands.GetSettingsStyle( i.Value, directExe: false, cancel: cancel, build: needBuild, logger.Information); logger.Information($"Settings type: {result}"); observer.OnNext(result); } catch (Exception ex) { Logger.Error($"Error checking if patcher can open settings: {ex}"); } observer.OnCompleted(); })); }) .Switch() .ToGuiProperty(this, nameof(SettingsConfiguration), new SettingsConfiguration(SettingsStyle.None, Array.Empty <ReflectionSettingsConfig>())); OpenSettingsCommand = NoggogCommand.CreateFromObject( objectSource: projPath, canExecute: x => x.Succeeded, extraCanExecute: this.WhenAnyValue(x => x.SettingsConfiguration) .Select(x => x.Style == SettingsStyle.Open), execute: async(o) => { var result = await Synthesis.Bethesda.Execution.CLI.Commands.OpenForSettings( o.Value, directExe: false, rect: parent.Profile.Config.MainVM.Rectangle, cancel: CancellationToken.None, release: parent.Profile.Release, dataFolderPath: parent.Profile.DataFolder, loadOrder: parent.Profile.LoadOrder.Items.Select(lvm => lvm.Listing)); }, disposable: this.CompositeDisposable); _SettingsOpen = OpenSettingsCommand.IsExecuting .ToGuiProperty(this, nameof(SettingsOpen)); _ReflectionSettings = Observable.CombineLatest( this.WhenAnyValue(x => x.SettingsConfiguration), projPath, (SettingsConfig, ProjPath) => (SettingsConfig, ProjPath)) .Select(x => { if (x.ProjPath.Failed || x.SettingsConfig.Style != SettingsStyle.SpecifiedClass || x.SettingsConfig.Targets.Length == 0) { return(default(AutogeneratedSettingsVM?)); } return(new AutogeneratedSettingsVM( x.SettingsConfig, projPath: x.ProjPath.Value, displayName: parent.DisplayName, loadOrder: parent.Profile.LoadOrder.Connect(), linkCache: parent.Profile.SimpleLinkCache, log: Log.Logger.Information)); }) .ToGuiProperty <AutogeneratedSettingsVM?>(this, nameof(ReflectionSettings), initialValue: null, deferSubscription: true); }
public PatcherSettingsVM( ILogger logger, PatcherVM parent, IObservable <(GetResponse <string> ProjPath, string?SynthVersion)> source,
public PatcherSettingsVM( ILogger logger, PatcherVM parent, IObservable <GetResponse <string> > projPath, bool needBuild) { Logger = logger; _SettingsConfiguration = projPath .Select(i => { return(Observable.Create <SettingsConfiguration>(async(observer, cancel) => { observer.OnNext(new SettingsConfiguration(SettingsStyle.None, Array.Empty <ReflectionSettingsConfig >())); if (i.Failed) { return; } try { var result = await Synthesis.Bethesda.Execution.CLI.Commands.GetSettingsStyle( i.Value, directExe: false, cancel: cancel, build: needBuild); observer.OnNext(result); } catch (Exception ex) { Logger.Error($"Error checking if patcher can open settings: {ex}"); } observer.OnCompleted(); })); }) .Switch() .ToGuiProperty(this, nameof(SettingsConfiguration), new SettingsConfiguration(SettingsStyle.None, Array.Empty <ReflectionSettingsConfig>())); OpenSettingsCommand = NoggogCommand.CreateFromObject( objectSource: projPath, canExecute: x => x.Succeeded, extraCanExecute: this.WhenAnyValue(x => x.SettingsConfiguration) .Select(x => x.Style == SettingsStyle.Open), execute: async(o) => { var result = await Synthesis.Bethesda.Execution.CLI.Commands.OpenForSettings( o.Value, directExe: false, rect: parent.Profile.Config.MainVM.Rectangle, cancel: CancellationToken.None); }, disposable: this.CompositeDisposable); _SettingsOpen = OpenSettingsCommand.IsExecuting .ToGuiProperty(this, nameof(SettingsOpen)); var targetSettingsVM = Observable.CombineLatest( this.WhenAnyValue(x => x.SettingsConfiguration), projPath, (settingsTarget, projPath) => (settingsTarget, projPath)) .ObserveOn(RxApp.TaskpoolScheduler) .Select(i => { return(Observable.Create <(bool Processing, GetResponse <ReflectionSettingsVM[]> SettingsVM)>(async(observer, cancel) => { if (i.projPath.Failed || i.settingsTarget.Style != SettingsStyle.SpecifiedClass || i.settingsTarget.Targets.Length == 0) { observer.OnNext((false, GetResponse <ReflectionSettingsVM[]> .Succeed(Array.Empty <ReflectionSettingsVM>()))); return; } observer.OnNext((true, Array.Empty <ReflectionSettingsVM>())); try { var vms = await Utility.ExtractInfoFromProject <ReflectionSettingsVM[]>( projPath: i.projPath.Value, cancel: cancel, getter: (assemb) => { return i.settingsTarget.Targets .Select((s, index) => { var t = assemb.GetType(s.TypeName); if (t == null) { return null; } return new ReflectionSettingsVM( new SettingsParameters(assemb, parent.Profile.LoadOrder.Connect(), parent.Profile.SimpleLinkCache), t, nickname: i.settingsTarget.Targets[index].Nickname, settingsFolder: Path.Combine(Execution.Paths.TypicalExtraData, parent.DisplayName), settingsSubPath: i.settingsTarget.Targets[index].Path); }) .NotNull() .ToArray(); }); if (vms.Failed) { Logger.Error($"Error creating reflection GUI: {vms.Reason}"); observer.OnNext((false, vms.BubbleFailure <ReflectionSettingsVM[]>())); return; } await Task.WhenAll(vms.Value.Select(vm => vm.Import(logger, cancel))); observer.OnNext((false, vms.Value)); } catch (Exception ex) { Logger.Error($"Error creating reflection GUI: {ex}"); observer.OnNext((false, GetResponse <ReflectionSettingsVM[]> .Fail(ex))); } observer.OnCompleted(); })); }) .Switch() .Replay(1) .RefCount(); _SettingsLoading = targetSettingsVM .Select(t => t.Processing) .ToGuiProperty(this, nameof(SettingsLoading), deferSubscription: true); _reflectionSettings = new Lazy <IObservableCollection <ReflectionSettingsVM> >(() => { return(targetSettingsVM .Select(x => { if (x.Processing || x.SettingsVM.Failed) { return Enumerable.Empty <ReflectionSettingsVM>(); } return x.SettingsVM.Value; }) .ObserveOnGui() .Select(x => { SelectedSettings = x.FirstOrDefault(); return x.AsObservableChangeSet(x => (StringCaseAgnostic)x.SettingsSubPath); }) .Switch() .ToObservableCollection(this.CompositeDisposable)); }, isThreadSafe: true); _Error = targetSettingsVM .Select(x => (ErrorResponse)x.SettingsVM) .ToGuiProperty(this, nameof(Error), deferSubscription: true); }