Browse Source

Transaction commit now correctly clones the transaction when scheduling processing on the Unity main thread

pull/44/head
Anairkoen Schno 4 years ago
parent
commit
428aade59e
2 changed files with 23 additions and 1 deletions
  1. +6
    -1
      IPA.Loader/Loader/PluginManager.cs
  2. +17
    -0
      IPA.Loader/Loader/StateTransitionTransaction.cs

+ 6
- 1
IPA.Loader/Loader/PluginManager.cs View File

@ -85,7 +85,11 @@ namespace IPA.Loader
if (!transaction.HasStateChanged) return TaskEx.WhenAll(); if (!transaction.HasStateChanged) return TaskEx.WhenAll();
if (!UnityGame.OnMainThread) if (!UnityGame.OnMainThread)
return UnityMainThreadTaskScheduler.Factory.StartNew(() => CommitTransaction(transaction)).Unwrap();
{
var transactionCopy = transaction.Clone();
transaction.Dispose();
return UnityMainThreadTaskScheduler.Factory.StartNew(() => CommitTransaction(transactionCopy)).Unwrap();
}
lock (commitTransactionLockObject) lock (commitTransactionLockObject)
{ {
@ -94,6 +98,7 @@ namespace IPA.Loader
|| transaction.CurrentlyDisabled.Except(DisabledPlugins) || transaction.CurrentlyDisabled.Except(DisabledPlugins)
.Concat(DisabledPlugins.Except(transaction.CurrentlyDisabled)).Any()) .Concat(DisabledPlugins.Except(transaction.CurrentlyDisabled)).Any())
{ // ensure that the transaction's base state reflects the current state, otherwise throw { // ensure that the transaction's base state reflects the current state, otherwise throw
transaction.Dispose();
throw new InvalidOperationException("Transaction no longer resembles the current state of plugins"); throw new InvalidOperationException("Transaction no longer resembles the current state of plugins");
} }


+ 17
- 0
IPA.Loader/Loader/StateTransitionTransaction.cs View File

@ -237,6 +237,23 @@ namespace IPA.Loader
/// <exception cref="InvalidOperationException">if the plugins' state no longer matches this transaction's original state</exception> /// <exception cref="InvalidOperationException">if the plugins' state no longer matches this transaction's original state</exception>
public Task Commit() => ThrowIfDisposed<Task>() ?? PluginManager.CommitTransaction(this); public Task Commit() => ThrowIfDisposed<Task>() ?? PluginManager.CommitTransaction(this);
/// <summary>
/// Clones this transaction to be identical, but with unrelated underlying sets.
/// </summary>
/// <returns>the new <see cref="StateTransitionTransaction"/></returns>
/// <exception cref="ObjectDisposedException">if this object has been disposed</exception>
public StateTransitionTransaction Clone()
{
ThrowIfDisposed();
var copy = new StateTransitionTransaction(CurrentlyEnabled, CurrentlyDisabled);
foreach (var toEnable in ToEnable)
copy.toEnable.Add(toEnable);
foreach (var toDisable in ToDisable)
copy.toDisable.Add(toDisable);
copy.stateChanged = stateChanged;
return copy;
}
private void ThrowIfDisposed() => ThrowIfDisposed<byte>(); private void ThrowIfDisposed() => ThrowIfDisposed<byte>();
private T ThrowIfDisposed<T>() private T ThrowIfDisposed<T>()
{ {


Loading…
Cancel
Save