1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-14 20:22:55 +08:00

Add a very simple method of applying batch changes to EditorBeatmap

This commit is contained in:
Dean Herbert 2020-10-06 21:21:09 +09:00
parent fa65e14455
commit 14c734c244
2 changed files with 73 additions and 17 deletions

View File

@ -91,6 +91,8 @@ namespace osu.Game.Screens.Edit
private readonly HashSet<HitObject> pendingUpdates = new HashSet<HitObject>();
private bool isBatchApplying;
/// <summary>
/// Adds a collection of <see cref="HitObject"/>s to this <see cref="EditorBeatmap"/>.
/// </summary>
@ -126,6 +128,10 @@ namespace osu.Game.Screens.Edit
mutableHitObjects.Insert(index, hitObject);
if (isBatchApplying)
batchPendingInserts.Add(hitObject);
else
{
// must be run after any change to hitobject ordering
beatmapProcessor?.PreProcess();
processHitObject(hitObject);
@ -133,6 +139,7 @@ namespace osu.Game.Screens.Edit
HitObjectAdded?.Invoke(hitObject);
}
}
/// <summary>
/// Updates a <see cref="HitObject"/>, invoking <see cref="HitObject.ApplyDefaults"/> and re-processing the beatmap.
@ -180,6 +187,10 @@ namespace osu.Game.Screens.Edit
bindable.UnbindAll();
startTimeBindables.Remove(hitObject);
if (isBatchApplying)
batchPendingDeletes.Add(hitObject);
else
{
// must be run after any change to hitobject ordering
beatmapProcessor?.PreProcess();
processHitObject(hitObject);
@ -187,6 +198,48 @@ namespace osu.Game.Screens.Edit
HitObjectRemoved?.Invoke(hitObject);
}
}
private readonly List<HitObject> batchPendingInserts = new List<HitObject>();
private readonly List<HitObject> batchPendingDeletes = new List<HitObject>();
/// <summary>
/// Apply a batch of operations in one go, without performing Pre/Postprocessing each time.
/// </summary>
/// <param name="applyFunction">The function which will apply the batch changes.</param>
public void ApplyBatchChanges(Action<EditorBeatmap> applyFunction)
{
if (isBatchApplying)
throw new InvalidOperationException("Attempting to perform a batch application from within an existing batch");
isBatchApplying = true;
applyFunction(this);
beatmapProcessor?.PreProcess();
beatmapProcessor?.PostProcess();
isBatchApplying = false;
foreach (var h in batchPendingDeletes)
{
processHitObject(h);
HitObjectRemoved?.Invoke(h);
}
batchPendingDeletes.Clear();
foreach (var h in batchPendingInserts)
{
processHitObject(h);
HitObjectAdded?.Invoke(h);
}
batchPendingInserts.Clear();
isBatchApplying = false;
}
/// <summary>
/// Clears all <see cref="HitObjects"/> from this <see cref="EditorBeatmap"/>.

View File

@ -68,16 +68,19 @@ namespace osu.Game.Screens.Edit
toRemove.Sort();
toAdd.Sort();
editorBeatmap.ApplyBatchChanges(eb =>
{
// Apply the changes.
for (int i = toRemove.Count - 1; i >= 0; i--)
editorBeatmap.RemoveAt(toRemove[i]);
eb.RemoveAt(toRemove[i]);
if (toAdd.Count > 0)
{
IBeatmap newBeatmap = readBeatmap(newState);
foreach (var i in toAdd)
editorBeatmap.Insert(i, newBeatmap.HitObjects[i]);
eb.Insert(i, newBeatmap.HitObjects[i]);
}
});
}
private string readString(byte[] state) => Encoding.UTF8.GetString(state);