From fb2cb28cf46f6b4f4329d0eaef2df4ae7b9a0e66 Mon Sep 17 00:00:00 2001 From: Justin Swanson Date: Sun, 1 Dec 2019 23:36:47 -0600 Subject: [PATCH] Some ISubInstallerVM work --- Wabbajack/View Models/Compilers/CompilerVM.cs | 7 -- .../View Models/Compilers/ISubCompilerVM.cs | 1 - .../View Models/Installers/ISubInstallerVM.cs | 18 +++ .../{ => Installers}/InstallerVM.cs | 116 +++++++----------- .../View Models/Installers/MO2InstallerVM.cs | 84 +++++++++++++ Wabbajack/Views/InstallationView.xaml | 2 +- Wabbajack/Wabbajack.csproj | 4 +- 7 files changed, 153 insertions(+), 79 deletions(-) create mode 100644 Wabbajack/View Models/Installers/ISubInstallerVM.cs rename Wabbajack/View Models/{ => Installers}/InstallerVM.cs (84%) create mode 100644 Wabbajack/View Models/Installers/MO2InstallerVM.cs diff --git a/Wabbajack/View Models/Compilers/CompilerVM.cs b/Wabbajack/View Models/Compilers/CompilerVM.cs index b5986757..af540398 100644 --- a/Wabbajack/View Models/Compilers/CompilerVM.cs +++ b/Wabbajack/View Models/Compilers/CompilerVM.cs @@ -28,9 +28,6 @@ namespace Wabbajack private readonly ObservableAsPropertyHelper _currentModlistSettings; public ModlistSettingsEditorVM CurrentModlistSettings => _currentModlistSettings.Value; - private readonly ObservableAsPropertyHelper _currentStatusTracker; - public StatusUpdateTracker CurrentStatusTracker => _currentStatusTracker.Value; - private readonly ObservableAsPropertyHelper _compiling; public bool Compiling => _compiling.Value; @@ -86,10 +83,6 @@ namespace Wabbajack _currentModlistSettings = this.WhenAny(x => x.Compiler.ModlistSettings) .ToProperty(this, nameof(CurrentModlistSettings)); - // Let sub VM determine what progress we're seeing - _currentStatusTracker = this.WhenAny(x => x.Compiler.StatusTracker) - .ToProperty(this, nameof(CurrentStatusTracker)); - _image = this.WhenAny(x => x.CurrentModlistSettings.ImagePath.TargetPath) // Throttle so that it only loads image after any sets of swaps have completed .Throttle(TimeSpan.FromMilliseconds(50), RxApp.MainThreadScheduler) diff --git a/Wabbajack/View Models/Compilers/ISubCompilerVM.cs b/Wabbajack/View Models/Compilers/ISubCompilerVM.cs index 1c228f5c..2a3fd08a 100644 --- a/Wabbajack/View Models/Compilers/ISubCompilerVM.cs +++ b/Wabbajack/View Models/Compilers/ISubCompilerVM.cs @@ -10,7 +10,6 @@ namespace Wabbajack ACompiler ActiveCompilation { get; } ModlistSettingsEditorVM ModlistSettings { get; } - StatusUpdateTracker StatusTracker { get;} void Unload(); } } diff --git a/Wabbajack/View Models/Installers/ISubInstallerVM.cs b/Wabbajack/View Models/Installers/ISubInstallerVM.cs new file mode 100644 index 00000000..f2b1bf45 --- /dev/null +++ b/Wabbajack/View Models/Installers/ISubInstallerVM.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ReactiveUI; +using Wabbajack.Common; +using Wabbajack.Lib; + +namespace Wabbajack +{ + public interface ISubInstallerVM + { + IReactiveCommand BeginCommand { get; } + AInstaller ActiveInstallation { get; } + void Unload(); + } +} diff --git a/Wabbajack/View Models/InstallerVM.cs b/Wabbajack/View Models/Installers/InstallerVM.cs similarity index 84% rename from Wabbajack/View Models/InstallerVM.cs rename to Wabbajack/View Models/Installers/InstallerVM.cs index 77cd6ec0..987e09a2 100644 --- a/Wabbajack/View Models/InstallerVM.cs +++ b/Wabbajack/View Models/Installers/InstallerVM.cs @@ -17,6 +17,7 @@ using ReactiveUI.Fody.Helpers; using System.Windows.Media; using DynamicData; using DynamicData.Binding; +using System.Reactive; namespace Wabbajack { @@ -33,15 +34,12 @@ namespace Wabbajack public FilePickerVM ModListPath { get; } - [Reactive] - public bool UIReady { get; set; } + private readonly ObservableAsPropertyHelper _installer; + public ISubInstallerVM Installer => _installer.Value; private readonly ObservableAsPropertyHelper _htmlReport; public string HTMLReport => _htmlReport.Value; - [Reactive] - public AInstaller ActiveInstallation { get; private set; } - private readonly ObservableAsPropertyHelper _installing; public bool Installing => _installing.Value; @@ -82,8 +80,10 @@ namespace Wabbajack private readonly ObservableAsPropertyHelper _CurrentSettings; public ModlistInstallationSettings CurrentSettings => _CurrentSettings.Value; + private readonly ObservableAsPropertyHelper _TargetManager; + public ModManager? TargetManager => _TargetManager.Value; + // Command properties - public IReactiveCommand BeginCommand { get; } public IReactiveCommand ShowReportCommand { get; } public IReactiveCommand OpenReadmeCommand { get; } public IReactiveCommand VisitWebsiteCommand { get; } @@ -127,6 +127,31 @@ namespace Wabbajack PromptTitle = "Select a modlist to install" }; + // Swap to proper sub VM based on selected type + _installer = this.WhenAny(x => x.TargetManager) + // Delay so the initial VM swap comes in immediately, subVM comes right after + .DelayInitial(TimeSpan.FromMilliseconds(50), RxApp.MainThreadScheduler) + .Select(type => + { + switch (type) + { + case ModManager.MO2: + return new MO2InstallerVM(this); + case ModManager.Vortex: + throw new NotImplementedException(); + default: + return null; + } + }) + // Unload old VM + .Pairwise() + .Do(pair => + { + pair.Previous?.Unload(); + }) + .Select(p => p.Current) + .ToProperty(this, nameof(Installer)); + // Load settings _CurrentSettings = this.WhenAny(x => x.ModListPath.TargetPath) .Select(path => path == null ? null : MWVM.Settings.Installer.ModlistSettings.TryCreate(path)) @@ -161,17 +186,20 @@ namespace Wabbajack _htmlReport = this.WhenAny(x => x.ModList) .Select(modList => modList?.ReportHTML) .ToProperty(this, nameof(HTMLReport)); - _installing = this.WhenAny(x => x.ActiveInstallation) + _installing = this.WhenAny(x => x.Installer.ActiveInstallation) .Select(compilation => compilation != null) .ObserveOnGuiThread() .ToProperty(this, nameof(Installing)); + _TargetManager = this.WhenAny(x => x.ModList) + .Select(modList => modList?.ModManager) + .ToProperty(this, nameof(TargetManager)); BackCommand = ReactiveCommand.Create( execute: () => mainWindowVM.ActivePane = mainWindowVM.ModeSelectionVM, canExecute: this.WhenAny(x => x.Installing) .Select(x => !x)); - _percentCompleted = this.WhenAny(x => x.ActiveInstallation) + _percentCompleted = this.WhenAny(x => x.Installer.ActiveInstallation) .StartWith(default(AInstaller)) .Pairwise() .Select(c => @@ -233,18 +261,6 @@ namespace Wabbajack canExecute: this.WhenAny(x => x.ModList) .Select(modList => !string.IsNullOrEmpty(modList?.Readme)) .ObserveOnGuiThread()); - BeginCommand = ReactiveCommand.CreateFromTask( - execute: ExecuteBegin, - canExecute: Observable.CombineLatest( - this.WhenAny(x => x.Installing), - this.WhenAny(x => x.Location.InError), - this.WhenAny(x => x.DownloadLocation.InError), - resultSelector: (installing, loc, download) => - { - if (installing) return false; - return !loc && !download; - }) - .ObserveOnGuiThread()); VisitWebsiteCommand = ReactiveCommand.Create( execute: () => Process.Start(ModList.Website), canExecute: this.WhenAny(x => x.ModList.Website) @@ -274,7 +290,7 @@ namespace Wabbajack .ToProperty(this, nameof(ProgressTitle)); // Compile progress updates and populate ObservableCollection - this.WhenAny(x => x.ActiveInstallation) + this.WhenAny(x => x.Installer.ActiveInstallation) .SelectMany(c => c?.QueueStatus ?? Observable.Empty()) .ObserveOn(RxApp.TaskpoolScheduler) .ToObservableChangeSet(x => x.ID) @@ -286,6 +302,16 @@ namespace Wabbajack .Bind(StatusList) .Subscribe() .DisposeWith(CompositeDisposable); + + // When sub installer begins an install, mark state variable + this.WhenAny(x => x.Installer.BeginCommand) + .Select(x => x?.StartingExecution() ?? Observable.Empty()) + .Switch() + .Subscribe(_ => + { + InstallingMode = true; + }) + .DisposeWith(CompositeDisposable); } private void ShowReport() @@ -321,54 +347,6 @@ namespace Wabbajack } } - private async Task ExecuteBegin() - { - InstallingMode = true; - AInstaller installer; - - try - { - installer = new MO2Installer( - archive: ModListPath.TargetPath, - modList: ModList.SourceModList, - outputFolder: Location.TargetPath, - downloadFolder: DownloadLocation.TargetPath); - } - catch (Exception ex) - { - while (ex.InnerException != null) ex = ex.InnerException; - Utils.Log(ex.StackTrace); - Utils.Log(ex.ToString()); - Utils.Log($"{ex.Message} - Can't continue"); - ActiveInstallation = null; - return; - } - - await Task.Run(async () => - { - IDisposable subscription = null; - try - { - var workTask = installer.Begin(); - ActiveInstallation = installer; - await workTask; - } - catch (Exception ex) - { - while (ex.InnerException != null) ex = ex.InnerException; - Utils.Log(ex.StackTrace); - Utils.Log(ex.ToString()); - Utils.Log($"{ex.Message} - Can't continue"); - } - finally - { - // Dispose of CPU tracking systems - subscription?.Dispose(); - ActiveInstallation = null; - } - }); - } - private void SaveSettings(ModlistInstallationSettings settings) { MWVM.Settings.Installer.LastInstalledListLocation = ModListPath.TargetPath; diff --git a/Wabbajack/View Models/Installers/MO2InstallerVM.cs b/Wabbajack/View Models/Installers/MO2InstallerVM.cs new file mode 100644 index 00000000..ab4a0ae5 --- /dev/null +++ b/Wabbajack/View Models/Installers/MO2InstallerVM.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reactive.Linq; +using System.Text; +using System.Threading.Tasks; +using ReactiveUI; +using ReactiveUI.Fody.Helpers; +using Wabbajack.Common; +using Wabbajack.Lib; + +namespace Wabbajack +{ + public class MO2InstallerVM : ViewModel, ISubInstallerVM + { + public IReactiveCommand BeginCommand { get; } + + [Reactive] + public AInstaller ActiveInstallation { get; private set; } + + public MO2InstallerVM(InstallerVM installerVM) + { + BeginCommand = ReactiveCommand.CreateFromTask( + canExecute: Observable.CombineLatest( + installerVM.WhenAny(x => x.Location.InError), + installerVM.WhenAny(x => x.DownloadLocation.InError), + resultSelector: (loc, download) => + { + return !loc && !download; + }) + .ObserveOnGuiThread(), + execute: async () => + { + AInstaller installer; + + try + { + installer = new MO2Installer( + archive: installerVM.ModListPath.TargetPath, + modList: installerVM.ModList.SourceModList, + outputFolder: installerVM.Location.TargetPath, + downloadFolder: installerVM.DownloadLocation.TargetPath); + } + catch (Exception ex) + { + while (ex.InnerException != null) ex = ex.InnerException; + Utils.Log(ex.StackTrace); + Utils.Log(ex.ToString()); + Utils.Log($"{ex.Message} - Can't continue"); + ActiveInstallation = null; + return; + } + + await Task.Run(async () => + { + IDisposable subscription = null; + try + { + var workTask = installer.Begin(); + ActiveInstallation = installer; + await workTask; + } + catch (Exception ex) + { + while (ex.InnerException != null) ex = ex.InnerException; + Utils.Log(ex.StackTrace); + Utils.Log(ex.ToString()); + Utils.Log($"{ex.Message} - Can't continue"); + } + finally + { + // Dispose of CPU tracking systems + subscription?.Dispose(); + ActiveInstallation = null; + } + }); + }); + } + + public void Unload() + { + } + } +} diff --git a/Wabbajack/Views/InstallationView.xaml b/Wabbajack/Views/InstallationView.xaml index d634de56..5cde65e7 100644 --- a/Wabbajack/Views/InstallationView.xaml +++ b/Wabbajack/Views/InstallationView.xaml @@ -347,7 +347,7 @@ Grid.Column="4" Margin="0,0,25,0" HorizontalAlignment="Right" - Command="{Binding BeginCommand, Mode=OneWay}" /> + Command="{Binding Installer.BeginCommand, Mode=OneWay}" /> diff --git a/Wabbajack/Wabbajack.csproj b/Wabbajack/Wabbajack.csproj index ae806dcd..530b80d7 100644 --- a/Wabbajack/Wabbajack.csproj +++ b/Wabbajack/Wabbajack.csproj @@ -169,6 +169,8 @@ Designer + + @@ -301,7 +303,7 @@ App.xaml Code - + MainWindow.xaml