Random .Results swapped to async

This commit is contained in:
Justin Swanson 2019-12-06 20:54:27 -06:00
parent a25fc9d1a9
commit 729b5128da
13 changed files with 55 additions and 98 deletions

View File

@ -86,7 +86,7 @@ namespace Wabbajack.Lib
/// We don't want to make the installer index all the archives, that's just a waste of time, so instead /// We don't want to make the installer index all the archives, that's just a waste of time, so instead
/// we'll pass just enough information to VFS to let it know about the files we have. /// we'll pass just enough information to VFS to let it know about the files we have.
/// </summary> /// </summary>
public void PrimeVFS() public async Task PrimeVFS()
{ {
VFS.AddKnown(HashedArchives.Select(a => new KnownFile VFS.AddKnown(HashedArchives.Select(a => new KnownFile
{ {
@ -100,7 +100,7 @@ namespace Wabbajack.Lib
.OfType<FromArchive>() .OfType<FromArchive>()
.Select(f => new KnownFile { Paths = f.ArchiveHashPath})); .Select(f => new KnownFile { Paths = f.ArchiveHashPath}));
VFS.BackfillMissing(); await VFS.BackfillMissing();
} }
public void BuildFolderStructure() public void BuildFolderStructure()

View File

@ -86,7 +86,7 @@ namespace Wabbajack.Lib
Info("Using Profiles: " + string.Join(", ", SelectedProfiles.OrderBy(p => p))); Info("Using Profiles: " + string.Join(", ", SelectedProfiles.OrderBy(p => p)));
if (cancel.IsCancellationRequested) return false; if (cancel.IsCancellationRequested) return false;
VFS.IntegrateFromFile(_vfsCacheName); await VFS.IntegrateFromFile(_vfsCacheName);
var roots = new List<string>() var roots = new List<string>()
{ {

View File

@ -69,7 +69,7 @@ namespace Wabbajack.Lib
if (Directory.Exists(Path.Combine(OutputFolder, "mods")) && WarnOnOverwrite) if (Directory.Exists(Path.Combine(OutputFolder, "mods")) && WarnOnOverwrite)
{ {
if (Utils.Log(new ConfirmUpdateOfExistingInstall { ModListName = ModList.Name, OutputFolder = OutputFolder}).Task.Result == ConfirmUpdateOfExistingInstall.Choice.Abort) if ((await Utils.Log(new ConfirmUpdateOfExistingInstall { ModListName = ModList.Name, OutputFolder = OutputFolder }).Task) == ConfirmUpdateOfExistingInstall.Choice.Abort)
{ {
Utils.Log("Existing installation at the request of the user, existing mods folder found."); Utils.Log("Existing installation at the request of the user, existing mods folder found.");
return false; return false;
@ -105,7 +105,7 @@ namespace Wabbajack.Lib
if (cancel.IsCancellationRequested) return false; if (cancel.IsCancellationRequested) return false;
UpdateTracker.NextStep("Priming VFS"); UpdateTracker.NextStep("Priming VFS");
PrimeVFS(); await PrimeVFS();
if (cancel.IsCancellationRequested) return false; if (cancel.IsCancellationRequested) return false;
UpdateTracker.NextStep("Building Folder Structure"); UpdateTracker.NextStep("Building Folder Structure");

View File

@ -12,54 +12,6 @@ namespace Wabbajack.Lib
{ {
public static class UIUtils public static class UIUtils
{ {
public static string ShowFolderSelectionDialog(string prompt)
{
if (System.Windows.Application.Current.Dispatcher.Thread != Thread.CurrentThread)
{
var task = new TaskCompletionSource<string>();
System.Windows.Application.Current.Dispatcher.Invoke(() =>
{
try
{
task.SetResult(ShowFolderSelectionDialog(prompt));
}
catch (Exception ex)
{
task.SetException(ex);
}
});
task.Task.Wait();
if (task.Task.IsFaulted)
throw task.Task.Exception;
return task.Task.Result;
}
var dlg = new CommonOpenFileDialog();
dlg.Title = prompt;
dlg.IsFolderPicker = true;
dlg.InitialDirectory = Assembly.GetEntryAssembly().Location;
dlg.AddToMostRecentlyUsedList = false;
dlg.AllowNonFileSystemItems = false;
dlg.DefaultDirectory = Assembly.GetEntryAssembly().Location;
dlg.EnsureFileExists = true;
dlg.EnsurePathExists = true;
dlg.EnsureReadOnly = false;
dlg.EnsureValidNames = true;
dlg.Multiselect = false;
dlg.ShowPlacesList = true;
if (dlg.ShowDialog() == CommonFileDialogResult.Ok)
{
return dlg.FileName;
// Do something with selected folder string
}
return null;
}
public static BitmapImage BitmapImageFromResource(string name) => BitmapImageFromStream(System.Windows.Application.GetResourceStream(new Uri("pack://application:,,,/Wabbajack;component/" + name)).Stream); public static BitmapImage BitmapImageFromResource(string name) => BitmapImageFromStream(System.Windows.Application.GetResourceStream(new Uri("pack://application:,,,/Wabbajack;component/" + name)).Stream);
public static BitmapImage BitmapImageFromStream(Stream stream) public static BitmapImage BitmapImageFromStream(Stream stream)

View File

@ -65,7 +65,7 @@ namespace Wabbajack.Lib
Error("Cannot continue, was unable to download one or more archives"); Error("Cannot continue, was unable to download one or more archives");
} }
PrimeVFS(); await PrimeVFS();
if (cancel.IsCancellationRequested) return false; if (cancel.IsCancellationRequested) return false;
BuildFolderStructure(); BuildFolderStructure();

View File

@ -1,4 +1,5 @@
using System; using System;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting;
using Wabbajack.Common; using Wabbajack.Common;
using Wabbajack.Lib; using Wabbajack.Lib;
@ -28,20 +29,20 @@ namespace Wabbajack.Test
utils.Dispose(); utils.Dispose();
} }
protected MO2Compiler ConfigureAndRunCompiler(string profile) protected async Task<MO2Compiler> ConfigureAndRunCompiler(string profile)
{ {
var compiler = new MO2Compiler( var compiler = new MO2Compiler(
mo2Folder: utils.MO2Folder, mo2Folder: utils.MO2Folder,
mo2Profile: profile, mo2Profile: profile,
outputFile: profile + ExtensionManager.Extension); outputFile: profile + ExtensionManager.Extension);
compiler.ShowReportWhenFinished = false; compiler.ShowReportWhenFinished = false;
Assert.IsTrue(compiler.Begin().Result); Assert.IsTrue(await compiler.Begin());
return compiler; return compiler;
} }
protected ModList CompileAndInstall(string profile) protected async Task<ModList> CompileAndInstall(string profile)
{ {
var compiler = ConfigureAndRunCompiler(profile); var compiler = await ConfigureAndRunCompiler(profile);
Install(compiler); Install(compiler);
return compiler.ModList; return compiler.ModList;
} }

View File

@ -1,5 +1,6 @@
using System; using System;
using System.IO; using System.IO;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting;
using Wabbajack.Common; using Wabbajack.Common;
using Wabbajack.Lib; using Wabbajack.Lib;
@ -31,13 +32,13 @@ namespace Wabbajack.Test
utils.Dispose(); utils.Dispose();
} }
protected VortexCompiler ConfigureAndRunCompiler() protected async Task<VortexCompiler> ConfigureAndRunCompiler()
{ {
var vortexCompiler = MakeCompiler(); var vortexCompiler = MakeCompiler();
vortexCompiler.DownloadsFolder = utils.DownloadsFolder; vortexCompiler.DownloadsFolder = utils.DownloadsFolder;
vortexCompiler.StagingFolder = utils.InstallFolder; vortexCompiler.StagingFolder = utils.InstallFolder;
Directory.CreateDirectory(utils.InstallFolder); Directory.CreateDirectory(utils.InstallFolder);
Assert.IsTrue(vortexCompiler.Begin().Result); Assert.IsTrue(await vortexCompiler.Begin());
return vortexCompiler; return vortexCompiler;
} }
@ -52,9 +53,9 @@ namespace Wabbajack.Test
outputFile: $"test{ExtensionManager.Extension}"); outputFile: $"test{ExtensionManager.Extension}");
} }
protected ModList CompileAndInstall() protected async Task<ModList> CompileAndInstall()
{ {
var vortexCompiler = ConfigureAndRunCompiler(); var vortexCompiler = await ConfigureAndRunCompiler();
Install(vortexCompiler); Install(vortexCompiler);
return vortexCompiler.ModList; return vortexCompiler.ModList;
} }

View File

@ -1,4 +1,5 @@
using Microsoft.VisualStudio.TestTools.UnitTesting; using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Wabbajack.Lib.CompilationSteps; using Wabbajack.Lib.CompilationSteps;
namespace Wabbajack.Test namespace Wabbajack.Test
@ -7,13 +8,13 @@ namespace Wabbajack.Test
public class CompilationStackTests : ACompilerTest public class CompilationStackTests : ACompilerTest
{ {
[TestMethod] [TestMethod]
public void TestStackSerialization() public async Task TestStackSerialization()
{ {
var profile = utils.AddProfile(); var profile = utils.AddProfile();
var mod = utils.AddMod("test"); var mod = utils.AddMod("test");
utils.Configure(); utils.Configure();
var compiler = ConfigureAndRunCompiler(profile); var compiler = await ConfigureAndRunCompiler(profile);
var stack = compiler.MakeStack(); var stack = compiler.MakeStack();
var serialized = Serialization.Serialize(stack); var serialized = Serialization.Serialize(stack);

View File

@ -78,7 +78,7 @@ namespace Wabbajack.Test
outputFile: profile + ExtensionManager.Extension); outputFile: profile + ExtensionManager.Extension);
compiler.MO2DownloadsFolder = Path.Combine(utils.DownloadsFolder); compiler.MO2DownloadsFolder = Path.Combine(utils.DownloadsFolder);
compiler.ShowReportWhenFinished = false; compiler.ShowReportWhenFinished = false;
Assert.IsTrue(compiler.Begin().Result); Assert.IsTrue(await compiler.Begin());
} }
@ -139,9 +139,9 @@ namespace Wabbajack.Test
File.WriteAllText(dest + ".meta", ini); File.WriteAllText(dest + ".meta", ini);
} }
private ModList CompileAndInstall(string profile) private async Task<ModList> CompileAndInstall(string profile)
{ {
var compiler = ConfigureAndRunCompiler(profile); var compiler = await ConfigureAndRunCompiler(profile);
Install(compiler); Install(compiler);
return compiler.ModList; return compiler.ModList;
} }
@ -158,14 +158,14 @@ namespace Wabbajack.Test
installer.Begin().Wait(); installer.Begin().Wait();
} }
private MO2Compiler ConfigureAndRunCompiler(string profile) private async Task<MO2Compiler> ConfigureAndRunCompiler(string profile)
{ {
var compiler = new MO2Compiler( var compiler = new MO2Compiler(
mo2Folder: utils.MO2Folder, mo2Folder: utils.MO2Folder,
mo2Profile: profile, mo2Profile: profile,
outputFile: profile + ExtensionManager.Extension); outputFile: profile + ExtensionManager.Extension);
compiler.ShowReportWhenFinished = false; compiler.ShowReportWhenFinished = false;
Assert.IsTrue(compiler.Begin().Result); Assert.IsTrue(await compiler.Begin());
return compiler; return compiler;
} }
} }

