Enforce `IBeatmap.Breaks` to be sorted chronologically

This commit is contained in:
Salman Ahmed 2024-07-08 12:05:15 +03:00
parent da4067d059
commit b33e54d064
6 changed files with 30 additions and 7 deletions

View File

@ -8,6 +8,7 @@
using System.Linq;
using osu.Game.Beatmaps.ControlPoints;
using Newtonsoft.Json;
using osu.Framework.Lists;
using osu.Game.IO.Serialization.Converters;
namespace osu.Game.Beatmaps
@ -61,7 +62,7 @@ public Beatmap()
public ControlPointInfo ControlPointInfo { get; set; } = new ControlPointInfo();
public List<BreakPeriod> Breaks { get; set; } = new List<BreakPeriod>();
public SortedList<BreakPeriod> Breaks { get; set; } = new SortedList<BreakPeriod>();
public List<string> UnhandledEventLines { get; set; } = new List<string>();

View File

@ -7,6 +7,8 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using osu.Framework.Lists;
using osu.Game.Beatmaps.Timing;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Objects;
@ -50,7 +52,8 @@ public IBeatmap Convert(CancellationToken cancellationToken = default)
original.ControlPointInfo = original.ControlPointInfo.DeepClone();
// Used in osu!mania conversion.
original.Breaks = original.Breaks.ToList();
original.Breaks = new SortedList<BreakPeriod>(Comparer<BreakPeriod>.Default);
original.Breaks.AddRange(Beatmap.Breaks);
return ConvertBeatmap(original, cancellationToken);
}

View File

@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Lists;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Beatmaps.Timing;
using osu.Game.Rulesets.Objects;
@ -40,7 +41,7 @@ public interface IBeatmap
/// <summary>
/// The breaks in this beatmap.
/// </summary>
List<BreakPeriod> Breaks { get; set; }
SortedList<BreakPeriod> Breaks { get; set; }
/// <summary>
/// All lines from the [Events] section which aren't handled in the encoding process yet.

View File

@ -6,7 +6,7 @@
namespace osu.Game.Beatmaps.Timing
{
public class BreakPeriod : IEquatable<BreakPeriod>
public class BreakPeriod : IEquatable<BreakPeriod>, IComparable<BreakPeriod>
{
/// <summary>
/// The minimum gap between the start of the break and the previous object.
@ -76,5 +76,17 @@ public virtual bool Equals(BreakPeriod? other) =>
&& EndTime == other.EndTime;
public override int GetHashCode() => HashCode.Combine(StartTime, EndTime);
public int CompareTo(BreakPeriod? other)
{
if (ReferenceEquals(this, other)) return 0;
if (ReferenceEquals(null, other)) return 1;
int result = StartTime.CompareTo(other.StartTime);
if (result != 0)
return result;
return EndTime.CompareTo(other.EndTime);
}
}
}

View File

@ -10,6 +10,7 @@
using JetBrains.Annotations;
using osu.Framework.Audio.Track;
using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Lists;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Beatmaps.Timing;
@ -327,7 +328,7 @@ public BeatmapDifficulty Difficulty
set => baseBeatmap.Difficulty = value;
}
public List<BreakPeriod> Breaks
public SortedList<BreakPeriod> Breaks
{
get => baseBeatmap.Breaks;
set => baseBeatmap.Breaks = value;

View File

@ -10,6 +10,7 @@
using JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Lists;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Beatmaps.Legacy;
@ -111,7 +112,11 @@ public EditorBeatmap(IBeatmap playableBeatmap, ISkin beatmapSkin = null, Beatmap
trackStartTime(obj);
Breaks = new BindableList<BreakPeriod>(playableBeatmap.Breaks);
Breaks.BindCollectionChanged((_, _) => playableBeatmap.Breaks = Breaks.ToList());
Breaks.BindCollectionChanged((_, _) =>
{
playableBeatmap.Breaks.Clear();
playableBeatmap.Breaks.AddRange(Breaks);
});
PreviewTime = new BindableInt(BeatmapInfo.Metadata.PreviewTime);
PreviewTime.BindValueChanged(s =>
@ -177,7 +182,7 @@ public ControlPointInfo ControlPointInfo
public readonly BindableList<BreakPeriod> Breaks;
List<BreakPeriod> IBeatmap.Breaks
SortedList<BreakPeriod> IBeatmap.Breaks
{
get => PlayableBeatmap.Breaks;
set => PlayableBeatmap.Breaks = value;