1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-28 02:43:19 +08:00

Make component and add hooking events

This commit is contained in:
Dean Herbert 2020-10-08 17:17:52 +09:00
parent ce04daf053
commit a9bca671d0

View File

@ -2,14 +2,30 @@
// See the LICENCE file in the repository root for full licence text.
using System;
using osu.Framework.Graphics;
namespace osu.Game.Screens.Edit
{
/// <summary>
/// A component that tracks a batch change, only applying after all active changes are completed.
/// </summary>
public abstract class TransactionalCommitComponent
public abstract class TransactionalCommitComponent : Component
{
/// <summary>
/// Fires whenever a transaction begins. Will not fire on nested transactions.
/// </summary>
public event Action TransactionBegan;
/// <summary>
/// Fires when the last transaction completes.
/// </summary>
public event Action TransactionEnded;
/// <summary>
/// Fires when <see cref="SaveState"/> is called and results in a non-transactional state save.
/// </summary>
public event Action SaveStateTriggered;
public bool TransactionActive => bulkChangesStarted > 0;
private int bulkChangesStarted;
@ -17,7 +33,11 @@ namespace osu.Game.Screens.Edit
/// <summary>
/// Signal the beginning of a change.
/// </summary>
public void BeginChange() => bulkChangesStarted++;
public void BeginChange()
{
if (bulkChangesStarted++ == 0)
TransactionBegan?.Invoke();
}
/// <summary>
/// Signal the end of a change.
@ -29,14 +49,22 @@ namespace osu.Game.Screens.Edit
throw new InvalidOperationException($"Cannot call {nameof(EndChange)} without a previous call to {nameof(BeginChange)}.");
if (--bulkChangesStarted == 0)
{
UpdateState();
TransactionEnded?.Invoke();
}
}
/// <summary>
/// Force an update of the state with no attached transaction.
/// This is a no-op if a transaction is already active. Should generally be used as a safety measure to ensure granular changes are not left outside a transaction.
/// </summary>
public void SaveState()
{
if (bulkChangesStarted > 0)
return;
SaveStateTriggered?.Invoke();
UpdateState();
}