Browse Source

DisabledConfig now correctly enables and disables mods when reloaded

pull/46/head
Anairkoen Schno 4 years ago
parent
commit
d0d682cdaa
1 changed files with 99 additions and 40 deletions
  1. +99
    -40
      IPA.Loader/Loader/DisabledConfig.cs

+ 99
- 40
IPA.Loader/Loader/DisabledConfig.cs View File

@ -1,44 +1,103 @@
using IPA.Config;
using IPA.Config.Stores;
using IPA.Config.Stores.Attributes;
using IPA.Config.Stores.Converters;
using IPA.Utilities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IPA.Loader
{
internal class DisabledConfig
{
public static Config.Config Disabled { get; set; }
public static DisabledConfig Instance;
public static void Load()
{
Disabled = Config.Config.GetConfigFor("Disabled Mods", "json");
Instance = Disabled.Generated<DisabledConfig>();
}
public virtual bool Reset { get; set; } = true;
[NonNullable]
[UseConverter(typeof(CollectionConverter<string, HashSet<string>>))]
public virtual HashSet<string> DisabledModIds { get; set; } = new HashSet<string>();
protected internal virtual void Changed() { }
protected internal virtual IDisposable ChangeTransaction() => null;
protected virtual void OnReload()
{
using IPA.Config;
using IPA.Config.Stores;
using IPA.Config.Stores.Attributes;
using IPA.Config.Stores.Converters;
using IPA.Logging;
using IPA.Utilities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
#if NET4
using Task = System.Threading.Tasks.Task;
using TaskEx = System.Threading.Tasks.Task;
#endif
#if NET3
using Net3_Proxy;
#endif
namespace IPA.Loader
{
internal class DisabledConfig
{
public static Config.Config Disabled { get; set; }
public static DisabledConfig Instance;
public static void Load()
{
Disabled = Config.Config.GetConfigFor("Disabled Mods", "json");
Instance = Disabled.Generated<DisabledConfig>();
}
public virtual bool Reset { get; set; } = true;
[NonNullable]
[UseConverter(typeof(CollectionConverter<string, HashSet<string>>))]
public virtual HashSet<string> DisabledModIds { get; set; } = new HashSet<string>();
protected internal virtual void Changed() { }
protected internal virtual IDisposable ChangeTransaction() => null;
private Task disableUpdateTask = null;
private int updateState = 0;
protected virtual void OnReload()
{
if (DisabledModIds == null || Reset)
{
DisabledModIds = new HashSet<string>();
Reset = false;
}
}
}
}
}
var referToState = unchecked(++updateState);
var copy = DisabledModIds.ToArray();
if (disableUpdateTask == null || disableUpdateTask.IsCompleted)
{
disableUpdateTask = UpdateDisabledMods(copy);
}
else
{
disableUpdateTask = disableUpdateTask.ContinueWith(t =>
{
// skip if another got here before the last finished
if (referToState != updateState) return TaskEx.WhenAll();
else return UpdateDisabledMods(copy);
});
}
}
private Task UpdateDisabledMods(string[] updateWithDisabled)
{
do
{
using var transaction = PluginManager.PluginStateTransaction();
var disabled = transaction.DisabledPlugins.ToArray();
foreach (var plugin in disabled)
transaction.Enable(plugin, autoDeps: true);
var all = transaction.EnabledPlugins.ToArray();
foreach (var plugin in all.Where(m => updateWithDisabled.Contains(m.Id)))
transaction.Disable(plugin, autoDependents: true);
try
{
return transaction.Commit().ContinueWith(t =>
{
if (t.IsFaulted)
{
Logger.loader.Error("Error changing disabled plugins");
Logger.loader.Error(t.Exception);
}
});
}
catch (InvalidOperationException)
{
continue;
}
}
while (true);
}
}
}

Loading…
Cancel
Save