View File

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting;
using Wabbajack.Common; using Wabbajack.Common;
using Wabbajack.Lib; using Wabbajack.Lib;
@ -14,7 +15,7 @@ namespace Wabbajack.Test
public class SanityTests : ACompilerTest public class SanityTests : ACompilerTest
{ {
[TestMethod] [TestMethod]
public void TestDirectMatch() public async Task TestDirectMatch()
{ {
var profile = utils.AddProfile(); var profile = utils.AddProfile();
@ -26,13 +27,13 @@ namespace Wabbajack.Test
utils.AddManualDownload( utils.AddManualDownload(
new Dictionary<string, byte[]> {{"/baz/biz.pex", File.ReadAllBytes(test_pex)}}); new Dictionary<string, byte[]> {{"/baz/biz.pex", File.ReadAllBytes(test_pex)}});
CompileAndInstall(profile); await CompileAndInstall(profile);
utils.VerifyInstalledFile(mod, @"Data\scripts\test.pex"); utils.VerifyInstalledFile(mod, @"Data\scripts\test.pex");
} }
[TestMethod] [TestMethod]
public void TestDuplicateFilesAreCopied() public async Task TestDuplicateFilesAreCopied()
{ {
var profile = utils.AddProfile(); var profile = utils.AddProfile();
@ -47,14 +48,14 @@ namespace Wabbajack.Test
utils.AddManualDownload( utils.AddManualDownload(
new Dictionary<string, byte[]> { { "/baz/biz.pex", File.ReadAllBytes(test_pex) } }); new Dictionary<string, byte[]> { { "/baz/biz.pex", File.ReadAllBytes(test_pex) } });
CompileAndInstall(profile); await CompileAndInstall(profile);
utils.VerifyInstalledFile(mod, @"Data\scripts\test.pex"); utils.VerifyInstalledFile(mod, @"Data\scripts\test.pex");
utils.VerifyInstalledFile(mod, @"Data\scripts\test.pex.copy"); utils.VerifyInstalledFile(mod, @"Data\scripts\test.pex.copy");
} }
[TestMethod] [TestMethod]
public void TestUpdating() public async Task TestUpdating()
{ {
var profile = utils.AddProfile(); var profile = utils.AddProfile();
@ -73,7 +74,7 @@ namespace Wabbajack.Test
{ "/baz/modified.pex", File.ReadAllBytes(modified) }, { "/baz/modified.pex", File.ReadAllBytes(modified) },
}); });
CompileAndInstall(profile); await CompileAndInstall(profile);
utils.VerifyInstalledFile(mod, @"Data\scripts\unchanged.pex"); utils.VerifyInstalledFile(mod, @"Data\scripts\unchanged.pex");
utils.VerifyInstalledFile(mod, @"Data\scripts\deleted.pex"); utils.VerifyInstalledFile(mod, @"Data\scripts\deleted.pex");
@ -95,7 +96,7 @@ namespace Wabbajack.Test
Assert.IsTrue(File.Exists(extra_path)); Assert.IsTrue(File.Exists(extra_path));
CompileAndInstall(profile); await CompileAndInstall(profile);
utils.VerifyInstalledFile(mod, @"Data\scripts\unchanged.pex"); utils.VerifyInstalledFile(mod, @"Data\scripts\unchanged.pex");
utils.VerifyInstalledFile(mod, @"Data\scripts\deleted.pex"); utils.VerifyInstalledFile(mod, @"Data\scripts\deleted.pex");
@ -108,7 +109,7 @@ namespace Wabbajack.Test
[TestMethod] [TestMethod]
public void CleanedESMTest() public async Task CleanedESMTest()
{ {
var profile = utils.AddProfile(); var profile = utils.AddProfile();
var mod = utils.AddMod("Cleaned ESMs"); var mod = utils.AddMod("Cleaned ESMs");
@ -123,7 +124,7 @@ namespace Wabbajack.Test
utils.VerifyInstalledFile(mod, @"Update.esm"); utils.VerifyInstalledFile(mod, @"Update.esm");
var compiler = ConfigureAndRunCompiler(profile); var compiler = await ConfigureAndRunCompiler(profile);
// Update the file and verify that it throws an error. // Update the file and verify that it throws an error.
utils.GenerateRandomFileData(game_file, 20); utils.GenerateRandomFileData(game_file, 20);
@ -155,7 +156,7 @@ namespace Wabbajack.Test
} }
[TestMethod] [TestMethod]
public void UnmodifiedInlinedFilesArePulledFromArchives() public async Task UnmodifiedInlinedFilesArePulledFromArchives()
{ {
var profile = utils.AddProfile(); var profile = utils.AddProfile();
var mod = utils.AddMod(); var mod = utils.AddMod();
@ -165,7 +166,7 @@ namespace Wabbajack.Test
utils.AddManualDownload( utils.AddManualDownload(
new Dictionary<string, byte[]> { { "/baz/biz.pex", File.ReadAllBytes(ini) } }); new Dictionary<string, byte[]> { { "/baz/biz.pex", File.ReadAllBytes(ini) } });
var modlist = CompileAndInstall(profile); var modlist = await CompileAndInstall(profile);
var directive = modlist.Directives.Where(m => m.To == $"mods\\{mod}\\foo.ini").FirstOrDefault(); var directive = modlist.Directives.Where(m => m.To == $"mods\\{mod}\\foo.ini").FirstOrDefault();
Assert.IsNotNull(directive); Assert.IsNotNull(directive);
@ -173,7 +174,7 @@ namespace Wabbajack.Test
} }
[TestMethod] [TestMethod]
public void ModifiedIniFilesArePatchedAgainstFileWithSameName() public async Task ModifiedIniFilesArePatchedAgainstFileWithSameName()
{ {
var profile = utils.AddProfile(); var profile = utils.AddProfile();
var mod = utils.AddMod(); var mod = utils.AddMod();
@ -195,7 +196,7 @@ namespace Wabbajack.Test
// Modify after creating mod archive in the downloads folder // Modify after creating mod archive in the downloads folder
File.WriteAllText(ini, "Wabbajack, Wabbajack, Wabbajack!"); File.WriteAllText(ini, "Wabbajack, Wabbajack, Wabbajack!");
var modlist = CompileAndInstall(profile); var modlist = await CompileAndInstall(profile);
var directive = modlist.Directives.Where(m => m.To == $"mods\\{mod}\\foo.ini").FirstOrDefault(); var directive = modlist.Directives.Where(m => m.To == $"mods\\{mod}\\foo.ini").FirstOrDefault();
Assert.IsNotNull(directive); Assert.IsNotNull(directive);

View File

@ -1,5 +1,6 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks;
using Alphaleonis.Win32.Filesystem; using Alphaleonis.Win32.Filesystem;
using Microsoft.VisualStudio.TestTools.UnitTesting; using Microsoft.VisualStudio.TestTools.UnitTesting;
using Wabbajack.Common; using Wabbajack.Common;
@ -11,7 +12,7 @@ namespace Wabbajack.Test
public class zEditIntegrationTests : ACompilerTest public class zEditIntegrationTests : ACompilerTest
{ {
[TestMethod] [TestMethod]
public void CanCreatezEditPatches() public async Task CanCreatezEditPatches()
{ {
var profile = utils.AddProfile(); var profile = utils.AddProfile();
var moda = utils.AddMod(); var moda = utils.AddMod();
@ -72,7 +73,7 @@ namespace Wabbajack.Test
}); });
var modlist = CompileAndInstall(profile); var modlist = await CompileAndInstall(profile);
var directive = modlist.Directives.Where(m => m.To == $"mods\\{moddest}\\merged.esp").FirstOrDefault(); var directive = modlist.Directives.Where(m => m.To == $"mods\\{moddest}\\merged.esp").FirstOrDefault();
Assert.IsNotNull(directive); Assert.IsNotNull(directive);

View File

@ -47,7 +47,7 @@ namespace Wabbajack.VirtualFileSystem.Test
{ {
await context.AddRoot(VFS_TEST_DIR_FULL); await context.AddRoot(VFS_TEST_DIR_FULL);
await context.WriteToFile(Path.Combine(VFS_TEST_DIR_FULL, "vfs_cache.bin")); await context.WriteToFile(Path.Combine(VFS_TEST_DIR_FULL, "vfs_cache.bin"));
context.IntegrateFromFile(Path.Combine(VFS_TEST_DIR_FULL, "vfs_cache.bin")); await context.IntegrateFromFile(Path.Combine(VFS_TEST_DIR_FULL, "vfs_cache.bin"));
} }

View File

@ -72,7 +72,7 @@ namespace Wabbajack.VirtualFileSystem
return await VirtualFile.Analyze(this, null, f, f); return await VirtualFile.Analyze(this, null, f, f);
}); });
var newIndex = IndexRoot.Empty.Integrate(filtered.Concat(allFiles).ToList()); var newIndex = await IndexRoot.Empty.Integrate(filtered.Concat(allFiles).ToList());
lock (this) lock (this)
{ {
@ -108,7 +108,7 @@ namespace Wabbajack.VirtualFileSystem
return await VirtualFile.Analyze(this, null, f, f); return await VirtualFile.Analyze(this, null, f, f);
}); });
var newIndex = IndexRoot.Empty.Integrate(filtered.Concat(allFiles).ToList()); var newIndex = await IndexRoot.Empty.Integrate(filtered.Concat(allFiles).ToList());
lock (this) lock (this)
{ {
@ -166,7 +166,7 @@ namespace Wabbajack.VirtualFileSystem
} }
} }
public void IntegrateFromFile(string filename) public async Task IntegrateFromFile(string filename)
{ {
try try
{ {
@ -188,7 +188,7 @@ namespace Wabbajack.VirtualFileSystem
br.BaseStream.Read(bytes, 0, (int) size); br.BaseStream.Read(bytes, 0, (int) size);
return VirtualFile.Read(this, bytes); return VirtualFile.Read(this, bytes);
}).ToList(); }).ToList();
var newIndex = Index.Integrate(files); var newIndex = await Index.Integrate(files);
lock (this) lock (this)
{ {
Index = newIndex; Index = newIndex;
@ -252,7 +252,7 @@ namespace Wabbajack.VirtualFileSystem
var parents = await indexedState[""] var parents = await indexedState[""]
.PMap(Queue,f => VirtualFile.CreateFromPortable(this, indexedState, links, f)); .PMap(Queue,f => VirtualFile.CreateFromPortable(this, indexedState, links, f));
var newIndex = Index.Integrate(parents); var newIndex = await Index.Integrate(parents);
lock (this) lock (this)
{ {
Index = newIndex; Index = newIndex;
@ -273,7 +273,7 @@ namespace Wabbajack.VirtualFileSystem
_knownFiles.AddRange(known); _knownFiles.AddRange(known);
} }
public void BackfillMissing() public async Task BackfillMissing()
{ {
var newFiles = _knownFiles.Where(f => f.Paths.Length == 1) var newFiles = _knownFiles.Where(f => f.Paths.Length == 1)
.GroupBy(f => f.Hash) .GroupBy(f => f.Hash)
@ -307,7 +307,7 @@ namespace Wabbajack.VirtualFileSystem
} }
_knownFiles.Where(f => f.Paths.Length > 1).Do(BackFillOne); _knownFiles.Where(f => f.Paths.Length > 1).Do(BackFillOne);
var newIndex = Index.Integrate(newFiles.Values.ToList()); var newIndex = await Index.Integrate(newFiles.Values.ToList());
lock (this) lock (this)
Index = newIndex; Index = newIndex;
@ -373,7 +373,7 @@ namespace Wabbajack.VirtualFileSystem
public ImmutableDictionary<string, ImmutableStack<VirtualFile>> ByName { get; set; } public ImmutableDictionary<string, ImmutableStack<VirtualFile>> ByName { get; set; }
public ImmutableDictionary<string, VirtualFile> ByRootPath { get; } public ImmutableDictionary<string, VirtualFile> ByRootPath { get; }
public IndexRoot Integrate(ICollection<VirtualFile> files) public async Task<IndexRoot> Integrate(ICollection<VirtualFile> files)
{ {
Utils.Log($"Integrating {files.Count} files"); Utils.Log($"Integrating {files.Count} files");
var allFiles = AllFiles.Concat(files).GroupBy(f => f.Name).Select(g => g.Last()).ToImmutableList(); var allFiles = AllFiles.Concat(files).GroupBy(f => f.Name).Select(g => g.Last()).ToImmutableList();
@ -391,10 +391,10 @@ namespace Wabbajack.VirtualFileSystem
var byRootPath = Task.Run(() => allFiles.ToImmutableDictionary(f => f.Name)); var byRootPath = Task.Run(() => allFiles.ToImmutableDictionary(f => f.Name));
var result = new IndexRoot(allFiles, var result = new IndexRoot(allFiles,
byFullPath.Result, await byFullPath,
byHash.Result, await byHash,
byRootPath.Result, await byRootPath,
byName.Result); await byName);
Utils.Log($"Done integrating"); Utils.Log($"Done integrating");
return result; return result;
} }