Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify convertible hitobject parsing and add IHasLegacyHitObjectType #30578

Merged
merged 5 commits into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 13 additions & 25 deletions osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapInfoWedge.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

#nullable disable

using System;
using System.Collections.Generic;
using System.Linq;
using JetBrains.Annotations;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
Expand All @@ -23,7 +20,6 @@
using osu.Game.Rulesets.Mania;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Legacy;
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Rulesets.Taiko;
Expand All @@ -35,15 +31,11 @@ namespace osu.Game.Tests.Visual.SongSelect
[TestFixture]
public partial class TestSceneBeatmapInfoWedge : OsuTestScene
{
private RulesetStore rulesets;
private TestBeatmapInfoWedge infoWedge;
private readonly List<IBeatmap> beatmaps = new List<IBeatmap>();
[Resolved]
private RulesetStore rulesets { get; set; } = null!;

[BackgroundDependencyLoader]
private void load(RulesetStore rulesets)
{
this.rulesets = rulesets;
}
private TestBeatmapInfoWedge infoWedge = null!;
private readonly List<IBeatmap> beatmaps = new List<IBeatmap>();

protected override void LoadComplete()
{
Expand Down Expand Up @@ -156,7 +148,7 @@ public void TestBPMUpdates()
IBeatmap beatmap = createTestBeatmap(new OsuRuleset().RulesetInfo);
beatmap.ControlPointInfo.Add(0, new TimingControlPoint { BeatLength = 60 * 1000 / bpm });

OsuModDoubleTime doubleTime = null;
OsuModDoubleTime doubleTime = null!;

selectBeatmap(beatmap);
checkDisplayedBPM($"{bpm}");
Expand All @@ -173,7 +165,7 @@ public void TestBPMUpdates()
[TestCase(120, 120.4, null, "120")]
[TestCase(120, 120.6, "DT", "180-182 (mostly 180)")]
[TestCase(120, 120.4, "DT", "180")]
public void TestVaryingBPM(double commonBpm, double otherBpm, string mod, string expectedDisplay)
public void TestVaryingBPM(double commonBpm, double otherBpm, string? mod, string expectedDisplay)
{
IBeatmap beatmap = createTestBeatmap(new OsuRuleset().RulesetInfo);
beatmap.ControlPointInfo.Add(0, new TimingControlPoint { BeatLength = 60 * 1000 / commonBpm });
Expand Down Expand Up @@ -203,7 +195,7 @@ public void TestLengthUpdates()
double drain = beatmap.CalculateDrainLength();
beatmap.BeatmapInfo.Length = drain;

OsuModDoubleTime doubleTime = null;
OsuModDoubleTime doubleTime = null!;

selectBeatmap(beatmap);
checkDisplayedLength(drain);
Expand All @@ -221,14 +213,15 @@ private void checkDisplayedLength(double drain)

AddUntilStep($"check map drain ({displayedLength})", () =>
{
var label = infoWedge.DisplayedContent.ChildrenOfType<BeatmapInfoWedge.WedgeInfoText.InfoLabel>().Single(l => l.Statistic.Name == BeatmapsetsStrings.ShowStatsTotalLength(displayedLength));
var label = infoWedge.DisplayedContent.ChildrenOfType<BeatmapInfoWedge.WedgeInfoText.InfoLabel>()
.Single(l => l.Statistic.Name == BeatmapsetsStrings.ShowStatsTotalLength(displayedLength));
return label.Statistic.Content == displayedLength.ToString();
});
}

private void setRuleset(RulesetInfo rulesetInfo)
{
Container containerBefore = null;
Container? containerBefore = null;

AddStep("set ruleset", () =>
{
Expand All @@ -242,9 +235,9 @@ private void setRuleset(RulesetInfo rulesetInfo)
AddUntilStep("wait for async load", () => infoWedge.DisplayedContent != containerBefore);
}

private void selectBeatmap([CanBeNull] IBeatmap b)
private void selectBeatmap(IBeatmap? b)
{
Container containerBefore = null;
Container? containerBefore = null;

AddStep($"select {b?.Metadata.Title ?? "null"} beatmap", () =>
{
Expand Down Expand Up @@ -307,11 +300,6 @@ private partial class TestBeatmapInfoWedge : BeatmapInfoWedge
public new WedgeInfoText Info => base.Info;
}

private class TestHitObject : ConvertHitObject, IHasPosition
{
public float X => 0;
public float Y => 0;
public Vector2 Position { get; } = Vector2.Zero;
}
private class TestHitObject : ConvertHitObject;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@
using osu.Game.Rulesets;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Legacy;
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Screens.Select;
using osuTK;

namespace osu.Game.Tests.Visual.SongSelectV2
{
Expand Down Expand Up @@ -209,11 +207,6 @@ private partial class TestBeatmapInfoWedgeV2 : BeatmapInfoWedgeV2
public new WedgeInfoText? Info => base.Info;
}

private class TestHitObject : ConvertHitObject, IHasPosition
{
public float X => 0;
public float Y => 0;
public Vector2 Position { get; } = Vector2.Zero;
}
private class TestHitObject : ConvertHitObject;
}
}
45 changes: 9 additions & 36 deletions osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@ public class LegacyBeatmapDecoder : LegacyDecoder<Beatmap>
internal static RulesetStore? RulesetStore;

private Beatmap beatmap = null!;

private ConvertHitObjectParser? parser;
private ConvertHitObjectParser parser = null!;

private LegacySampleBank defaultSampleBank;
private int defaultSampleVolume = 100;
Expand Down Expand Up @@ -80,6 +79,7 @@ protected override void ParseStreamInto(LineBufferedReader stream, Beatmap beatm
{
this.beatmap = beatmap;
this.beatmap.BeatmapInfo.BeatmapVersion = FormatVersion;
parser = new ConvertHitObjectParser(getOffsetTime(), FormatVersion);

applyLegacyDefaults(this.beatmap.BeatmapInfo);

Expand Down Expand Up @@ -162,7 +162,8 @@ private void applySamples(HitObject hitObject)
{
if (hitObject is IHasRepeats hasRepeats)
{
SampleControlPoint sampleControlPoint = (beatmap.ControlPointInfo as LegacyControlPointInfo)?.SamplePointAt(hitObject.StartTime + CONTROL_POINT_LENIENCY + 1) ?? SampleControlPoint.DEFAULT;
SampleControlPoint sampleControlPoint = (beatmap.ControlPointInfo as LegacyControlPointInfo)?.SamplePointAt(hitObject.StartTime + CONTROL_POINT_LENIENCY + 1)
?? SampleControlPoint.DEFAULT;
hitObject.Samples = hitObject.Samples.Select(o => sampleControlPoint.ApplyTo(o)).ToList();

for (int i = 0; i < hasRepeats.NodeSamples.Count; i++)
Expand All @@ -175,7 +176,8 @@ private void applySamples(HitObject hitObject)
}
else
{
SampleControlPoint sampleControlPoint = (beatmap.ControlPointInfo as LegacyControlPointInfo)?.SamplePointAt(hitObject.GetEndTime() + CONTROL_POINT_LENIENCY) ?? SampleControlPoint.DEFAULT;
SampleControlPoint sampleControlPoint = (beatmap.ControlPointInfo as LegacyControlPointInfo)?.SamplePointAt(hitObject.GetEndTime() + CONTROL_POINT_LENIENCY)
?? SampleControlPoint.DEFAULT;
hitObject.Samples = hitObject.Samples.Select(o => sampleControlPoint.ApplyTo(o)).ToList();
}
}
Expand Down Expand Up @@ -263,29 +265,7 @@ private void handleGeneral(string line)
break;

case @"Mode":
int rulesetID = Parsing.ParseInt(pair.Value);

beatmap.BeatmapInfo.Ruleset = RulesetStore?.GetRuleset(rulesetID) ?? throw new ArgumentException("Ruleset is not available locally.");

switch (rulesetID)
{
case 0:
parser = new Rulesets.Objects.Legacy.Osu.ConvertHitObjectParser(getOffsetTime(), FormatVersion);
break;

case 1:
parser = new Rulesets.Objects.Legacy.Taiko.ConvertHitObjectParser(getOffsetTime(), FormatVersion);
break;

case 2:
parser = new Rulesets.Objects.Legacy.Catch.ConvertHitObjectParser(getOffsetTime(), FormatVersion);
break;

case 3:
parser = new Rulesets.Objects.Legacy.Mania.ConvertHitObjectParser(getOffsetTime(), FormatVersion);
break;
}

beatmap.BeatmapInfo.Ruleset = RulesetStore?.GetRuleset(Parsing.ParseInt(pair.Value)) ?? throw new ArgumentException("Ruleset is not available locally.");
break;

case @"LetterboxInBreaks":
Expand Down Expand Up @@ -617,17 +597,10 @@ private void flushPendingPoints()

private void handleHitObject(string line)
{
// If the ruleset wasn't specified, assume the osu!standard ruleset.
parser ??= new Rulesets.Objects.Legacy.Osu.ConvertHitObjectParser(getOffsetTime(), FormatVersion);

var obj = parser.Parse(line);
obj.ApplyDefaults(beatmap.ControlPointInfo, beatmap.Difficulty);

if (obj != null)
{
obj.ApplyDefaults(beatmap.ControlPointInfo, beatmap.Difficulty);

beatmap.HitObjects.Add(obj);
}
beatmap.HitObjects.Add(obj);
}

private int getOffsetTime(int time) => time + (ApplyOffsets ? offset : 0);
Expand Down
2 changes: 1 addition & 1 deletion osu.Game/Beatmaps/Legacy/LegacyHitObjectType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
namespace osu.Game.Beatmaps.Legacy
{
[Flags]
internal enum LegacyHitObjectType
public enum LegacyHitObjectType
{
Circle = 1,
Slider = 1 << 1,
Expand Down
20 changes: 0 additions & 20 deletions osu.Game/Rulesets/Objects/Legacy/Catch/ConvertHit.cs

This file was deleted.

63 changes: 0 additions & 63 deletions osu.Game/Rulesets/Objects/Legacy/Catch/ConvertHitObjectParser.cs

This file was deleted.

20 changes: 0 additions & 20 deletions osu.Game/Rulesets/Objects/Legacy/Catch/ConvertSlider.cs

This file was deleted.

19 changes: 0 additions & 19 deletions osu.Game/Rulesets/Objects/Legacy/Catch/ConvertSpinner.cs

This file was deleted.

13 changes: 13 additions & 0 deletions osu.Game/Rulesets/Objects/Legacy/ConvertHitCircle.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright (c) ppy Pty Ltd <[email protected]>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

namespace osu.Game.Rulesets.Objects.Legacy
{
/// <summary>
/// Legacy "HitCircle" hit object type.
/// </summary>
/// <remarks>
/// Only used for parsing beatmaps and not gameplay.
/// </remarks>
internal sealed class ConvertHitCircle : ConvertHitObject;
}
Loading