public ErrorVM(string title, string?str = null, Action?backAction = null) { Title = title; String = str; BackAction = backAction; BackCommand = NoggogCommand.CreateFromObject( objectSource: this.WhenAnyValue(x => x.BackAction), canExecute: x => x != null, execute: x => { x?.Invoke(); }, disposable: this.CompositeDisposable); // Go back automatically if things no longer apply this.WhenAnyValue(x => x.String) .DistinctUntilChanged() .Where(x => x.IsNullOrWhitespace()) .Subscribe(_ => { BackAction?.Invoke(); }) .DisposeWith(this); }
public MainVM(Window window) { _window = window; var dotNet = Observable.Interval(TimeSpan.FromSeconds(10), RxApp.TaskpoolScheduler) .StartWith(0) .SelectTask(async i => { try { var ret = await DotNetCommands.DotNetSdkVersion(CancellationToken.None); Log.Logger.Information($"dotnet SDK: {ret}"); return(ret); } catch (Exception ex) { Log.Logger.Error(ex, $"Error retrieving dotnet SDK version"); return(default(Version?)); } }); DotNetSdkInstalled = dotNet .Take(1) .Merge(dotNet .FirstAsync(v => v != null)) .DistinctUntilChanged() .Replay(1) .RefCount(); Configuration = new ConfigurationVM(this); ActivePanel = Configuration; DiscardActionCommand = NoggogCommand.CreateFromObject( objectSource: this.WhenAnyValue(x => x.TargetConfirmation), canExecute: target => target != null, execute: (_) => { TargetConfirmation = null; }, disposable: this.CompositeDisposable); ConfirmActionCommand = NoggogCommand.CreateFromObject( objectSource: this.WhenAnyFallback(x => x.TargetConfirmation !.ToDo), canExecute: toDo => toDo != null, execute: toDo => { toDo?.Invoke(); TargetConfirmation = null; }, disposable: this.CompositeDisposable); _Hot = this.WhenAnyValue(x => x.ActivePanel) .Select(x => { switch (x) { case ConfigurationVM config: return(config.WhenAnyFallback(x => x.CurrentRun !.Running, fallback: false)); case PatchersRunVM running: return(running.WhenAnyValue(x => x.Running)); default: break; } return(Observable.Return(false)); }) .Switch() .DistinctUntilChanged() .ToGuiProperty(this, nameof(Hot)); OpenProfilesPageCommand = ReactiveCommand.Create(() => { ActivePanel = new ProfilesDisplayVM(Configuration, ActivePanel); }, canExecute: Observable.CombineLatest( this.WhenAnyFallback(x => x.Configuration.CurrentRun !.Running, fallback: false), this.WhenAnyValue(x => x.ActivePanel) .Select(x => x is ProfilesDisplayVM), (running, isProfile) => !running && !isProfile)); IdeOptions.AddRange(EnumExt.GetValues <IDE>()); Task.Run(() => Mutagen.Bethesda.WarmupAll.Init()).FireAndForget(); SynthesisVersion = Mutagen.Bethesda.Synthesis.Versions.SynthesisVersion; MutagenVersion = Mutagen.Bethesda.Synthesis.Versions.MutagenVersion; var latestVersions = Observable.Return(Unit.Default) .ObserveOn(RxApp.TaskpoolScheduler) .CombineLatest( DotNetSdkInstalled, (_, v) => v) .SelectTask(async v => { var normalUpdateTask = GetLatestVersions(v, includePrerelease: false); var prereleaseUpdateTask = GetLatestVersions(v, includePrerelease: true); await Task.WhenAll(normalUpdateTask, prereleaseUpdateTask); return(Normal: await normalUpdateTask, Prerelease: await prereleaseUpdateTask); }) .Replay(1) .RefCount(); NewestMutagenVersion = Observable.CombineLatest( latestVersions, this.WhenAnyFallback(x => x.Configuration.SelectedProfile !.ConsiderPrereleaseNugets), (vers, prereleases) => prereleases ? vers.Prerelease.MutagenVersion : vers.Normal.MutagenVersion) .Replay(1) .RefCount(); NewestSynthesisVersion = Observable.CombineLatest( latestVersions, this.WhenAnyFallback(x => x.Configuration.SelectedProfile !.ConsiderPrereleaseNugets), (vers, prereleases) => prereleases ? vers.Prerelease.SynthesisVersion : vers.Normal.SynthesisVersion) .Replay(1) .RefCount(); // Switch to DotNet screen if missing DotNetSdkInstalled .Subscribe(v => { if (v == null) { ActivePanel = new DotNetNotInstalledVM(this, this.ActivePanel, DotNetSdkInstalled); } }); _ActiveConfirmation = Observable.CombineLatest( this.WhenAnyFallback(x => x.Configuration.SelectedProfile !.SelectedPatcher) .Select(x => { if (x is not GitPatcherVM gitPatcher) { return(Observable.Return(default(GitPatcherVM?))); } return(gitPatcher.WhenAnyValue(x => x.PatcherSettings.SettingsOpen) .Select(open => open ? (GitPatcherVM?)gitPatcher : null)); }) .Switch(), this.WhenAnyValue(x => x.TargetConfirmation), (openPatcher, target) => { if (target != null) { return(target); } if (openPatcher == null) { return(default(ConfirmationActionVM?)); } return(new ConfirmationActionVM( "External Patcher Settings Open", $"{openPatcher.Nickname} is open for settings manipulation.", toDo: null)); }) .ToGuiProperty(this, nameof(ActiveConfirmation), default(ConfirmationActionVM?)); _InModal = this.WhenAnyValue(x => x.ActiveConfirmation) .Select(x => x != null) .ToGuiProperty(this, nameof(InModal)); }
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, 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); }