mirror of
https://github.com/ppy/osu.git
synced 2024-11-07 15:17:30 +08:00
Merge pull request #10399 from peppy/editor-beatmap-batch-change-support
Add editor beatmap batch change support
This commit is contained in:
commit
338b4c56ce
@ -239,10 +239,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
|||||||
private void deleteSelected()
|
private void deleteSelected()
|
||||||
{
|
{
|
||||||
ChangeHandler?.BeginChange();
|
ChangeHandler?.BeginChange();
|
||||||
|
EditorBeatmap?.RemoveRange(selectedBlueprints.Select(b => b.HitObject));
|
||||||
foreach (var h in selectedBlueprints.ToList())
|
|
||||||
EditorBeatmap?.Remove(h.HitObject);
|
|
||||||
|
|
||||||
ChangeHandler?.EndChange();
|
ChangeHandler?.EndChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -484,8 +484,7 @@ namespace osu.Game.Screens.Edit
|
|||||||
protected void Cut()
|
protected void Cut()
|
||||||
{
|
{
|
||||||
Copy();
|
Copy();
|
||||||
foreach (var h in editorBeatmap.SelectedHitObjects.ToArray())
|
editorBeatmap.RemoveRange(editorBeatmap.SelectedHitObjects.ToArray());
|
||||||
editorBeatmap.Remove(h);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void Copy()
|
protected void Copy()
|
||||||
|
@ -91,14 +91,19 @@ namespace osu.Game.Screens.Edit
|
|||||||
|
|
||||||
private readonly HashSet<HitObject> pendingUpdates = new HashSet<HitObject>();
|
private readonly HashSet<HitObject> pendingUpdates = new HashSet<HitObject>();
|
||||||
|
|
||||||
|
private bool isBatchApplying;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a collection of <see cref="HitObject"/>s to this <see cref="EditorBeatmap"/>.
|
/// Adds a collection of <see cref="HitObject"/>s to this <see cref="EditorBeatmap"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="hitObjects">The <see cref="HitObject"/>s to add.</param>
|
/// <param name="hitObjects">The <see cref="HitObject"/>s to add.</param>
|
||||||
public void AddRange(IEnumerable<HitObject> hitObjects)
|
public void AddRange(IEnumerable<HitObject> hitObjects)
|
||||||
|
{
|
||||||
|
ApplyBatchChanges(_ =>
|
||||||
{
|
{
|
||||||
foreach (var h in hitObjects)
|
foreach (var h in hitObjects)
|
||||||
Add(h);
|
Add(h);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -126,6 +131,10 @@ namespace osu.Game.Screens.Edit
|
|||||||
|
|
||||||
mutableHitObjects.Insert(index, hitObject);
|
mutableHitObjects.Insert(index, hitObject);
|
||||||
|
|
||||||
|
if (isBatchApplying)
|
||||||
|
batchPendingInserts.Add(hitObject);
|
||||||
|
else
|
||||||
|
{
|
||||||
// must be run after any change to hitobject ordering
|
// must be run after any change to hitobject ordering
|
||||||
beatmapProcessor?.PreProcess();
|
beatmapProcessor?.PreProcess();
|
||||||
processHitObject(hitObject);
|
processHitObject(hitObject);
|
||||||
@ -133,6 +142,7 @@ namespace osu.Game.Screens.Edit
|
|||||||
|
|
||||||
HitObjectAdded?.Invoke(hitObject);
|
HitObjectAdded?.Invoke(hitObject);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Updates a <see cref="HitObject"/>, invoking <see cref="HitObject.ApplyDefaults"/> and re-processing the beatmap.
|
/// Updates a <see cref="HitObject"/>, invoking <see cref="HitObject.ApplyDefaults"/> and re-processing the beatmap.
|
||||||
@ -159,6 +169,19 @@ namespace osu.Game.Screens.Edit
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes a collection of <see cref="HitObject"/>s to this <see cref="EditorBeatmap"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="hitObjects">The <see cref="HitObject"/>s to remove.</param>
|
||||||
|
public void RemoveRange(IEnumerable<HitObject> hitObjects)
|
||||||
|
{
|
||||||
|
ApplyBatchChanges(_ =>
|
||||||
|
{
|
||||||
|
foreach (var h in hitObjects)
|
||||||
|
Remove(h);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Finds the index of a <see cref="HitObject"/> in this <see cref="EditorBeatmap"/>.
|
/// Finds the index of a <see cref="HitObject"/> in this <see cref="EditorBeatmap"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -180,6 +203,10 @@ namespace osu.Game.Screens.Edit
|
|||||||
bindable.UnbindAll();
|
bindable.UnbindAll();
|
||||||
startTimeBindables.Remove(hitObject);
|
startTimeBindables.Remove(hitObject);
|
||||||
|
|
||||||
|
if (isBatchApplying)
|
||||||
|
batchPendingDeletes.Add(hitObject);
|
||||||
|
else
|
||||||
|
{
|
||||||
// must be run after any change to hitobject ordering
|
// must be run after any change to hitobject ordering
|
||||||
beatmapProcessor?.PreProcess();
|
beatmapProcessor?.PreProcess();
|
||||||
processHitObject(hitObject);
|
processHitObject(hitObject);
|
||||||
@ -187,15 +214,45 @@ namespace osu.Game.Screens.Edit
|
|||||||
|
|
||||||
HitObjectRemoved?.Invoke(hitObject);
|
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();
|
||||||
|
|
||||||
|
foreach (var h in batchPendingDeletes) processHitObject(h);
|
||||||
|
foreach (var h in batchPendingInserts) processHitObject(h);
|
||||||
|
|
||||||
|
beatmapProcessor?.PostProcess();
|
||||||
|
|
||||||
|
foreach (var h in batchPendingDeletes) HitObjectRemoved?.Invoke(h);
|
||||||
|
foreach (var h in batchPendingInserts) HitObjectAdded?.Invoke(h);
|
||||||
|
|
||||||
|
batchPendingDeletes.Clear();
|
||||||
|
batchPendingInserts.Clear();
|
||||||
|
|
||||||
|
isBatchApplying = false;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Clears all <see cref="HitObjects"/> from this <see cref="EditorBeatmap"/>.
|
/// Clears all <see cref="HitObjects"/> from this <see cref="EditorBeatmap"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Clear()
|
public void Clear() => RemoveRange(HitObjects.ToArray());
|
||||||
{
|
|
||||||
foreach (var h in HitObjects.ToArray())
|
|
||||||
Remove(h);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Update()
|
protected override void Update()
|
||||||
{
|
{
|
||||||
|
@ -68,16 +68,19 @@ namespace osu.Game.Screens.Edit
|
|||||||
toRemove.Sort();
|
toRemove.Sort();
|
||||||
toAdd.Sort();
|
toAdd.Sort();
|
||||||
|
|
||||||
|
editorBeatmap.ApplyBatchChanges(eb =>
|
||||||
|
{
|
||||||
// Apply the changes.
|
// Apply the changes.
|
||||||
for (int i = toRemove.Count - 1; i >= 0; i--)
|
for (int i = toRemove.Count - 1; i >= 0; i--)
|
||||||
editorBeatmap.RemoveAt(toRemove[i]);
|
eb.RemoveAt(toRemove[i]);
|
||||||
|
|
||||||
if (toAdd.Count > 0)
|
if (toAdd.Count > 0)
|
||||||
{
|
{
|
||||||
IBeatmap newBeatmap = readBeatmap(newState);
|
IBeatmap newBeatmap = readBeatmap(newState);
|
||||||
foreach (var i in toAdd)
|
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);
|
private string readString(byte[] state) => Encoding.UTF8.GetString(state);
|
||||||
|
Loading…
Reference in New Issue
Block a user