diff --git a/IPA.Loader/Loader/PluginManager.cs b/IPA.Loader/Loader/PluginManager.cs index f104d1ca..29eac51f 100644 --- a/IPA.Loader/Loader/PluginManager.cs +++ b/IPA.Loader/Loader/PluginManager.cs @@ -66,6 +66,10 @@ namespace IPA.Loader public static PluginMetadata GetDisabledPluginFromId(string name) => DisabledPlugins.FirstOrDefault(p => p.Id == name); + /// + /// Creates a new transaction for mod enabling and disabling mods simultaneously. + /// + /// a new that captures the current state of loaded mods public static StateTransitionTransaction PluginStateTransaction() => new StateTransitionTransaction(AllPlugins, DisabledPlugins); diff --git a/IPA.Loader/Loader/StateTransitionTransaction.cs b/IPA.Loader/Loader/StateTransitionTransaction.cs index 4e2c6388..3fec30cf 100644 --- a/IPA.Loader/Loader/StateTransitionTransaction.cs +++ b/IPA.Loader/Loader/StateTransitionTransaction.cs @@ -6,6 +6,9 @@ using System.Threading.Tasks; namespace IPA.Loader { + /// + /// A class to represent a transaction for changing the state of loaded mods. + /// public sealed class StateTransitionTransaction : IDisposable { private readonly HashSet currentlyEnabled; @@ -19,23 +22,64 @@ namespace IPA.Loader currentlyDisabled = new HashSet(disabled.ToArray()); } + /// + /// Gets whether or not a game restart will be necessary to fully apply this transaction. + /// + /// if any mod who's state is changed cannot be changed at runtime, otherwise public bool WillNeedRestart => toEnable.Concat(toDisable).Any(m => m.RuntimeOptions != RuntimeOptions.DynamicInit); internal IEnumerable ToEnable => toEnable; internal IEnumerable ToDisable => toDisable; - public IEnumerable EnabledPlugins => currentlyEnabled.Except(toDisable).Concat(toEnable); - public IEnumerable DisabledPlugins => currentlyDisabled.Except(toEnable).Concat(toDisable); + /// + /// Gets a list of plugins that are enabled according to this transaction's current state. + /// + public IEnumerable EnabledPlugins + => ThrowIfDisposed>() + ?? currentlyEnabled.Except(toDisable).Concat(toEnable); + /// + /// Gets a list of plugins that are disabled according to this transaction's current state. + /// + public IEnumerable DisabledPlugins + => ThrowIfDisposed>() + ?? currentlyDisabled.Except(toEnable).Concat(toDisable); + /// + /// Checks if a plugin is enabled according to this transaction's current state. + /// + /// + /// This should be roughly equivalent to EnabledPlugins.Contains(meta), but more performant. + /// This should also always return the inverse of for valid plugins. + /// + /// the plugin to check + /// if the plugin is enabled, otherwise + /// + /// public bool IsEnabled(PluginMetadata meta) => ThrowIfDisposed() || (currentlyEnabled.Contains(meta) && !toDisable.Contains(meta)) || toEnable.Contains(meta); + /// + /// Checks if a plugin is disabled according to this transaction's current state. + /// + /// + /// This should be roughly equivalent to DisabledPlugins.Contains(meta), but more performant. + /// This should also always return the inverse of for valid plugins. + /// + /// the plugin to check + /// if the plugin is disabled, otherwise + /// + /// public bool IsDisabled(PluginMetadata meta) => ThrowIfDisposed() || (currentlyDisabled.Contains(meta) && !toEnable.Contains(meta)) || toDisable.Contains(meta); + /// + /// Enables a plugin in this transaction. + /// + /// the plugin to enable + /// if the transaction's state was changed, otherwise public bool Enable(PluginMetadata meta) { // returns whether or not state was changed ThrowIfDisposed(); @@ -49,6 +93,11 @@ namespace IPA.Loader return true; } + /// + /// Disables a plugin in this transaction. + /// + /// the plugin to disable + /// if the transaction's state was changed, otherwise public bool Disable(PluginMetadata meta) { // returns whether or not state was changed ThrowIfDisposed(); @@ -62,7 +111,11 @@ namespace IPA.Loader return true; } - public Task Commit() => PluginManager.CommitTransaction(this); + /// + /// Commits this transaction to actual state, enabling and disabling plugins as necessary. + /// + /// a which completes whenever all disables complete + public Task Commit() => ThrowIfDisposed() ?? PluginManager.CommitTransaction(this); private void ThrowIfDisposed() => ThrowIfDisposed(); private T ThrowIfDisposed() @@ -73,6 +126,9 @@ namespace IPA.Loader } private bool disposed = false; + /// + /// Disposes and discards this transaction without committing it. + /// public void Dispose() => disposed = true; }