Skip to content

Commit

Permalink
Proportional, granular progress updates for installing
Browse files Browse the repository at this point in the history
  • Loading branch information
HebaruSan committed Mar 11, 2024
1 parent 7b66b1e commit 35f0ae6
Show file tree
Hide file tree
Showing 13 changed files with 243 additions and 168 deletions.
8 changes: 3 additions & 5 deletions ConsoleUI/InstallScreen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,8 @@ public override void Run(ConsoleTheme theme, Action<ConsoleTheme> process = null

HashSet<string> possibleConfigOnlyDirs = null;

ModuleInstaller inst = new ModuleInstaller(manager.CurrentInstance, manager.Cache, this)
{
onReportModInstalled = OnModInstalled
};
ModuleInstaller inst = new ModuleInstaller(manager.CurrentInstance, manager.Cache, this);
inst.onReportModInstalled += OnModInstalled;
if (plan.Remove.Count > 0) {
inst.UninstallList(plan.Remove, ref possibleConfigOnlyDirs, regMgr, true, new List<CkanModule>(plan.Install));
plan.Remove.Clear();
Expand Down Expand Up @@ -103,9 +101,9 @@ public override void Run(ConsoleTheme theme, Action<ConsoleTheme> process = null
}

trans.Complete();
inst.onReportModInstalled -= OnModInstalled;
// Don't let the installer re-use old screen references
inst.User = null;
inst.onReportModInstalled = null;

} catch (CancelledActionKraken) {
// Don't need to tell the user they just cancelled out.
Expand Down
6 changes: 6 additions & 0 deletions Core/Extensions/IOExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,12 @@ public static void CopyTo(this Stream src,
lastProgressTime = now;
}
}
if (timer != null)
{
timer.Stop();
timer.Close();
timer = null;
}
// Make sure we get a final progress notification after we're done
progress.Report(total);
}
Expand Down
311 changes: 187 additions & 124 deletions Core/ModuleInstaller.cs

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions Core/Registry/Registry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -829,10 +829,10 @@ public List<CkanModule> LatestAvailableWithProvides(
/// Register the supplied module as having been installed, thereby keeping
/// track of its metadata and files.
/// </summary>
public void RegisterModule(CkanModule mod,
IEnumerable<string> absoluteFiles,
GameInstance inst,
bool autoInstalled)
public void RegisterModule(CkanModule mod,
List<string> absoluteFiles,
GameInstance inst,
bool autoInstalled)
{
log.DebugFormat("Registering module {0}", mod);
EnlistWithTransaction();
Expand Down
18 changes: 12 additions & 6 deletions Core/Repositories/ProgressFilesOffsetsToPercent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,15 @@ public ProgressFilesOffsetsToPercent(IProgress<int> percentProgress,
/// <param name="currentFileOffset">How far into the current file we are</param>
public void Report(long currentFileOffset)
{
var percent = basePercent + (int)(100 * currentFileOffset / totalSize);
// Only report each percentage once, to avoid spamming UI calls
if (percent > lastPercent)
if (totalSize > 0)
{
percentProgress.Report(percent);
lastPercent = percent;
var percent = basePercent + (int)(100 * currentFileOffset / totalSize);
// Only report each percentage once, to avoid spamming UI calls
if (percent > lastPercent)
{
percentProgress.Report(percent);
lastPercent = percent;
}
}
}

Expand All @@ -44,7 +47,10 @@ public void Report(long currentFileOffset)
public void NextFile()
{
doneSize += sizes[currentIndex];
basePercent = (int)(100 * doneSize / totalSize);
if (totalSize > 0)
{
basePercent = (int)(100 * doneSize / totalSize);
}
++currentIndex;
if (basePercent > lastPercent)
{
Expand Down
7 changes: 5 additions & 2 deletions Core/Repositories/ProgressScalePercentsByFileSize.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public ProgressScalePercentsByFileSizes(IProgress<int> percentProgress,
/// <param name="currentFilePercent">How far into the current file we are</param>
public void Report(int currentFilePercent)
{
if (basePercent < 100 && currentIndex < sizes.Length)
if (basePercent < 100 && currentIndex < sizes.Length && totalSize > 0)
{
var percent = basePercent + (int)(currentFilePercent * sizes[currentIndex] / totalSize);
// Only report each percentage once, to avoid spamming UI calls
Expand All @@ -47,7 +47,10 @@ public void Report(int currentFilePercent)
public void NextFile()
{
doneSize += sizes[currentIndex];
basePercent = (int)(100 * doneSize / totalSize);
if (totalSize > 0)
{
basePercent = (int)(100 * doneSize / totalSize);
}
++currentIndex;
if (basePercent > lastPercent)
{
Expand Down
4 changes: 2 additions & 2 deletions Tests/CmdLine/UpgradeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public void RunCommand_IdentifierEqualsVersionSyntax_UpgradesToCorrectVersion(
regMgr.registry.RepositoriesAdd(repo.repo);
var fromModule = regMgr.registry.GetModuleByVersion(identifier, fromVersion);
var toModule = regMgr.registry.GetModuleByVersion(identifier, toVersion);
regMgr.registry.RegisterModule(fromModule, Enumerable.Empty<string>(), inst.KSP, false);
regMgr.registry.RegisterModule(fromModule, new List<string>(), inst.KSP, false);
manager.Cache.Store(toModule, TestData.DogeCoinFlagZip(), null);
var opts = new UpgradeOptions()
{
Expand Down Expand Up @@ -598,7 +598,7 @@ public void RunCommand_VersionDependsUpgrade_UpgradesCorrectly(string descript
foreach (var fromModule in instMods)
{
regMgr.registry.RegisterModule(fromModule,
Enumerable.Empty<string>(),
new List<string>(),
inst.KSP, false);
}
// Pre-store mods that might be installed
Expand Down
18 changes: 9 additions & 9 deletions Tests/Core/ModuleInstallerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ public void DontOverWrite_208()

Assert.Throws<FileExistsKraken>(delegate
{
ModuleInstaller.CopyZipEntry(zipfile, entry, tmpfile, false);
ModuleInstaller.CopyZipEntry(zipfile, entry, tmpfile, false, null);
});

// Cleanup
Expand Down Expand Up @@ -357,7 +357,7 @@ private string CopyDogeFromZip()

// We have to delete our temporary file, as CZE refuses to overwrite; huzzah!
File.Delete(tmpfile);
ModuleInstaller.CopyZipEntry(zipfile, entry, tmpfile, false);
ModuleInstaller.CopyZipEntry(zipfile, entry, tmpfile, false, null);

return tmpfile;
}
Expand Down Expand Up @@ -662,7 +662,7 @@ public void GroupFilesByRemovable_WithFiles_CorrectOutput(string relRoot,
var registry = RegistryManager.Instance(inst.KSP, repoData.Manager).registry;
// Make files to be registered to another mod
var absFiles = registeredFiles.Select(f => inst.KSP.ToAbsoluteGameDir(f))
.ToArray();
.ToList();
foreach (var absPath in absFiles)
{
Directory.CreateDirectory(Path.GetDirectoryName(absPath));
Expand Down Expand Up @@ -874,7 +874,7 @@ public void Replace_WithCompatibleModule_Succeeds()
var downloader = new NetAsyncModulesDownloader(nullUser, manager.Cache);

// Act
registry.RegisterModule(replaced, Enumerable.Empty<string>(), inst.KSP, false);
registry.RegisterModule(replaced, new List<string>(), inst.KSP, false);
manager.Cache.Store(replaced, TestData.DogeCoinFlagZip(), new Progress<long>(bytes => {}));
var replacement = querier.GetReplacement(replaced.identifier,
new GameVersionCriteria(new GameVersion(1, 12)));
Expand Down Expand Up @@ -940,7 +940,7 @@ public void Replace_WithIncompatibleModule_Fails()
var downloader = new NetAsyncModulesDownloader(nullUser, manager.Cache);

// Act
registry.RegisterModule(replaced, Enumerable.Empty<string>(), inst.KSP, false);
registry.RegisterModule(replaced, new List<string>(), inst.KSP, false);
manager.Cache.Store(replaced, TestData.DogeCoinFlagZip(), new Progress<long>(bytes => {}));
var replacement = querier.GetReplacement(replaced.identifier,
new GameVersionCriteria(new GameVersion(1, 11)));
Expand Down Expand Up @@ -1006,14 +1006,14 @@ public void UninstallList_WithAutoInst_RemovesAutoRemovable(string[] regularMods
foreach (var m in regularMods)
{
registry.RegisterModule(CkanModule.FromJson(m),
Enumerable.Empty<string>(),
new List<string>(),
inst.KSP,
false);
}
foreach (var m in autoInstMods)
{
registry.RegisterModule(CkanModule.FromJson(m),
Enumerable.Empty<string>(),
new List<string>(),
inst.KSP,
true);
}
Expand Down Expand Up @@ -1098,15 +1098,15 @@ public void Upgrade_WithAutoInst_RemovesAutoRemovable(string[] regularMods,
if (!querier.IsInstalled(module.identifier, false))
{
registry.RegisterModule(module,
Enumerable.Empty<string>(),
new List<string>(),
inst.KSP,
false);
}
}
foreach (var m in autoInstMods)
{
registry.RegisterModule(CkanModule.FromJson(m),
Enumerable.Empty<string>(),
new List<string>(),
inst.KSP,
true);
}
Expand Down
19 changes: 9 additions & 10 deletions Tests/Core/Registry/Registry.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using System;
using System.IO;
using System.Transactions;
using System.Collections.Generic;
Expand Down Expand Up @@ -316,8 +315,8 @@ public void HasUpdate_OtherModDependsOnCurrent_ReturnsFalse()
CkanModule dependingMod = registry.GetModuleByVersion("DependingMod", "1.0");

GameInstance gameInst = gameInstWrapper.KSP;
registry.RegisterModule(olderDepMod, Array.Empty<string>(), gameInst, false);
registry.RegisterModule(dependingMod, Array.Empty<string>(), gameInst, false);
registry.RegisterModule(olderDepMod, new List<string>(), gameInst, false);
registry.RegisterModule(dependingMod, new List<string>(), gameInst, false);
GameVersionCriteria crit = new GameVersionCriteria(olderDepMod.ksp_version);

// Act
Expand Down Expand Up @@ -420,7 +419,7 @@ public void TxEmbeddedCommit()
using (var tScope = new TransactionScope())
{
reg = CKAN.Registry.Empty();
reg.RegisterModule(module, Enumerable.Empty<string>(),
reg.RegisterModule(module, new List<string>(),
gameInstWrapper.KSP, false);

CollectionAssert.AreEqual(
Expand Down Expand Up @@ -451,7 +450,7 @@ public void TxCommit()
using (var gameInstWrapper = new DisposableKSP())
using (var tScope = new TransactionScope())
{
registry.RegisterModule(module, Enumerable.Empty<string>(),
registry.RegisterModule(module, new List<string>(),
gameInstWrapper.KSP, false);

CollectionAssert.AreEqual(
Expand Down Expand Up @@ -481,7 +480,7 @@ public void TxRollback()
""version"": ""1.0"",
""download"": ""https://github.com/""
}");
registry.RegisterModule(module, Enumerable.Empty<string>(),
registry.RegisterModule(module, new List<string>(),
gameInstWrapper.KSP, false);

CollectionAssert.AreEqual(
Expand Down Expand Up @@ -515,7 +514,7 @@ public void TxNested()
""version"": ""1.0"",
""download"": ""https://github.com/""
}");
registry.RegisterModule(module, Enumerable.Empty<string>(),
registry.RegisterModule(module, new List<string>(),
gameInstWrapper.KSP, false);

using (var tScope2 = new TransactionScope(TransactionScopeOption.RequiresNew))
Expand All @@ -528,7 +527,7 @@ public void TxNested()
""version"": ""1.0"",
""download"": ""https://github.com/""
}");
registry.RegisterModule(module2, Enumerable.Empty<string>(),
registry.RegisterModule(module2, new List<string>(),
gameInstWrapper.KSP, false);
});
tScope2.Complete();
Expand All @@ -553,7 +552,7 @@ public void TxAmbient()
""version"": ""1.0"",
""download"": ""https://github.com/""
}");
registry.RegisterModule(module, Enumerable.Empty<string>(),
registry.RegisterModule(module, new List<string>(),
gameInstWrapper.KSP, false);

using (var tScope2 = new TransactionScope())
Expand All @@ -566,7 +565,7 @@ public void TxAmbient()
""version"": ""1.0"",
""download"": ""https://github.com/""
}");
registry.RegisterModule(module2, Enumerable.Empty<string>(),
registry.RegisterModule(module2, new List<string>(),
gameInstWrapper.KSP, false);
});
tScope2.Complete();
Expand Down
2 changes: 1 addition & 1 deletion Tests/Core/Registry/RegistryManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ public void ScanUnmanagedFiles_WithDLLs_FindsUnregisteredOnly(string[] registere
var regMgr = RegistryManager.Instance(gameInst, repoData.Manager);
var registry = regMgr.registry;
var absReg = registered.Select(p => gameInst.ToAbsoluteGameDir(p))
.ToArray();
.ToList();
var absUnreg = unregistered.Select(p => gameInst.ToAbsoluteGameDir(p))
.ToArray();

Expand Down
6 changes: 3 additions & 3 deletions Tests/Core/Relationships/RelationshipResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ public void ModList_WithInstalledModules_ContainsThemWithReasonInstalled()
var registry = new CKAN.Registry(repoData.Manager, repo.repo);
var list = new List<CkanModule> { mod_a };

registry.RegisterModule(mod_a, Array.Empty<string>(), null, false);
registry.RegisterModule(mod_a, new List<string>(), null, false);

var relationship_resolver = new RelationshipResolver(
list, null, options, registry, null);
Expand Down Expand Up @@ -1036,8 +1036,8 @@ public void UninstallingConflictingModule_InstallingRecursiveDependencies_Resolv
var registry = new CKAN.Registry(repoData.Manager, repo.repo);

// Start with eve and eveDefaultConfig installed
registry.RegisterModule(eve, Array.Empty<string>(), ksp.KSP, false);
registry.RegisterModule(eveDefaultConfig, Array.Empty<string>(), ksp.KSP, false);
registry.RegisterModule(eve, new List<string>(), ksp.KSP, false);
registry.RegisterModule(eveDefaultConfig, new List<string>(), ksp.KSP, false);

Assert.DoesNotThrow(() => registry.CheckSanity());

Expand Down
2 changes: 1 addition & 1 deletion Tests/GUI/Model/GUIMod.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public void HasUpdate_UpdateAvailable_ReturnsTrue()
{
var registry = new Registry(repoData.Manager, repo.repo);

registry.RegisterModule(old_version, Enumerable.Empty<string>(), null, false);
registry.RegisterModule(old_version, new List<string>(), null, false);
var upgradeableGroups = registry.CheckUpgradeable(tidy.KSP.VersionCriteria(),
new HashSet<string>());

Expand Down
2 changes: 1 addition & 1 deletion Tests/GUI/Model/ModList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ public void InstallAndSortByCompat_WithAnyCompat_NoCrash()

// Install module and set it as pre-installed
manager.Cache.Store(TestData.DogeCoinFlag_101_module(), TestData.DogeCoinFlagZip(), new Progress<long>(bytes => {}));
registry.RegisterModule(anyVersionModule, Array.Empty<string>(), instance.KSP, false);
registry.RegisterModule(anyVersionModule, new List<string>(), instance.KSP, false);

HashSet<string> possibleConfigOnlyDirs = null;
installer.InstallList(
Expand Down

0 comments on commit 35f0ae6

Please sign in to comment.