Skip to content

Commit

Permalink
Fix slow response to checkbox changes
Browse files Browse the repository at this point in the history
  • Loading branch information
HebaruSan committed Mar 12, 2018
1 parent 624839f commit 900701b
Show file tree
Hide file tree
Showing 15 changed files with 450 additions and 470 deletions.
2 changes: 1 addition & 1 deletion Cmdline/Action/Import.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public int RunCommand(CKAN.KSP ksp, object options)
log.InfoFormat("Importing {0} files", toImport.Count);
List<string> toInstall = new List<string>();
ModuleInstaller inst = ModuleInstaller.GetInstance(ksp, user);
inst.ImportFiles(toImport, user, id => toInstall.Add(id), !opts.Headless);
inst.ImportFiles(toImport, user, mod => toInstall.Add(mod.identifier), !opts.Headless);
if (toInstall.Count > 0)
{
inst.InstallList(
Expand Down
105 changes: 43 additions & 62 deletions ConsoleUI/DependencyScreen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,12 @@ public DependencyScreen(KSPManager mgr, ChangePlan cp, HashSet<string> rej, bool
new ConsoleListBoxColumn<Dependency>() {
Header = "Install",
Width = 7,
Renderer = (Dependency d) => StatusSymbol(d.identifier),
Renderer = (Dependency d) => StatusSymbol(d.module)
},
new ConsoleListBoxColumn<Dependency>() {
Header = "Name",
Width = 24,
Renderer = (Dependency d) => d.identifier,
Width = 36,
Renderer = (Dependency d) => d.module.ToString()
},
new ConsoleListBoxColumn<Dependency>() {
Header = "Sources",
Expand All @@ -56,7 +56,7 @@ public DependencyScreen(KSPManager mgr, ChangePlan cp, HashSet<string> rej, bool
);
dependencyList.AddTip("+", "Toggle");
dependencyList.AddBinding(Keys.Plus, (object sender) => {
ChangePlan.toggleContains(accepted, dependencyList.Selection.identifier);
ChangePlan.toggleContains(accepted, dependencyList.Selection.module);
return true;
});

Expand All @@ -81,7 +81,7 @@ public DependencyScreen(KSPManager mgr, ChangePlan cp, HashSet<string> rej, bool
if (dependencyList.Selection != null) {
LaunchSubScreen(new ModInfoScreen(
manager, plan,
registry.LatestAvailable(dependencyList.Selection.identifier, manager.CurrentInstance.VersionCriteria()),
dependencyList.Selection.module,
debug
));
}
Expand All @@ -94,20 +94,20 @@ public DependencyScreen(KSPManager mgr, ChangePlan cp, HashSet<string> rej, bool
AddBinding(Keys.Escape, (object sender) => {
// Add everything to rejected
foreach (var kvp in dependencies) {
rejected.Add(kvp.Key);
rejected.Add(kvp.Key.identifier);
}
return false;
});

AddTip("F9", "Accept");
AddBinding(Keys.F9, (object sender) => {
foreach (string name in accepted) {
plan.Install.Add(name);
foreach (CkanModule mod in accepted) {
plan.Install.Add(mod);
}
// Add the rest to rejected
foreach (var kvp in dependencies) {
if (!accepted.Contains(kvp.Key)) {
rejected.Add(kvp.Key);
rejected.Add(kvp.Key.identifier);
}
}
return false;
Expand All @@ -126,94 +126,75 @@ public bool HaveOptions()
return dependencies.Count > 0;
}

private void generateList(HashSet<string> inst)
private void generateList(HashSet<CkanModule> inst)
{
foreach (string mod in inst) {
CkanModule m = registry.LatestAvailable(mod, manager.CurrentInstance.VersionCriteria());
if (m != null) {
AddDependencies(inst, mod, m.recommends, true);
AddDependencies(inst, mod, m.suggests, false);
}
foreach (CkanModule mod in inst) {
AddDependencies(inst, mod, mod.recommends, true);
AddDependencies(inst, mod, mod.suggests, false);
}
}

private void AddDependencies(HashSet<string> alreadyInstalling, string identifier, List<RelationshipDescriptor> source, bool installByDefault)
private void AddDependencies(HashSet<CkanModule> alreadyInstalling, CkanModule dependent, List<RelationshipDescriptor> source, bool installByDefault)
{
if (source != null) {
foreach (RelationshipDescriptor dependency in source) {
if (!rejected.Contains(dependency.name)) {
try {
if (registry.LatestAvailable(
dependency.name,
manager.CurrentInstance.VersionCriteria(),
dependency
) != null
&& !registry.IsInstalled(dependency.name)
&& !alreadyInstalling.Contains(dependency.name)) {

AddDep(dependency.name, installByDefault, identifier);
}
} catch (ModuleNotFoundKraken) {
// LatestAvailable throws if you recommend a "provides" name,
// so ask the registry again for provides-based choices
List<CkanModule> opts = registry.LatestAvailableWithProvides(
dependency.name,
manager.CurrentInstance.VersionCriteria(),
dependency
);
foreach (CkanModule provider in opts) {
if (!registry.IsInstalled(provider.identifier)
&& !alreadyInstalling.Contains(provider.identifier)) {

// Default to not installing because these probably conflict with each other
AddDep(provider.identifier, false, identifier);
}
// LatestAvailable throws if you recommend a "provides" name,
// so ask the registry again for provides-based choices
List<CkanModule> opts = registry.LatestAvailableWithProvides(
dependency.name,
manager.CurrentInstance.VersionCriteria(),
dependency
);
foreach (CkanModule provider in opts) {
if (!registry.IsInstalled(provider.identifier)
&& !alreadyInstalling.Contains(provider)) {

// Default to not installing because these probably conflict with each other
AddDep(provider, installByDefault, dependent);
}
} catch (Kraken) {
// GUI/MainInstall.cs::AddMod just ignores all exceptions,
// so that's baked into the infrastructure
}
}
}
}
}

private void AddDep(string identifier, bool defaultInstall, string dependent)
private void AddDep(CkanModule mod, bool defaultInstall, CkanModule dependent)
{
if (dependencies.ContainsKey(identifier)) {
dependencies[identifier].defaultInstall |= defaultInstall;
dependencies[identifier].dependents.Add(dependent);
if (dependencies.ContainsKey(mod)) {
dependencies[mod].defaultInstall |= defaultInstall;
dependencies[mod].dependents.Add(dependent);
} else {
dependencies.Add(identifier, new Dependency() {
identifier = identifier,
dependencies.Add(mod, new Dependency() {
module = mod,
defaultInstall = defaultInstall,
dependents = new List<string>() {dependent}
dependents = new List<CkanModule>() { dependent }
});
}
if (defaultInstall) {
accepted.Add(identifier);
accepted.Add(mod);
}
}

private string StatusSymbol(string identifier)
private string StatusSymbol(CkanModule mod)
{
if (accepted.Contains(identifier)) {
if (accepted.Contains(mod)) {
return installing;
} else {
return notinstalled;
}
}

private HashSet<string> accepted = new HashSet<string>();
private HashSet<CkanModule> accepted = new HashSet<CkanModule>();
private HashSet<string> rejected;

private IRegistryQuerier registry;
private KSPManager manager;
private ChangePlan plan;
private bool debug;

private Dictionary<string, Dependency> dependencies = new Dictionary<string, Dependency>();
private ConsoleListBox<Dependency> dependencyList;
private Dictionary<CkanModule, Dependency> dependencies = new Dictionary<CkanModule, Dependency>();
private ConsoleListBox<Dependency> dependencyList;

private static readonly string notinstalled = " ";
private static readonly string installing = "+";
Expand All @@ -227,17 +208,17 @@ public class Dependency {
/// <summary>
/// Identifier of mod
/// </summary>
public string identifier;
public CkanModule module;

/// <summary>
/// True if we default to installing, false otherwise
/// </summary>
public bool defaultInstall;
public bool defaultInstall;

/// <summary>
/// List of mods that recommended or suggested this mod
/// </summary>
public List<string> dependents = new List<string>();
public List<CkanModule> dependents = new List<CkanModule>();
}

}
2 changes: 1 addition & 1 deletion ConsoleUI/DownloadImportDialog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public static void ImportDownloads(KSP gameInst, ChangePlan cp)
ProgressScreen ps = new ProgressScreen("Importing Downloads", "Calculating...");
ModuleInstaller inst = ModuleInstaller.GetInstance(gameInst, ps);
ps.Run(() => inst.ImportFiles(files, ps,
(string identifier) => cp.Install.Add(identifier)));
(CkanModule mod) => cp.Install.Add(mod)));
// Don't let the installer re-use old screen references
inst.User = null;
}
Expand Down
16 changes: 6 additions & 10 deletions ConsoleUI/InstallScreen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public override void Run(Action process = null)
plan.Upgrade.Clear();
}
if (plan.Install.Count > 0) {
List<string> iList = new List<string>(plan.Install);
List<CkanModule> iList = new List<CkanModule>(plan.Install);
inst.InstallList(iList, resolvOpts, dl);
plan.Install.Clear();
}
Expand Down Expand Up @@ -109,19 +109,15 @@ public override void Run(Action process = null)
RaiseError(ex.InconsistenciesPretty);
} catch (TooManyModsProvideKraken ex) {

List<string> opts = new List<string>();
foreach (CkanModule opt in ex.modules) {
opts.Add(opt.identifier);
}
ConsoleChoiceDialog<string> ch = new ConsoleChoiceDialog<string>(
ConsoleChoiceDialog<CkanModule> ch = new ConsoleChoiceDialog<CkanModule>(
$"Module {ex.requested} is provided by multiple modules. Which would you like to install?",
"Name",
opts,
(string s) => s
ex.modules,
(CkanModule mod) => mod.ToString()
);
string chosen = ch.Run();
CkanModule chosen = ch.Run();
DrawBackground();
if (!string.IsNullOrEmpty(chosen)) {
if (chosen != null) {
// Use chosen to continue installing
plan.Install.Add(chosen);
retry = true;
Expand Down
71 changes: 45 additions & 26 deletions ConsoleUI/ModListScreen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -174,10 +174,10 @@ public ModListScreen(KSPManager mgr, bool dbg)
moduleList.AddBinding(Keys.Plus, (object sender) => {
if (moduleList.Selection != null) {
if (!registry.IsInstalled(moduleList.Selection.identifier, false)) {
plan.ToggleInstall(moduleList.Selection.identifier);
plan.ToggleInstall(moduleList.Selection);
} else if (registry.IsInstalled(moduleList.Selection.identifier, false)
&& registry.HasUpdate(moduleList.Selection.identifier, manager.CurrentInstance.VersionCriteria())) {
plan.ToggleUpgrade(moduleList.Selection.identifier);
plan.ToggleUpgrade(moduleList.Selection);
}
}
return true;
Expand All @@ -189,7 +189,7 @@ public ModListScreen(KSPManager mgr, bool dbg)
);
moduleList.AddBinding(Keys.Minus, (object sender) => {
if (moduleList.Selection != null && registry.IsInstalled(moduleList.Selection.identifier, false)) {
plan.ToggleRemove(moduleList.Selection.identifier);
plan.ToggleRemove(moduleList.Selection);
}
return true;
});
Expand Down Expand Up @@ -325,7 +325,7 @@ private bool ViewSuggestions()
// Only check mods that are still available
try {
if (registry.LatestAvailable(im.identifier, manager.CurrentInstance.VersionCriteria()) != null) {
reinstall.Install.Add(im.identifier);
reinstall.Install.Add(im.Module);
}
} catch {
// The registry object badly needs an IsAvailable check
Expand All @@ -337,8 +337,8 @@ private bool ViewSuggestions()
LaunchSubScreen(ds);
bool needRefresh = false;
// Copy the right ones into our real plan
foreach (string mod in reinstall.Install) {
if (!registry.IsInstalled(mod, false)) {
foreach (CkanModule mod in reinstall.Install) {
if (!registry.IsInstalled(mod.identifier, false)) {
plan.Install.Add(mod);
needRefresh = true;
}
Expand Down Expand Up @@ -582,34 +582,34 @@ public ChangePlan() { }
/// <summary>
/// Add or remove a mod from the remove list
/// </summary>
/// <param name="identifier">The mod to add or remove</param>
public void ToggleRemove(string identifier)
/// <param name="mod">The mod to add or remove</param>
public void ToggleRemove(CkanModule mod)
{
Install.Remove(identifier);
Upgrade.Remove(identifier);
toggleContains(Remove, identifier);
Install.Remove(mod);
Upgrade.Remove(mod.identifier);
toggleContains(Remove, mod.identifier);
}

/// <summary>
/// Add or remove a mod from the install list
/// </summary>
/// <param name="identifier">The mod to add or remove</param>
public void ToggleInstall(string identifier)
/// <param name="mod">The mod to add or remove</param>
public void ToggleInstall(CkanModule mod)
{
Upgrade.Remove(identifier);
Remove.Remove(identifier);
toggleContains(Install, identifier);
Upgrade.Remove(mod.identifier);
Remove.Remove(mod.identifier);
toggleContains(Install, mod);
}

/// <summary>
/// Add or remove a mod from the upgrade list
/// </summary>
/// <param name="identifier">The mod to add or remove</param>
public void ToggleUpgrade(string identifier)
/// <param name="mod">The mod to add or remove</param>
public void ToggleUpgrade(CkanModule mod)
{
Install.Remove(identifier);
Remove.Remove(identifier);
toggleContains(Upgrade, identifier);
Install.Remove(mod);
Remove.Remove(mod.identifier);
toggleContains(Upgrade, mod.identifier);
}

/// <summary>
Expand Down Expand Up @@ -659,11 +659,14 @@ public InstallStatus GetModStatus(KSPManager manager, IRegistryQuerier registry,
return InstallStatus.Installed;
}
} else {
if (Install.Contains(identifier)) {
return InstallStatus.Installing;
} else {
return InstallStatus.NotInstalled;
foreach (CkanModule m in Install)
{
if (m.identifier == identifier)
{
return InstallStatus.Installing;
}
}
return InstallStatus.NotInstalled;
}
}

Expand Down Expand Up @@ -701,10 +704,26 @@ public static void toggleContains(HashSet<string> list, string identifier)
}
}

/// <summary>
/// Add or remove a value from a HashSet
/// </summary>
/// <param name="list">HashSet to manipulate</param>
/// <param name="mod">The value</param>
public static void toggleContains(HashSet<CkanModule> list, CkanModule mod)
{
if (list != null && mod != null) {
if (list.Contains(mod)) {
list.Remove(mod);
} else {
list.Add(mod);
}
}
}

/// <summary>
/// Mods we're planning to install
/// </summary>
public readonly HashSet<string> Install = new HashSet<string>();
public readonly HashSet<CkanModule> Install = new HashSet<CkanModule>();

/// <summary>
/// Mods we're planning to upgrade
Expand Down
Loading

0 comments on commit 900701b

Please sign in to comment.