mirror of
https://github.com/ppy/osu.git
synced 2025-02-20 20:33:21 +08:00
Move snap/divisor helper methods to inside ControlPointInfo
This commit is contained in:
parent
b8b6d0e861
commit
48d6c9ac4b
@ -85,7 +85,7 @@ namespace osu.Game.Tests.NonVisual
|
||||
};
|
||||
|
||||
for (int i = 0; i < divisors.Count; ++i)
|
||||
Assert.AreEqual(closestDivisors[i], beatmap.ClosestBeatDivisor(beatmap.HitObjects[i].StartTime), $"at index {i}");
|
||||
Assert.AreEqual(closestDivisors[i], beatmap.ControlPointInfo.ClosestBeatDivisor(beatmap.HitObjects[i].StartTime), $"at index {i}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,6 @@ using System.Linq;
|
||||
using osu.Game.Beatmaps.ControlPoints;
|
||||
using Newtonsoft.Json;
|
||||
using osu.Game.IO.Serialization.Converters;
|
||||
using osu.Game.Screens.Edit;
|
||||
|
||||
namespace osu.Game.Beatmaps
|
||||
{
|
||||
@ -75,31 +74,6 @@ namespace osu.Game.Beatmaps
|
||||
return mostCommon.beatLength;
|
||||
}
|
||||
|
||||
public int ClosestSnapTime(double time, int beatDivisor, double? referenceTime = null)
|
||||
{
|
||||
var timingPoint = ControlPointInfo.TimingPointAt(referenceTime ?? time);
|
||||
var beatLength = timingPoint.BeatLength / beatDivisor;
|
||||
var beatLengths = (int)Math.Round((time - timingPoint.Time) / beatLength, MidpointRounding.AwayFromZero);
|
||||
|
||||
// Casting to int matches stable.
|
||||
return (int)(timingPoint.Time + beatLengths * beatLength);
|
||||
}
|
||||
|
||||
public int ClosestSnapTime(double time, double? referenceTime = null)
|
||||
{
|
||||
return ClosestSnapTime(time, ClosestBeatDivisor(time, referenceTime), referenceTime);
|
||||
}
|
||||
|
||||
public int ClosestBeatDivisor(double time, double? referenceTime = null)
|
||||
{
|
||||
double getUnsnap(int divisor) => Math.Abs(time - ClosestSnapTime(time, divisor, referenceTime));
|
||||
|
||||
int[] divisors = BindableBeatDivisor.VALID_DIVISORS;
|
||||
double smallestUnsnap = divisors.Min(getUnsnap);
|
||||
|
||||
return divisors.FirstOrDefault(divisor => getUnsnap(divisor) == smallestUnsnap);
|
||||
}
|
||||
|
||||
IBeatmap IBeatmap.Clone() => Clone();
|
||||
|
||||
public Beatmap<T> Clone() => (Beatmap<T>)MemberwiseClone();
|
||||
|
@ -7,6 +7,7 @@ using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Lists;
|
||||
using osu.Game.Screens.Edit;
|
||||
|
||||
namespace osu.Game.Beatmaps.ControlPoints
|
||||
{
|
||||
@ -160,6 +161,47 @@ namespace osu.Game.Beatmaps.ControlPoints
|
||||
groups.Remove(group);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the time on the given beat divisor closest to the given time.
|
||||
/// </summary>
|
||||
/// <param name="time">The time to find the closest snapped time to.</param>
|
||||
/// <param name="beatDivisor">The beat divisor to snap to.</param>
|
||||
/// <param name="referenceTime">An optional reference point to use for timing point lookup.</param>
|
||||
public int ClosestSnapTime(double time, int beatDivisor, double? referenceTime = null)
|
||||
{
|
||||
var timingPoint = TimingPointAt(referenceTime ?? time);
|
||||
var beatLength = timingPoint.BeatLength / beatDivisor;
|
||||
var beatLengths = (int)Math.Round((time - timingPoint.Time) / beatLength, MidpointRounding.AwayFromZero);
|
||||
|
||||
// Casting to int matches stable.
|
||||
return (int)(timingPoint.Time + beatLengths * beatLength);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the time on any valid beat divisor closest to the given time.
|
||||
/// </summary>
|
||||
/// <param name="time">The time to find the closest snapped time to.</param>
|
||||
/// <param name="referenceTime">An optional reference point to use for timing point lookup.</param>
|
||||
public int ClosestSnapTime(double time, double? referenceTime = null)
|
||||
{
|
||||
return ClosestSnapTime(time, ClosestBeatDivisor(time, referenceTime), referenceTime);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the beat snap divisor closest to the given time. If two are equally close, the smallest is returned.
|
||||
/// </summary>
|
||||
/// <param name="time">The time to find the closest beat snap divisor to.</param>
|
||||
/// <param name="referenceTime">An optional reference point to use for timing point lookup.</param>
|
||||
public int ClosestBeatDivisor(double time, double? referenceTime = null)
|
||||
{
|
||||
double getUnsnap(int divisor) => Math.Abs(time - ClosestSnapTime(time, divisor, referenceTime));
|
||||
|
||||
int[] divisors = BindableBeatDivisor.VALID_DIVISORS;
|
||||
double smallestUnsnap = divisors.Min(getUnsnap);
|
||||
|
||||
return divisors.FirstOrDefault(divisor => getUnsnap(divisor) == smallestUnsnap);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Binary searches one of the control point lists to find the active control point at <paramref name="time"/>.
|
||||
/// Includes logic for returning a specific point when no matching point is found.
|
||||
|
@ -51,28 +51,6 @@ namespace osu.Game.Beatmaps
|
||||
/// </summary>
|
||||
double GetMostCommonBeatLength();
|
||||
|
||||
/// <summary>
|
||||
/// Returns the time on the given beat divisor closest to the given time.
|
||||
/// </summary>
|
||||
/// <param name="time">The time to find the closest snapped time to.</param>
|
||||
/// <param name="beatDivisor">The beat divisor to snap to.</param>
|
||||
/// <param name="referenceTime">An optional reference point to use for timing point lookup.</param>
|
||||
int ClosestSnapTime(double time, int beatDivisor, double? referenceTime = null);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the time on any valid beat divisor closest to the given time.
|
||||
/// </summary>
|
||||
/// <param name="time">The time to find the closest snapped time to.</param>
|
||||
/// <param name="referenceTime">An optional reference point to use for timing point lookup.</param>
|
||||
int ClosestSnapTime(double time, double? referenceTime = null);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the beat snap divisor closest to the given time. If two are equally close, the smallest is returned.
|
||||
/// </summary>
|
||||
/// <param name="time">The time to find the closest beat snap divisor to.</param>
|
||||
/// <param name="referenceTime">An optional reference point to use for timing point lookup.</param>
|
||||
int ClosestBeatDivisor(double time, double? referenceTime = null);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a shallow-clone of this beatmap and returns it.
|
||||
/// </summary>
|
||||
|
@ -24,9 +24,11 @@ namespace osu.Game.Rulesets.Edit.Checks
|
||||
|
||||
public IEnumerable<Issue> Run(IBeatmap playableBeatmap, IWorkingBeatmap workingBeatmap)
|
||||
{
|
||||
var controlPointInfo = playableBeatmap.ControlPointInfo;
|
||||
|
||||
foreach (var hitobject in playableBeatmap.HitObjects)
|
||||
{
|
||||
double startUnsnap = hitobject.StartTime - playableBeatmap.ClosestSnapTime(hitobject.StartTime);
|
||||
double startUnsnap = hitobject.StartTime - controlPointInfo.ClosestSnapTime(hitobject.StartTime);
|
||||
string startPostfix = hitobject is IHasDuration ? "start" : "";
|
||||
foreach (var issue in getUnsnapIssues(hitobject, startUnsnap, hitobject.StartTime, startPostfix))
|
||||
yield return issue;
|
||||
@ -37,7 +39,7 @@ namespace osu.Game.Rulesets.Edit.Checks
|
||||
{
|
||||
double spanDuration = hasRepeats.Duration / (hasRepeats.RepeatCount + 1);
|
||||
double repeatTime = hitobject.StartTime + spanDuration * (repeatIndex + 1);
|
||||
double repeatUnsnap = repeatTime - playableBeatmap.ClosestSnapTime(repeatTime);
|
||||
double repeatUnsnap = repeatTime - controlPointInfo.ClosestSnapTime(repeatTime);
|
||||
foreach (var issue in getUnsnapIssues(hitobject, repeatUnsnap, repeatTime, "repeat"))
|
||||
yield return issue;
|
||||
}
|
||||
@ -45,7 +47,7 @@ namespace osu.Game.Rulesets.Edit.Checks
|
||||
|
||||
if (hitobject is IHasDuration hasDuration)
|
||||
{
|
||||
double endUnsnap = hasDuration.EndTime - playableBeatmap.ClosestSnapTime(hasDuration.EndTime);
|
||||
double endUnsnap = hasDuration.EndTime - controlPointInfo.ClosestSnapTime(hasDuration.EndTime);
|
||||
foreach (var issue in getUnsnapIssues(hitobject, endUnsnap, hasDuration.EndTime, "end"))
|
||||
yield return issue;
|
||||
}
|
||||
|
@ -301,16 +301,7 @@ namespace osu.Game.Screens.Edit
|
||||
return list.Count - 1;
|
||||
}
|
||||
|
||||
public int ClosestSnapTime(double time, int beatDivisor, double? referenceTime = null)
|
||||
{
|
||||
return PlayableBeatmap.ClosestSnapTime(time, beatDivisor, referenceTime);
|
||||
}
|
||||
|
||||
public int ClosestSnapTime(double time, double? referenceTime = null) => PlayableBeatmap.ClosestSnapTime(time, referenceTime);
|
||||
|
||||
public int ClosestBeatDivisor(double time, double? referenceTime = null) => PlayableBeatmap.ClosestBeatDivisor(time, referenceTime);
|
||||
|
||||
public double SnapTime(double time, double? referenceTime) => ClosestSnapTime(time, BeatDivisor, referenceTime);
|
||||
public double SnapTime(double time, double? referenceTime) => ControlPointInfo.ClosestSnapTime(time, BeatDivisor, referenceTime);
|
||||
|
||||
public double GetBeatLengthAtTime(double referenceTime) => ControlPointInfo.TimingPointAt(referenceTime).BeatLength / BeatDivisor;
|
||||
|
||||
|
@ -45,15 +45,6 @@ namespace osu.Game.Screens.Play
|
||||
|
||||
public double GetMostCommonBeatLength() => PlayableBeatmap.GetMostCommonBeatLength();
|
||||
|
||||
public int ClosestSnapTime(double time, int beatDivisor, double? referenceTime = null)
|
||||
{
|
||||
return PlayableBeatmap.ClosestSnapTime(time, beatDivisor, referenceTime);
|
||||
}
|
||||
|
||||
public int ClosestSnapTime(double time, double? referenceTime = null) => PlayableBeatmap.ClosestSnapTime(time, referenceTime);
|
||||
|
||||
public int ClosestBeatDivisor(double time, double? referenceTime = null) => PlayableBeatmap.ClosestBeatDivisor(time, referenceTime);
|
||||
|
||||
public IBeatmap Clone() => PlayableBeatmap.Clone();
|
||||
|
||||
private readonly Bindable<JudgementResult> lastJudgementResult = new Bindable<JudgementResult>();
|
||||
|
Loading…
Reference in New Issue
Block a user