From 179ac2b0ee4a8d36f2470f2bb05bccc1ff6574d9 Mon Sep 17 00:00:00 2001 From: Justin Swanson Date: Tue, 3 Dec 2019 15:56:18 -0600 Subject: [PATCH] ABatchProcessor takes CancellationToken Some basic usage of it. Needs to be utilized deeper --- Wabbajack.Lib/ABatchProcessor.cs | 7 ++++--- Wabbajack.Lib/ACompiler.cs | 1 + Wabbajack.Lib/MO2Compiler.cs | 14 +++++++++++--- Wabbajack.Lib/MO2Installer.cs | 17 ++++++++++++++++- Wabbajack.Lib/VortexCompiler.cs | 12 +++++++++++- Wabbajack.Lib/VortexInstaller.cs | 22 +++++++++++++++++++--- 6 files changed, 62 insertions(+), 11 deletions(-) diff --git a/Wabbajack.Lib/ABatchProcessor.cs b/Wabbajack.Lib/ABatchProcessor.cs index c05b9bde..70ab467c 100644 --- a/Wabbajack.Lib/ABatchProcessor.cs +++ b/Wabbajack.Lib/ABatchProcessor.cs @@ -45,6 +45,7 @@ namespace Wabbajack.Lib private int _configured; private int _started; + private readonly CancellationTokenSource _cancel = new CancellationTokenSource(); protected void ConfigureProcessor(int steps, int threads = 0) { @@ -77,7 +78,7 @@ namespace Wabbajack.Lib } } - protected abstract bool _Begin(); + protected abstract bool _Begin(CancellationToken cancel); public Task Begin() { if (1 == Interlocked.CompareExchange(ref _started, 1, 1)) @@ -92,7 +93,7 @@ namespace Wabbajack.Lib { try { - _tcs.SetResult(_Begin()); + _tcs.SetResult(_Begin(_cancel.Token)); } catch (Exception ex) { @@ -110,8 +111,8 @@ namespace Wabbajack.Lib public void Terminate() { + _cancel.Cancel(); Queue?.Shutdown(); - _processorThread?.Abort(); _isRunning.OnNext(false); } } diff --git a/Wabbajack.Lib/ACompiler.cs b/Wabbajack.Lib/ACompiler.cs index fd7e4b48..4052d345 100644 --- a/Wabbajack.Lib/ACompiler.cs +++ b/Wabbajack.Lib/ACompiler.cs @@ -5,6 +5,7 @@ using System.IO; using System.IO.Compression; using System.Linq; using System.Reactive.Subjects; +using System.Threading; using CommonMark; using Wabbajack.Common; using Wabbajack.Lib.CompilationSteps; diff --git a/Wabbajack.Lib/MO2Compiler.cs b/Wabbajack.Lib/MO2Compiler.cs index 952c2e25..38010f23 100644 --- a/Wabbajack.Lib/MO2Compiler.cs +++ b/Wabbajack.Lib/MO2Compiler.cs @@ -4,6 +4,7 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Threading; using System.Threading.Tasks; using Wabbajack.Common; using Wabbajack.Lib.CompilationSteps; @@ -70,8 +71,9 @@ namespace Wabbajack.Lib public HashSet SelectedProfiles { get; set; } = new HashSet(); - protected override bool _Begin() + protected override bool _Begin(CancellationToken cancel) { + if (cancel.IsCancellationRequested) return false; ConfigureProcessor(16); UpdateTracker.Reset(); UpdateTracker.NextStep("Gathering information"); @@ -83,6 +85,7 @@ namespace Wabbajack.Lib Info("Using Profiles: " + string.Join(", ", SelectedProfiles.OrderBy(p => p))); + if (cancel.IsCancellationRequested) return false; VFS.IntegrateFromFile(_vfsCacheName); var roots = new List() @@ -101,6 +104,7 @@ namespace Wabbajack.Lib } UpdateTracker.NextStep("Indexing folders"); + if (cancel.IsCancellationRequested) return false; VFS.AddRoots(roots); VFS.WriteToFile(_vfsCacheName); @@ -112,10 +116,12 @@ namespace Wabbajack.Lib { Path = Path.Combine(Consts.LOOTFolderFilesDir, p.RelativeTo(lootPath)) }); } + if (cancel.IsCancellationRequested) return false; UpdateTracker.NextStep("Cleaning output folder"); if (Directory.Exists(ModListOutputFolder)) Utils.DeleteDirectory(ModListOutputFolder); + if (cancel.IsCancellationRequested) return false; UpdateTracker.NextStep("Finding Install Files"); Directory.CreateDirectory(ModListOutputFolder); @@ -161,6 +167,7 @@ namespace Wabbajack.Lib Info($"Found {AllFiles.Count} files to build into mod list"); + if (cancel.IsCancellationRequested) return false; UpdateTracker.NextStep("Verifying destinations"); var dups = AllFiles.GroupBy(f => f.Path) @@ -179,6 +186,7 @@ namespace Wabbajack.Lib ExtraFiles = new ConcurrentBag(); + if (cancel.IsCancellationRequested) return false; UpdateTracker.NextStep("Loading INIs"); ModInis = Directory.EnumerateDirectories(Path.Combine(MO2Folder, "mods")) @@ -193,13 +201,13 @@ namespace Wabbajack.Lib .Where(f => f.Item2 != null) .ToDictionary(f => f.Item1, f => f.Item2); + if (cancel.IsCancellationRequested) return false; var stack = MakeStack(); - UpdateTracker.NextStep("Running Compilation Stack"); var results = AllFiles.PMap(Queue, UpdateTracker, f => RunStack(stack, f)).ToList(); // Add the extra files that were generated by the stack - + if (cancel.IsCancellationRequested) return false; UpdateTracker.NextStep($"Adding {ExtraFiles.Count} that were generated by the stack"); results = results.Concat(ExtraFiles).ToList(); diff --git a/Wabbajack.Lib/MO2Installer.cs b/Wabbajack.Lib/MO2Installer.cs index 7d978754..41b54ef5 100644 --- a/Wabbajack.Lib/MO2Installer.cs +++ b/Wabbajack.Lib/MO2Installer.cs @@ -2,6 +2,7 @@ using System.IO; using System.Linq; using System.Text; +using System.Threading; using System.Windows; using Alphaleonis.Win32.Filesystem; using IniParser; @@ -35,8 +36,9 @@ namespace Wabbajack.Lib { } - protected override bool _Begin() + protected override bool _Begin(CancellationToken cancel) { + if (cancel.IsCancellationRequested) return false; ConfigureProcessor(18, RecommendQueueSize()); var game = GameRegistry.Games[ModList.GameType]; @@ -53,9 +55,11 @@ namespace Wabbajack.Lib return false; } + if (cancel.IsCancellationRequested) return false; UpdateTracker.NextStep("Validating Game ESMs"); ValidateGameESMs(); + if (cancel.IsCancellationRequested) return false; UpdateTracker.NextStep("Validating Modlist"); ValidateModlist.RunValidation(ModList); @@ -71,15 +75,19 @@ namespace Wabbajack.Lib } } + if (cancel.IsCancellationRequested) return false; UpdateTracker.NextStep("Optimizing Modlist"); OptimizeModlist(); + if (cancel.IsCancellationRequested) return false; UpdateTracker.NextStep("Hashing Archives"); HashArchives(); + if (cancel.IsCancellationRequested) return false; UpdateTracker.NextStep("Downloading Missing Archives"); DownloadArchives(); + if (cancel.IsCancellationRequested) return false; UpdateTracker.NextStep("Hashing Remaining Archives"); HashArchives(); @@ -94,24 +102,31 @@ namespace Wabbajack.Lib Error("Cannot continue, was unable to download one or more archives"); } + if (cancel.IsCancellationRequested) return false; UpdateTracker.NextStep("Priming VFS"); PrimeVFS(); + if (cancel.IsCancellationRequested) return false; UpdateTracker.NextStep("Building Folder Structure"); BuildFolderStructure(); + if (cancel.IsCancellationRequested) return false; UpdateTracker.NextStep("Installing Archives"); InstallArchives(); + if (cancel.IsCancellationRequested) return false; UpdateTracker.NextStep("Installing Included files"); InstallIncludedFiles(); + if (cancel.IsCancellationRequested) return false; UpdateTracker.NextStep("Installing Archive Metas"); InstallIncludedDownloadMetas(); + if (cancel.IsCancellationRequested) return false; UpdateTracker.NextStep("Building BSAs"); BuildBSAs(); + if (cancel.IsCancellationRequested) return false; UpdateTracker.NextStep("Generating Merges"); zEditIntegration.GenerateMerges(this); diff --git a/Wabbajack.Lib/VortexCompiler.cs b/Wabbajack.Lib/VortexCompiler.cs index 0f0e0234..d81bfabd 100644 --- a/Wabbajack.Lib/VortexCompiler.cs +++ b/Wabbajack.Lib/VortexCompiler.cs @@ -4,6 +4,7 @@ using System.IO; using System.Linq; using System.Security.Cryptography; using System.Text; +using System.Threading; using DynamicData; using Microsoft.WindowsAPICodePack.Shell; using Newtonsoft.Json; @@ -69,19 +70,24 @@ namespace Wabbajack.Lib ActiveArchives = new List(); } - protected override bool _Begin() + protected override bool _Begin(CancellationToken cancel) { + if (cancel.IsCancellationRequested) return false; + ConfigureProcessor(10); if (string.IsNullOrEmpty(ModListName)) ModListName = $"Vortex ModList for {Game.ToString()}"; Info($"Starting Vortex compilation for {GameName} at {GamePath} with staging folder at {StagingFolder} and downloads folder at {DownloadsFolder}."); + if (cancel.IsCancellationRequested) return false; ParseDeploymentFile(); + if (cancel.IsCancellationRequested) return false; Info("Starting pre-compilation steps"); CreateMetaFiles(); + if (cancel.IsCancellationRequested) return false; Info($"Indexing {StagingFolder}"); VFS.AddRoot(StagingFolder); @@ -91,8 +97,10 @@ namespace Wabbajack.Lib Info($"Indexing {DownloadsFolder}"); VFS.AddRoot(DownloadsFolder); + if (cancel.IsCancellationRequested) return false; AddExternalFolder(); + if (cancel.IsCancellationRequested) return false; Info("Cleaning output folder"); if (Directory.Exists(ModListOutputFolder)) Utils.DeleteDirectory(ModListOutputFolder); Directory.CreateDirectory(ModListOutputFolder); @@ -138,6 +146,7 @@ namespace Wabbajack.Lib Info($"Found {AllFiles.Count} files to build into mod list"); + if (cancel.IsCancellationRequested) return false; Info("Verifying destinations"); var duplicates = AllFiles.GroupBy(f => f.Path) .Where(fs => fs.Count() > 1) @@ -220,6 +229,7 @@ namespace Wabbajack.Lib } */ + if (cancel.IsCancellationRequested) return false; GatherArchives(); ModList = new ModList diff --git a/Wabbajack.Lib/VortexInstaller.cs b/Wabbajack.Lib/VortexInstaller.cs index 802b7a37..ae416716 100644 --- a/Wabbajack.Lib/VortexInstaller.cs +++ b/Wabbajack.Lib/VortexInstaller.cs @@ -1,5 +1,6 @@ using System.Diagnostics; using System.Linq; +using System.Threading; using System.Windows; using Wabbajack.Common; using Directory = Alphaleonis.Win32.Filesystem.Directory; @@ -29,21 +30,29 @@ namespace Wabbajack.Lib GameInfo = GameRegistry.Games[ModList.GameType]; } - protected override bool _Begin() + protected override bool _Begin(CancellationToken cancel) { + if (cancel.IsCancellationRequested) return false; MessageBox.Show( "Vortex Support is still experimental and may produce unexpected results. " + "If anything fails go to the special vortex support channels on the discord. @erri120#2285 " + "for support.", "Warning", MessageBoxButton.OK); + if (cancel.IsCancellationRequested) return false; ConfigureProcessor(10, RecommendQueueSize()); Directory.CreateDirectory(DownloadFolder); - HashArchives(); - DownloadArchives(); + if (cancel.IsCancellationRequested) return false; HashArchives(); + if (cancel.IsCancellationRequested) return false; + DownloadArchives(); + + if (cancel.IsCancellationRequested) return false; + HashArchives(); + + if (cancel.IsCancellationRequested) return false; var missing = ModList.Archives.Where(a => !HashedArchives.ContainsKey(a.Hash)).ToList(); if (missing.Count > 0) { @@ -57,9 +66,16 @@ namespace Wabbajack.Lib PrimeVFS(); + if (cancel.IsCancellationRequested) return false; BuildFolderStructure(); + + if (cancel.IsCancellationRequested) return false; InstallArchives(); + + if (cancel.IsCancellationRequested) return false; InstallIncludedFiles(); + + if (cancel.IsCancellationRequested) return false; InstallSteamWorkshopItems(); //InstallIncludedDownloadMetas();