From 5260d5c62afd789adea8db71555f655627d8a97f Mon Sep 17 00:00:00 2001 From: Anairkoen Schno Date: Sun, 5 Apr 2020 01:27:18 -0500 Subject: [PATCH] Changed disable logic to only disable if all dependents could be disabled --- IPA.Loader/Loader/CannotRuntimeDisableException.cs | 7 +++++++ IPA.Loader/Loader/PluginManager.cs | 7 +++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/IPA.Loader/Loader/CannotRuntimeDisableException.cs b/IPA.Loader/Loader/CannotRuntimeDisableException.cs index fe0e9973..da608f19 100644 --- a/IPA.Loader/Loader/CannotRuntimeDisableException.cs +++ b/IPA.Loader/Loader/CannotRuntimeDisableException.cs @@ -22,6 +22,13 @@ namespace IPA.Loader /// the plugin that cannot be disabled public CannotRuntimeDisableException(PluginMetadata plugin) : base($"Cannot runtime disable plugin \"{plugin.Name}\" ({plugin.Id})") => Plugin = plugin; + /// + /// Creats an exception with the given plugin metadata and message information. + /// + /// the plugin that cannot be disabled + /// the message to associate with it + public CannotRuntimeDisableException(PluginMetadata plugin, string message) : base($"{message} \"{plugin.Name}\" ({plugin.Id})") + => Plugin = plugin; /// /// Creates an exception from a serialization context. Not currently implemented. diff --git a/IPA.Loader/Loader/PluginManager.cs b/IPA.Loader/Loader/PluginManager.cs index 62002591..72b9ee46 100644 --- a/IPA.Loader/Loader/PluginManager.cs +++ b/IPA.Loader/Loader/PluginManager.cs @@ -190,8 +190,11 @@ namespace IPA.Loader return TaskEx6.FromException(new CannotRuntimeDisableException(exec.Executor.Metadata)); var res = TaskEx.WhenAll(exec.Dependents.Select(d => Disable(d, alreadyDisabled))) - .ContinueWith(t => TaskEx.WhenAll(t, exec.Executor.Disable()), UnityMainThreadTaskScheduler.Default).Unwrap(); - // The WhenAll above allows us to wait for the executor to disable, but still propagate errors + .ContinueWith(t => t.IsFaulted + ? TaskEx.WhenAll(t, TaskEx6.FromException( + new CannotRuntimeDisableException(exec.Executor.Metadata, "Dependents cannot be disabled for plugin"))) + : exec.Executor.Disable(), UnityMainThreadTaskScheduler.Default).Unwrap(); + // We do not want to call the disable method if a dependent couldn't be disabled // By scheduling on a UnityMainThreadScheduler, we ensure that Disable() is always called on the Unity main thread alreadyDisabled.Add(exec.Executor, res); return res;