You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

79 lines
3.4 KiB

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IPA.Loader
{
public sealed class StateTransitionTransaction : IDisposable
{
private readonly HashSet<PluginMetadata> currentlyEnabled;
private readonly HashSet<PluginMetadata> currentlyDisabled;
private readonly HashSet<PluginMetadata> toEnable = new HashSet<PluginMetadata>();
private readonly HashSet<PluginMetadata> toDisable = new HashSet<PluginMetadata>();
internal StateTransitionTransaction(IEnumerable<PluginMetadata> enabled, IEnumerable<PluginMetadata> disabled)
{
currentlyEnabled = new HashSet<PluginMetadata>(enabled.ToArray());
currentlyDisabled = new HashSet<PluginMetadata>(disabled.ToArray());
}
public bool WillNeedRestart => toEnable.Concat(toDisable).Any(m => m.RuntimeOptions != RuntimeOptions.DynamicInit);
internal IEnumerable<PluginMetadata> ToEnable => toEnable;
internal IEnumerable<PluginMetadata> ToDisable => toDisable;
public IEnumerable<PluginMetadata> EnabledPlugins => currentlyEnabled.Except(toDisable).Concat(toEnable);
public IEnumerable<PluginMetadata> DisabledPlugins => currentlyDisabled.Except(toEnable).Concat(toDisable);
public bool IsEnabled(PluginMetadata meta)
=> ThrowIfDisposed<bool>()
|| (currentlyEnabled.Contains(meta) && !toDisable.Contains(meta))
|| toEnable.Contains(meta);
public bool IsDisabled(PluginMetadata meta)
=> ThrowIfDisposed<bool>()
|| (currentlyDisabled.Contains(meta) && !toEnable.Contains(meta))
|| toDisable.Contains(meta);
public bool Enable(PluginMetadata meta)
{ // returns whether or not state was changed
ThrowIfDisposed();
if (!currentlyEnabled.Contains(meta) && !currentlyDisabled.Contains(meta))
throw new ArgumentException(nameof(meta), "Plugin metadata does not represent a loadable plugin");
if (toEnable.Contains(meta)) return false;
if (currentlyEnabled.Contains(meta) && !toDisable.Contains(meta)) return false;
toDisable.Remove(meta);
toEnable.Add(meta);
return true;
}
public bool Disable(PluginMetadata meta)
{ // returns whether or not state was changed
ThrowIfDisposed();
if (!currentlyEnabled.Contains(meta) && !currentlyDisabled.Contains(meta))
throw new ArgumentException(nameof(meta), "Plugin metadata does not represent a ");
if (toEnable.Contains(meta)) return false;
if (currentlyEnabled.Contains(meta) && !toDisable.Contains(meta)) return false;
toDisable.Remove(meta);
toEnable.Add(meta);
return true;
}
public Task Commit() => PluginManager.CommitTransaction(this);
private void ThrowIfDisposed() => ThrowIfDisposed<byte>();
private T ThrowIfDisposed<T>()
{
if (disposed)
throw new ObjectDisposedException(nameof(StateTransitionTransaction));
return default;
}
private bool disposed = false;
public void Dispose()
=> disposed = true;
}
}