mirror of
https://github.com/ppy/osu.git
synced 2025-02-13 15:53:51 +08:00
Split transaction handling code out into base class
This commit is contained in:
parent
ef092de9ba
commit
ce04daf053
@ -16,7 +16,7 @@ namespace osu.Game.Screens.Edit
|
||||
/// <summary>
|
||||
/// Tracks changes to the <see cref="Editor"/>.
|
||||
/// </summary>
|
||||
public class EditorChangeHandler : IEditorChangeHandler
|
||||
public class EditorChangeHandler : TransactionalCommitComponent, IEditorChangeHandler
|
||||
{
|
||||
public readonly Bindable<bool> CanUndo = new Bindable<bool>();
|
||||
public readonly Bindable<bool> CanRedo = new Bindable<bool>();
|
||||
@ -41,7 +41,6 @@ namespace osu.Game.Screens.Edit
|
||||
}
|
||||
|
||||
private readonly EditorBeatmap editorBeatmap;
|
||||
private int bulkChangesStarted;
|
||||
private bool isRestoring;
|
||||
|
||||
public const int MAX_SAVED_STATES = 50;
|
||||
@ -70,22 +69,8 @@ namespace osu.Game.Screens.Edit
|
||||
|
||||
private void hitObjectUpdated(HitObject obj) => SaveState();
|
||||
|
||||
public void BeginChange() => bulkChangesStarted++;
|
||||
|
||||
public void EndChange()
|
||||
protected override void UpdateState()
|
||||
{
|
||||
if (bulkChangesStarted == 0)
|
||||
throw new InvalidOperationException($"Cannot call {nameof(EndChange)} without a previous call to {nameof(BeginChange)}.");
|
||||
|
||||
if (--bulkChangesStarted == 0)
|
||||
SaveState();
|
||||
}
|
||||
|
||||
public void SaveState()
|
||||
{
|
||||
if (bulkChangesStarted > 0)
|
||||
return;
|
||||
|
||||
if (isRestoring)
|
||||
return;
|
||||
|
||||
@ -120,7 +105,7 @@ namespace osu.Game.Screens.Edit
|
||||
/// <param name="direction">The direction to restore in. If less than 0, an older state will be used. If greater than 0, a newer state will be used.</param>
|
||||
public void RestoreState(int direction)
|
||||
{
|
||||
if (bulkChangesStarted > 0)
|
||||
if (TransactionActive)
|
||||
return;
|
||||
|
||||
if (savedStates.Count == 0)
|
||||
|
@ -68,19 +68,20 @@ namespace osu.Game.Screens.Edit
|
||||
toRemove.Sort();
|
||||
toAdd.Sort();
|
||||
|
||||
editorBeatmap.ApplyBatchChanges(eb =>
|
||||
{
|
||||
// Apply the changes.
|
||||
for (int i = toRemove.Count - 1; i >= 0; i--)
|
||||
eb.RemoveAt(toRemove[i]);
|
||||
editorBeatmap.BeginChange();
|
||||
|
||||
if (toAdd.Count > 0)
|
||||
{
|
||||
IBeatmap newBeatmap = readBeatmap(newState);
|
||||
foreach (var i in toAdd)
|
||||
eb.Insert(i, newBeatmap.HitObjects[i]);
|
||||
}
|
||||
});
|
||||
// Apply the changes.
|
||||
for (int i = toRemove.Count - 1; i >= 0; i--)
|
||||
editorBeatmap.RemoveAt(toRemove[i]);
|
||||
|
||||
if (toAdd.Count > 0)
|
||||
{
|
||||
IBeatmap newBeatmap = readBeatmap(newState);
|
||||
foreach (var i in toAdd)
|
||||
editorBeatmap.Insert(i, newBeatmap.HitObjects[i]);
|
||||
}
|
||||
|
||||
editorBeatmap.EndChange();
|
||||
}
|
||||
|
||||
private string readString(byte[] state) => Encoding.UTF8.GetString(state);
|
||||
|
45
osu.Game/Screens/Edit/TransactionalCommitComponent.cs
Normal file
45
osu.Game/Screens/Edit/TransactionalCommitComponent.cs
Normal file
@ -0,0 +1,45 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
|
||||
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 bool TransactionActive => bulkChangesStarted > 0;
|
||||
|
||||
private int bulkChangesStarted;
|
||||
|
||||
/// <summary>
|
||||
/// Signal the beginning of a change.
|
||||
/// </summary>
|
||||
public void BeginChange() => bulkChangesStarted++;
|
||||
|
||||
/// <summary>
|
||||
/// Signal the end of a change.
|
||||
/// </summary>
|
||||
/// <exception cref="InvalidOperationException">Throws if <see cref="BeginChange"/> was not first called.</exception>
|
||||
public void EndChange()
|
||||
{
|
||||
if (bulkChangesStarted == 0)
|
||||
throw new InvalidOperationException($"Cannot call {nameof(EndChange)} without a previous call to {nameof(BeginChange)}.");
|
||||
|
||||
if (--bulkChangesStarted == 0)
|
||||
UpdateState();
|
||||
}
|
||||
|
||||
public void SaveState()
|
||||
{
|
||||
if (bulkChangesStarted > 0)
|
||||
return;
|
||||
|
||||
UpdateState();
|
||||
}
|
||||
|
||||
protected abstract void UpdateState();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user