1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-15 05:02:55 +08:00

Merge pull request #23631 from bdach/fix-velocity-undo

Fix undo/redo not working for slider velocity and sample changes
This commit is contained in:
Dean Herbert 2023-05-23 14:46:49 +09:00 committed by GitHub
commit f908545b9b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 68 additions and 0 deletions

View File

@ -92,6 +92,20 @@ namespace osu.Game.Tests.Visual.Editing
hitObjectHasVelocity(1, 5); hitObjectHasVelocity(1, 5);
} }
[Test]
public void TestUndo()
{
clickDifficultyPiece(1);
velocityPopoverHasSingleValue(2);
setVelocityViaPopover(5);
hitObjectHasVelocity(1, 5);
dismissPopover();
AddStep("undo", () => Editor.Undo());
hitObjectHasVelocity(1, 2);
}
[Test] [Test]
public void TestMultipleSelectionWithSameSliderVelocity() public void TestMultipleSelectionWithSameSliderVelocity()
{ {

View File

@ -109,6 +109,21 @@ namespace osu.Game.Tests.Visual.Editing
hitObjectHasSampleBank(1, "drum"); hitObjectHasSampleBank(1, "drum");
} }
[Test]
public void TestUndo()
{
clickSamplePiece(1);
samplePopoverHasSingleBank("soft");
samplePopoverHasSingleVolume(60);
setVolumeViaPopover(90);
hitObjectHasSampleVolume(1, 90);
dismissPopover();
AddStep("undo", () => Editor.Undo());
hitObjectHasSampleVolume(1, 60);
}
[Test] [Test]
public void TestMultipleSelectionWithSameSampleVolume() public void TestMultipleSelectionWithSameSampleVolume()
{ {

View File

@ -5,6 +5,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
@ -15,7 +16,9 @@ using osu.Framework.Graphics.Textures;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Beatmaps.Formats; using osu.Game.Beatmaps.Formats;
using osu.Game.Extensions;
using osu.Game.IO; using osu.Game.IO;
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Skinning; using osu.Game.Skinning;
using Decoder = osu.Game.Beatmaps.Formats.Decoder; using Decoder = osu.Game.Beatmaps.Formats.Decoder;
@ -42,6 +45,7 @@ namespace osu.Game.Screens.Edit
editorBeatmap.BeginChange(); editorBeatmap.BeginChange();
processHitObjects(result, () => newBeatmap ??= readBeatmap(newState)); processHitObjects(result, () => newBeatmap ??= readBeatmap(newState));
processTimingPoints(() => newBeatmap ??= readBeatmap(newState)); processTimingPoints(() => newBeatmap ??= readBeatmap(newState));
processHitObjectLocalData(() => newBeatmap ??= readBeatmap(newState));
editorBeatmap.EndChange(); editorBeatmap.EndChange();
} }
@ -87,6 +91,41 @@ namespace osu.Game.Screens.Edit
} }
} }
private void processHitObjectLocalData(Func<IBeatmap> getNewBeatmap)
{
// This method handles data that are stored in control points in the legacy format,
// but were moved to the hitobjects themselves in lazer.
// Specifically, the data being referred to here consists of: slider velocity and sample information.
// For simplicity, this implementation relies on the editor beatmap already having the same hitobjects in sequence as the new beatmap.
// To guarantee that, `processHitObjects()` must be ran prior to this method for correct operation.
// This is done to avoid the necessity of reimplementing/reusing parts of LegacyBeatmapDecoder that already treat this data correctly.
var oldObjects = editorBeatmap.HitObjects;
var newObjects = getNewBeatmap().HitObjects;
Debug.Assert(oldObjects.Count == newObjects.Count);
foreach (var (oldObject, newObject) in oldObjects.Zip(newObjects))
{
// if `oldObject` and `newObject` are the same, it means that `oldObject` was inserted into `editorBeatmap` by `processHitObjects()`.
// in that case, there is nothing to do (and some of the subsequent changes may even prove destructive).
if (ReferenceEquals(oldObject, newObject))
continue;
if (oldObject is IHasSliderVelocity oldWithVelocity && newObject is IHasSliderVelocity newWithVelocity)
oldWithVelocity.SliderVelocity = newWithVelocity.SliderVelocity;
oldObject.Samples = newObject.Samples;
if (oldObject is IHasRepeats oldWithRepeats && newObject is IHasRepeats newWithRepeats)
{
oldWithRepeats.NodeSamples.Clear();
oldWithRepeats.NodeSamples.AddRange(newWithRepeats.NodeSamples);
}
}
}
private void findChangedIndices(DiffResult result, LegacyDecoder<Beatmap>.Section section, out List<int> removedIndices, out List<int> addedIndices) private void findChangedIndices(DiffResult result, LegacyDecoder<Beatmap>.Section section, out List<int> removedIndices, out List<int> addedIndices)
{ {
removedIndices = new List<int>(); removedIndices = new List<int>();