Merge branch 'master' into android

This commit is contained in:
tangalbert919
2019-05-28 09:08:44 -05:00
276 changed files with 2211 additions and 1497 deletions

View File

@ -35,7 +35,7 @@ platform :ios do
changelog.gsub!('$BUILD_ID', options[:build])
pilot(
wait_processing_interval: 900,
wait_processing_interval: 1800,
changelog: changelog,
ipa: './osu.iOS/bin/iPhone/Release/osu.iOS.ipa'
)

View File

@ -2,8 +2,6 @@
// See the LICENCE file in the repository root for full licence text.
using System;
using System.IO;
using System.Reflection;
using System.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
@ -169,23 +167,19 @@ namespace osu.Desktop.Updater
private class SquirrelLogger : Splat.ILogger, IDisposable
{
private readonly string path;
private readonly object locker = new object();
public LogLevel Level { get; set; } = LogLevel.Info;
public SquirrelLogger()
{
var file = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly()?.Location ?? Directory.GetCurrentDirectory()), "SquirrelSetupUpdater.log");
if (File.Exists(file)) File.Delete(file);
path = file;
}
private Logger logger;
public void Write(string message, LogLevel logLevel)
{
if (logLevel < Level)
return;
lock (locker) File.AppendAllText(path, message + "\r\n");
if (logger == null)
logger = Logger.GetLogger("updater");
logger.Add(message);
}
public void Dispose()

View File

@ -13,9 +13,9 @@ using osuTK;
namespace osu.Game.Rulesets.Catch.Tests
{
public class TestCaseAutoJuiceStream : PlayerTestCase
public class TestSceneAutoJuiceStream : PlayerTestScene
{
public TestCaseAutoJuiceStream()
public TestSceneAutoJuiceStream()
: base(new CatchRuleset())
{
}

View File

@ -13,7 +13,7 @@ using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Catch.Tests
{
[TestFixture]
public class TestCaseBananaShower : PlayerTestCase
public class TestSceneBananaShower : PlayerTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Catch.Tests
typeof(DrawableCatchRuleset),
};
public TestCaseBananaShower()
public TestSceneBananaShower()
: base(new CatchRuleset())
{
}

View File

@ -7,9 +7,9 @@ using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Catch.Tests
{
[TestFixture]
public class TestCaseCatchPlayer : PlayerTestCase
public class TestSceneCatchPlayer : PlayerTestScene
{
public TestCaseCatchPlayer()
public TestSceneCatchPlayer()
: base(new CatchRuleset())
{
}

View File

@ -9,9 +9,9 @@ using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Catch.Tests
{
[TestFixture]
public class TestCaseCatchStacker : PlayerTestCase
public class TestSceneCatchStacker : PlayerTestScene
{
public TestCaseCatchStacker()
public TestSceneCatchStacker()
: base(new CatchRuleset())
{
}

View File

@ -13,7 +13,7 @@ using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Catch.Tests
{
[TestFixture]
public class TestCaseCatcherArea : OsuTestCase
public class TestSceneCatcherArea : OsuTestScene
{
private RulesetInfo catchRuleset;
private TestCatcherArea catcherArea;
@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Catch.Tests
typeof(CatcherArea),
};
public TestCaseCatcherArea()
public TestSceneCatcherArea()
{
AddSliderStep<float>("CircleSize", 0, 8, 5, createCatcher);
AddToggleStep("Hyperdash", t => catcherArea.ToggleHyperDash(t));

View File

@ -15,7 +15,7 @@ using osuTK;
namespace osu.Game.Rulesets.Catch.Tests
{
[TestFixture]
public class TestCaseFruitObjects : OsuTestCase
public class TestSceneFruitObjects : OsuTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Catch.Tests
typeof(Pulp),
};
public TestCaseFruitObjects()
public TestSceneFruitObjects()
{
Add(new GridContainer
{

View File

@ -10,9 +10,9 @@ using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Catch.Tests
{
[TestFixture]
public class TestCaseHyperDash : PlayerTestCase
public class TestSceneHyperDash : PlayerTestScene
{
public TestCaseHyperDash()
public TestSceneHyperDash()
: base(new CatchRuleset())
{
}

View File

@ -2,8 +2,8 @@
<Import Project="..\osu.TestProject.props" />
<ItemGroup Label="Package References">
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.0.1" />
<PackageReference Include="NUnit" Version="3.11.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.1.0" />
<PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
</ItemGroup>

View File

@ -57,33 +57,20 @@ namespace osu.Game.Rulesets.Catch.Difficulty
CatchHitObject lastObject = null;
foreach (var hitObject in beatmap.HitObjects.OfType<CatchHitObject>())
// In 2B beatmaps, it is possible that a normal Fruit is placed in the middle of a JuiceStream.
foreach (var hitObject in beatmap.HitObjects
.SelectMany(obj => obj is JuiceStream stream ? stream.NestedHitObjects : new[] { obj })
.Cast<CatchHitObject>()
.OrderBy(x => x.StartTime))
{
if (lastObject == null)
{
lastObject = hitObject;
// We want to only consider fruits that contribute to the combo.
if (hitObject is BananaShower || hitObject is TinyDroplet)
continue;
}
switch (hitObject)
{
// We want to only consider fruits that contribute to the combo. Droplets are addressed as accuracy and spinners are not relevant for "skill" calculations.
case Fruit fruit:
yield return new CatchDifficultyHitObject(fruit, lastObject, clockRate, halfCatchWidth);
if (lastObject != null)
yield return new CatchDifficultyHitObject(hitObject, lastObject, clockRate, halfCatchWidth);
lastObject = hitObject;
break;
case JuiceStream _:
foreach (var nested in hitObject.NestedHitObjects.OfType<CatchHitObject>().Where(o => !(o is TinyDroplet)))
{
yield return new CatchDifficultyHitObject(nested, lastObject, clockRate, halfCatchWidth);
lastObject = nested;
}
break;
}
lastObject = hitObject;
}
}

View File

@ -8,12 +8,12 @@ using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Mania.Tests
{
public abstract class ManiaInputTestCase : OsuTestCase
public abstract class ManiaInputTestScene : OsuTestScene
{
private readonly Container<Drawable> content;
protected override Container<Drawable> Content => content ?? base.Content;
protected ManiaInputTestCase(int keys)
protected ManiaInputTestScene(int keys)
{
base.Content.Add(content = new LocalInputManager(keys));
}

View File

@ -20,14 +20,14 @@ using osuTK.Graphics;
namespace osu.Game.Rulesets.Mania.Tests
{
[Cached(Type = typeof(IManiaHitObjectComposer))]
public abstract class ManiaPlacementBlueprintTestCase : PlacementBlueprintTestCase, IManiaHitObjectComposer
public abstract class ManiaPlacementBlueprintTestScene : PlacementBlueprintTestScene, IManiaHitObjectComposer
{
private readonly Column column;
[Cached(typeof(IReadOnlyList<Mod>))]
private IReadOnlyList<Mod> mods { get; set; } = Array.Empty<Mod>();
protected ManiaPlacementBlueprintTestCase()
protected ManiaPlacementBlueprintTestScene()
{
Add(column = new Column(0)
{

View File

@ -13,14 +13,14 @@ using osuTK.Graphics;
namespace osu.Game.Rulesets.Mania.Tests
{
[Cached(Type = typeof(IManiaHitObjectComposer))]
public abstract class ManiaSelectionBlueprintTestCase : SelectionBlueprintTestCase, IManiaHitObjectComposer
public abstract class ManiaSelectionBlueprintTestScene : SelectionBlueprintTestScene, IManiaHitObjectComposer
{
[Cached(Type = typeof(IAdjustableClock))]
private readonly IAdjustableClock clock = new StopwatchClock();
private readonly Column column;
protected ManiaSelectionBlueprintTestCase()
protected ManiaSelectionBlueprintTestScene()
{
Add(column = new Column(0)
{

View File

@ -12,7 +12,7 @@ using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Mania.Tests
{
[TestFixture]
public class TestCaseAutoGeneration : OsuTestCase
public class TestSceneAutoGeneration : OsuTestScene
{
[Test]
public void TestSingleNote()

View File

@ -22,7 +22,7 @@ using osuTK.Graphics;
namespace osu.Game.Rulesets.Mania.Tests
{
[TestFixture]
public class TestCaseColumn : ManiaInputTestCase
public class TestSceneColumn : ManiaInputTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
@ -37,7 +37,7 @@ namespace osu.Game.Rulesets.Mania.Tests
private readonly List<Column> columns = new List<Column>();
public TestCaseColumn()
public TestSceneColumn()
: base(2)
{
}

View File

@ -11,11 +11,11 @@ using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Mania.Tests
{
[TestFixture]
public class TestCaseEditor : EditorTestCase
public class TestSceneEditor : EditorTestScene
{
private readonly Bindable<ManiaScrollingDirection> direction = new Bindable<ManiaScrollingDirection>();
public TestCaseEditor()
public TestSceneEditor()
: base(new ManiaRuleset())
{
AddStep("upwards scroll", () => direction.Value = ManiaScrollingDirection.Up);

View File

@ -10,7 +10,7 @@ using osu.Game.Rulesets.Objects.Drawables;
namespace osu.Game.Rulesets.Mania.Tests
{
public class TestCaseHoldNotePlacementBlueprint : ManiaPlacementBlueprintTestCase
public class TestSceneHoldNotePlacementBlueprint : ManiaPlacementBlueprintTestScene
{
protected override DrawableHitObject CreateHitObject(HitObject hitObject) => new DrawableHoldNote((HoldNote)hitObject);
protected override PlacementBlueprint CreateBlueprint() => new HoldNotePlacementBlueprint();

View File

@ -15,14 +15,14 @@ using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Mania.Tests
{
public class TestCaseHoldNoteSelectionBlueprint : ManiaSelectionBlueprintTestCase
public class TestSceneHoldNoteSelectionBlueprint : ManiaSelectionBlueprintTestScene
{
private readonly DrawableHoldNote drawableObject;
protected override Container<Drawable> Content => content ?? base.Content;
private readonly Container content;
public TestCaseHoldNoteSelectionBlueprint()
public TestSceneHoldNoteSelectionBlueprint()
{
var holdNote = new HoldNote { Column = 0, Duration = 1000 };
holdNote.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());

View File

@ -10,7 +10,7 @@ using osu.Game.Rulesets.Objects.Drawables;
namespace osu.Game.Rulesets.Mania.Tests
{
public class TestCaseNotePlacementBlueprint : ManiaPlacementBlueprintTestCase
public class TestSceneNotePlacementBlueprint : ManiaPlacementBlueprintTestScene
{
protected override DrawableHitObject CreateHitObject(HitObject hitObject) => new DrawableNote((Note)hitObject);
protected override PlacementBlueprint CreateBlueprint() => new NotePlacementBlueprint();

View File

@ -15,14 +15,14 @@ using osuTK;
namespace osu.Game.Rulesets.Mania.Tests
{
public class TestCaseNoteSelectionBlueprint : ManiaSelectionBlueprintTestCase
public class TestSceneNoteSelectionBlueprint : ManiaSelectionBlueprintTestScene
{
private readonly DrawableNote drawableObject;
protected override Container<Drawable> Content => content ?? base.Content;
private readonly Container content;
public TestCaseNoteSelectionBlueprint()
public TestSceneNoteSelectionBlueprint()
{
var note = new Note { Column = 0 };
note.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());

View File

@ -11,10 +11,10 @@ using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mania.Objects.Drawables;
using osu.Game.Rulesets.Objects.Drawables;
@ -27,7 +27,7 @@ using osuTK.Graphics;
namespace osu.Game.Rulesets.Mania.Tests
{
[TestFixture]
public class TestCaseNotes : OsuTestCase
public class TestSceneNotes : OsuTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
@ -138,7 +138,7 @@ namespace osu.Game.Rulesets.Mania.Tests
content = new Container { RelativeSizeAxes = Axes.Both }
}
},
new SpriteText
new OsuSpriteText
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,

View File

@ -22,7 +22,7 @@ using osuTK;
namespace osu.Game.Rulesets.Mania.Tests
{
[TestFixture]
public class TestCaseStage : ManiaInputTestCase
public class TestSceneStage : ManiaInputTestScene
{
private const int columns = 4;
@ -33,7 +33,7 @@ namespace osu.Game.Rulesets.Mania.Tests
private FillFlowContainer<ScrollingTestContainer> fill;
public TestCaseStage()
public TestSceneStage()
: base(columns)
{
}

View File

@ -2,8 +2,8 @@
<Import Project="..\osu.TestProject.props" />
<ItemGroup Label="Package References">
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.0.1" />
<PackageReference Include="NUnit" Version="3.11.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.1.0" />
<PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
</ItemGroup>

View File

@ -7,9 +7,9 @@ using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Osu.Tests
{
[TestFixture]
public class TestCaseEditor : EditorTestCase
public class TestSceneEditor : EditorTestScene
{
public TestCaseEditor()
public TestSceneEditor()
: base(new OsuRuleset())
{
}

View File

@ -15,7 +15,7 @@ using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Osu.Tests
{
[TestFixture]
public class TestCaseGameplayCursor : OsuTestCase, IProvideCursor
public class TestSceneGameplayCursor : OsuTestScene, IProvideCursor
{
private GameplayCursorContainer cursorContainer;

View File

@ -19,7 +19,7 @@ using osu.Game.Rulesets.Scoring;
namespace osu.Game.Rulesets.Osu.Tests
{
[TestFixture]
public class TestCaseHitCircle : OsuTestCase
public class TestSceneHitCircle : OsuTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Osu.Tests
private int depthIndex;
public TestCaseHitCircle()
public TestSceneHitCircle()
{
base.Content.Add(content = new OsuInputManager(new RulesetInfo { ID = 0 }));

View File

@ -10,11 +10,11 @@ using osu.Game.Rulesets.Osu.Mods;
namespace osu.Game.Rulesets.Osu.Tests
{
[TestFixture]
public class TestCaseHitCircleHidden : TestCaseHitCircle
public class TestSceneHitCircleHidden : TestSceneHitCircle
{
public override IReadOnlyList<Type> RequiredTypes => base.RequiredTypes.Concat(new[] { typeof(OsuModHidden) }).ToList();
public TestCaseHitCircleHidden()
public TestSceneHitCircleHidden()
{
Mods.Value = new[] { new OsuModHidden() };
}

View File

@ -10,9 +10,9 @@ using osuTK;
namespace osu.Game.Rulesets.Osu.Tests
{
[TestFixture]
public class TestCaseHitCircleLongCombo : PlayerTestCase
public class TestSceneHitCircleLongCombo : PlayerTestScene
{
public TestCaseHitCircleLongCombo()
public TestSceneHitCircleLongCombo()
: base(new OsuRuleset())
{
}

View File

@ -11,7 +11,7 @@ using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Osu.Tests
{
public class TestCaseHitCirclePlacementBlueprint : PlacementBlueprintTestCase
public class TestSceneHitCirclePlacementBlueprint : PlacementBlueprintTestScene
{
protected override DrawableHitObject CreateHitObject(HitObject hitObject) => new DrawableHitCircle((HitCircle)hitObject);
protected override PlacementBlueprint CreateBlueprint() => new HitCirclePlacementBlueprint();

View File

@ -12,11 +12,11 @@ using osuTK;
namespace osu.Game.Rulesets.Osu.Tests
{
public class TestCaseHitCircleSelectionBlueprint : SelectionBlueprintTestCase
public class TestSceneHitCircleSelectionBlueprint : SelectionBlueprintTestScene
{
private readonly DrawableHitCircle drawableObject;
public TestCaseHitCircleSelectionBlueprint()
public TestSceneHitCircleSelectionBlueprint()
{
var hitCircle = new HitCircle { Position = new Vector2(256, 192) };
hitCircle.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty { CircleSize = 2 });

View File

@ -7,7 +7,7 @@ using osu.Game.Screens.Play;
namespace osu.Game.Rulesets.Osu.Tests
{
public class TestCaseOsuFlashlight : TestCaseOsuPlayer
public class TestSceneOsuFlashlight : TestSceneOsuPlayer
{
protected override Player CreatePlayer(Ruleset ruleset)
{

View File

@ -7,9 +7,9 @@ using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Osu.Tests
{
[TestFixture]
public class TestCaseOsuPlayer : PlayerTestCase
public class TestSceneOsuPlayer : PlayerTestScene
{
public TestCaseOsuPlayer()
public TestSceneOsuPlayer()
: base(new OsuRuleset())
{
}

View File

@ -12,14 +12,14 @@ using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Osu.Tests
{
public class TestCaseResumeOverlay : ManualInputManagerTestCase
public class TestSceneResumeOverlay : ManualInputManagerTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
typeof(OsuResumeOverlay),
};
public TestCaseResumeOverlay()
public TestSceneResumeOverlay()
{
ManualOsuInputManager osuInputManager;
CursorContainer cursor;

View File

@ -7,7 +7,7 @@ using osu.Game.Rulesets.Scoring;
namespace osu.Game.Rulesets.Osu.Tests
{
public class TestCaseShaking : TestCaseHitCircle
public class TestSceneShaking : TestSceneHitCircle
{
public override void Add(Drawable drawable)
{

View File

@ -27,7 +27,7 @@ using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces;
namespace osu.Game.Rulesets.Osu.Tests
{
[TestFixture]
public class TestCaseSlider : OsuTestCase
public class TestSceneSlider : OsuTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
@ -45,7 +45,7 @@ namespace osu.Game.Rulesets.Osu.Tests
private int depthIndex;
public TestCaseSlider()
public TestSceneSlider()
{
base.Content.Add(content = new OsuInputManager(new RulesetInfo { ID = 0 }));

View File

@ -10,11 +10,11 @@ using osu.Game.Rulesets.Osu.Mods;
namespace osu.Game.Rulesets.Osu.Tests
{
[TestFixture]
public class TestCaseSliderHidden : TestCaseSlider
public class TestSceneSliderHidden : TestSceneSlider
{
public override IReadOnlyList<Type> RequiredTypes => base.RequiredTypes.Concat(new[] { typeof(OsuModHidden) }).ToList();
public TestCaseSliderHidden()
public TestSceneSliderHidden()
{
Mods.Value = new[] { new OsuModHidden() };
}

View File

@ -26,7 +26,7 @@ using osuTK;
namespace osu.Game.Rulesets.Osu.Tests
{
public class TestCaseSliderInput : RateAdjustedBeatmapTestCase
public class TestSceneSliderInput : RateAdjustedBeatmapTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
@ -353,6 +353,8 @@ namespace osu.Game.Rulesets.Osu.Tests
{
public new ScoreProcessor ScoreProcessor => base.ScoreProcessor;
protected override bool PauseOnFocusLost => false;
public ScoreAccessibleReplayPlayer(Score score)
: base(score, false, false)
{

View File

@ -11,7 +11,7 @@ using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Osu.Tests
{
public class TestCaseSliderPlacementBlueprint : PlacementBlueprintTestCase
public class TestSceneSliderPlacementBlueprint : PlacementBlueprintTestScene
{
protected override DrawableHitObject CreateHitObject(HitObject hitObject) => new DrawableSlider((Slider)hitObject);
protected override PlacementBlueprint CreateBlueprint() => new SliderPlacementBlueprint();

View File

@ -17,7 +17,7 @@ using osuTK;
namespace osu.Game.Rulesets.Osu.Tests
{
public class TestCaseSliderSelectionBlueprint : SelectionBlueprintTestCase
public class TestSceneSliderSelectionBlueprint : SelectionBlueprintTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Osu.Tests
private readonly DrawableSlider drawableObject;
public TestCaseSliderSelectionBlueprint()
public TestSceneSliderSelectionBlueprint()
{
var slider = new Slider
{

View File

@ -18,7 +18,7 @@ using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Osu.Tests
{
[TestFixture]
public class TestCaseSpinner : OsuTestCase
public class TestSceneSpinner : OsuTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Osu.Tests
private int depthIndex;
public TestCaseSpinner()
public TestSceneSpinner()
{
base.Content.Add(content = new OsuInputManager(new RulesetInfo { ID = 0 }));

View File

@ -10,11 +10,11 @@ using osu.Game.Rulesets.Osu.Mods;
namespace osu.Game.Rulesets.Osu.Tests
{
[TestFixture]
public class TestCaseSpinnerHidden : TestCaseSpinner
public class TestSceneSpinnerHidden : TestSceneSpinner
{
public override IReadOnlyList<Type> RequiredTypes => base.RequiredTypes.Concat(new[] { typeof(OsuModHidden) }).ToList();
public TestCaseSpinnerHidden()
public TestSceneSpinnerHidden()
{
Mods.Value = new[] { new OsuModHidden() };
}

View File

@ -11,7 +11,7 @@ using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Osu.Tests
{
public class TestCaseSpinnerPlacementBlueprint : PlacementBlueprintTestCase
public class TestSceneSpinnerPlacementBlueprint : PlacementBlueprintTestScene
{
protected override DrawableHitObject CreateHitObject(HitObject hitObject) => new DrawableSpinner((Spinner)hitObject);

View File

@ -17,7 +17,7 @@ using osuTK;
namespace osu.Game.Rulesets.Osu.Tests
{
public class TestCaseSpinnerSelectionBlueprint : SelectionBlueprintTestCase
public class TestSceneSpinnerSelectionBlueprint : SelectionBlueprintTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Osu.Tests
private readonly DrawableSpinner drawableSpinner;
public TestCaseSpinnerSelectionBlueprint()
public TestSceneSpinnerSelectionBlueprint()
{
var spinner = new Spinner
{

View File

@ -2,8 +2,8 @@
<Import Project="..\osu.TestProject.props" />
<ItemGroup Label="Package References">
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.0.1" />
<PackageReference Include="NUnit" Version="3.11.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.1.0" />
<PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
</ItemGroup>

View File

@ -7,6 +7,7 @@ using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Input;
using osu.Framework.Input.Events;
using osu.Framework.MathUtils;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Osu.Objects;
@ -48,7 +49,14 @@ namespace osu.Game.Rulesets.Osu.Mods
protected override bool OnMouseMove(MouseMoveEvent e)
{
FlashlightPosition = e.MousePosition;
const double follow_delay = 120;
var position = FlashlightPosition;
var destination = e.MousePosition;
FlashlightPosition = Interpolation.ValueAt(
MathHelper.Clamp(Clock.ElapsedFrameTime, 0, follow_delay), position, destination, 0, follow_delay, Easing.Out);
return base.OnMouseMove(e);
}

View File

@ -160,9 +160,10 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
{
base.SkinChanged(skin, allowFallback);
Body.AccentColour = skin.GetValue<SkinConfiguration, Color4?>(s => s.CustomColours.ContainsKey("SliderTrackOverride") ? s.CustomColours["SliderTrackOverride"] : (Color4?)null) ?? Body.AccentColour;
Body.BorderColour = skin.GetValue<SkinConfiguration, Color4?>(s => s.CustomColours.ContainsKey("SliderBorder") ? s.CustomColours["SliderBorder"] : (Color4?)null) ?? Body.BorderColour;
Ball.AccentColour = skin.GetValue<SkinConfiguration, Color4?>(s => s.CustomColours.ContainsKey("SliderBall") ? s.CustomColours["SliderBall"] : (Color4?)null) ?? Ball.AccentColour;
Body.BorderSize = skin.GetValue<SkinConfiguration, float?>(s => s.SliderBorderSize) ?? SliderBody.DEFAULT_BORDER_SIZE;
Body.AccentColour = skin.GetValue<SkinConfiguration, Color4?>(s => s.CustomColours.ContainsKey("SliderTrackOverride") ? s.CustomColours["SliderTrackOverride"] : (Color4?)null) ?? AccentColour;
Body.BorderColour = skin.GetValue<SkinConfiguration, Color4?>(s => s.CustomColours.ContainsKey("SliderBorder") ? s.CustomColours["SliderBorder"] : (Color4?)null) ?? Color4.White;
Ball.AccentColour = skin.GetValue<SkinConfiguration, Color4?>(s => s.CustomColours.ContainsKey("SliderBall") ? s.CustomColours["SliderBall"] : (Color4?)null) ?? AccentColour;
}
protected override void CheckForResult(bool userTriggered, double timeOffset)

View File

@ -14,6 +14,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
{
public abstract class SliderBody : CompositeDrawable
{
public const float DEFAULT_BORDER_SIZE = 1;
private readonly SliderPath path;
protected Path Path => path;
@ -64,6 +66,23 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
}
}
/// <summary>
/// Used to size the path border.
/// </summary>
public float BorderSize
{
get => path.BorderSize;
set
{
if (path.BorderSize == value)
return;
path.BorderSize = value;
container.ForceRedraw();
}
}
public Quad PathDrawQuad => container.ScreenSpaceDrawQuad;
protected SliderBody()
@ -92,6 +111,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
private class SliderPath : SmoothPath
{
private const float border_max_size = 8f;
private const float border_min_size = 0f;
private const float border_portion = 0.128f;
private const float gradient_portion = 1 - border_portion;
@ -130,12 +152,33 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
}
}
private float borderSize = DEFAULT_BORDER_SIZE;
public float BorderSize
{
get => borderSize;
set
{
if (borderSize == value)
return;
if (value < border_min_size || value > border_max_size)
return;
borderSize = value;
InvalidateTexture();
}
}
private float calculatedBorderPortion => BorderSize * border_portion;
protected override Color4 ColourAt(float position)
{
if (position <= border_portion)
if (calculatedBorderPortion != 0f && position <= calculatedBorderPortion)
return BorderColour;
position -= border_portion;
position -= calculatedBorderPortion;
return new Color4(AccentColour.R, AccentColour.G, AccentColour.B, (opacity_at_edge - (opacity_at_edge - opacity_at_centre) * position / gradient_portion) * AccentColour.A);
}
}

View File

@ -63,8 +63,10 @@ namespace osu.Game.Rulesets.Osu.UI
{
get
{
var first = (OsuHitObject)Objects.First();
return first.StartTime - Math.Max(2000, first.TimePreempt);
if (Objects.FirstOrDefault() is OsuHitObject first)
return first.StartTime - Math.Max(2000, first.TimePreempt);
return 0;
}
}
}

View File

@ -16,7 +16,7 @@ using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Taiko.Tests
{
[TestFixture]
public class TestCaseInputDrum : OsuTestCase
public class TestSceneInputDrum : OsuTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Taiko.Tests
typeof(SampleControlPoint)
};
public TestCaseInputDrum()
public TestSceneInputDrum()
{
Add(new TaikoInputManager(new RulesetInfo { ID = 1 })
{

View File

@ -26,7 +26,7 @@ using osu.Game.Rulesets.Scoring;
namespace osu.Game.Rulesets.Taiko.Tests
{
[TestFixture]
public class TestCaseTaikoPlayfield : OsuTestCase
public class TestSceneTaikoPlayfield : OsuTestScene
{
private const double default_duration = 1000;
private const float scroll_time = 1000;

View File

@ -2,8 +2,8 @@
<Import Project="..\osu.TestProject.props" />
<ItemGroup Label="Package References">
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.0.1" />
<PackageReference Include="NUnit" Version="3.11.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.1.0" />
<PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
</ItemGroup>

View File

@ -170,27 +170,98 @@ namespace osu.Game.Tests.Beatmaps.Formats
var controlPoints = beatmap.ControlPointInfo;
Assert.AreEqual(4, controlPoints.TimingPoints.Count);
var timingPoint = controlPoints.TimingPoints[0];
Assert.AreEqual(42, controlPoints.DifficultyPoints.Count);
Assert.AreEqual(42, controlPoints.SamplePoints.Count);
Assert.AreEqual(42, controlPoints.EffectPoints.Count);
var timingPoint = controlPoints.TimingPointAt(0);
Assert.AreEqual(956, timingPoint.Time);
Assert.AreEqual(329.67032967033, timingPoint.BeatLength);
Assert.AreEqual(TimeSignatures.SimpleQuadruple, timingPoint.TimeSignature);
timingPoint = controlPoints.TimingPointAt(48428);
Assert.AreEqual(956, timingPoint.Time);
Assert.AreEqual(329.67032967033d, timingPoint.BeatLength);
Assert.AreEqual(TimeSignatures.SimpleQuadruple, timingPoint.TimeSignature);
Assert.AreEqual(5, controlPoints.DifficultyPoints.Count);
var difficultyPoint = controlPoints.DifficultyPoints[0];
Assert.AreEqual(116999, difficultyPoint.Time);
Assert.AreEqual(0.75000000000000189d, difficultyPoint.SpeedMultiplier);
timingPoint = controlPoints.TimingPointAt(119637);
Assert.AreEqual(119637, timingPoint.Time);
Assert.AreEqual(659.340659340659, timingPoint.BeatLength);
Assert.AreEqual(TimeSignatures.SimpleQuadruple, timingPoint.TimeSignature);
Assert.AreEqual(34, controlPoints.SamplePoints.Count);
var soundPoint = controlPoints.SamplePoints[0];
var difficultyPoint = controlPoints.DifficultyPointAt(0);
Assert.AreEqual(0, difficultyPoint.Time);
Assert.AreEqual(1.0, difficultyPoint.SpeedMultiplier);
difficultyPoint = controlPoints.DifficultyPointAt(48428);
Assert.AreEqual(48428, difficultyPoint.Time);
Assert.AreEqual(1.0, difficultyPoint.SpeedMultiplier);
difficultyPoint = controlPoints.DifficultyPointAt(116999);
Assert.AreEqual(116999, difficultyPoint.Time);
Assert.AreEqual(0.75, difficultyPoint.SpeedMultiplier, 0.1);
var soundPoint = controlPoints.SamplePointAt(0);
Assert.AreEqual(956, soundPoint.Time);
Assert.AreEqual("soft", soundPoint.SampleBank);
Assert.AreEqual(60, soundPoint.SampleVolume);
Assert.AreEqual(8, controlPoints.EffectPoints.Count);
var effectPoint = controlPoints.EffectPoints[0];
soundPoint = controlPoints.SamplePointAt(53373);
Assert.AreEqual(53373, soundPoint.Time);
Assert.AreEqual("soft", soundPoint.SampleBank);
Assert.AreEqual(60, soundPoint.SampleVolume);
soundPoint = controlPoints.SamplePointAt(119637);
Assert.AreEqual(119637, soundPoint.Time);
Assert.AreEqual("soft", soundPoint.SampleBank);
Assert.AreEqual(80, soundPoint.SampleVolume);
var effectPoint = controlPoints.EffectPointAt(0);
Assert.AreEqual(0, effectPoint.Time);
Assert.IsFalse(effectPoint.KiaiMode);
Assert.IsFalse(effectPoint.OmitFirstBarLine);
effectPoint = controlPoints.EffectPointAt(53703);
Assert.AreEqual(53703, effectPoint.Time);
Assert.IsTrue(effectPoint.KiaiMode);
Assert.IsFalse(effectPoint.OmitFirstBarLine);
effectPoint = controlPoints.EffectPointAt(119637);
Assert.AreEqual(119637, effectPoint.Time);
Assert.IsFalse(effectPoint.KiaiMode);
Assert.IsFalse(effectPoint.OmitFirstBarLine);
}
}
[Test]
public void TestDecodeOverlappingTimingPoints()
{
var decoder = new LegacyBeatmapDecoder { ApplyOffsets = false };
using (var resStream = TestResources.OpenResource("overlapping-control-points.osu"))
using (var stream = new StreamReader(resStream))
{
var controlPoints = decoder.Decode(stream).ControlPointInfo;
Assert.That(controlPoints.DifficultyPointAt(500).SpeedMultiplier, Is.EqualTo(1.5).Within(0.1));
Assert.That(controlPoints.DifficultyPointAt(1500).SpeedMultiplier, Is.EqualTo(1.5).Within(0.1));
Assert.That(controlPoints.DifficultyPointAt(2500).SpeedMultiplier, Is.EqualTo(0.75).Within(0.1));
Assert.That(controlPoints.DifficultyPointAt(3500).SpeedMultiplier, Is.EqualTo(1.5).Within(0.1));
Assert.That(controlPoints.EffectPointAt(500).KiaiMode, Is.True);
Assert.That(controlPoints.EffectPointAt(1500).KiaiMode, Is.True);
Assert.That(controlPoints.EffectPointAt(2500).KiaiMode, Is.False);
Assert.That(controlPoints.EffectPointAt(3500).KiaiMode, Is.True);
Assert.That(controlPoints.SamplePointAt(500).SampleBank, Is.EqualTo("drum"));
Assert.That(controlPoints.SamplePointAt(1500).SampleBank, Is.EqualTo("drum"));
Assert.That(controlPoints.SamplePointAt(2500).SampleBank, Is.EqualTo("normal"));
Assert.That(controlPoints.SamplePointAt(3500).SampleBank, Is.EqualTo("drum"));
Assert.That(controlPoints.TimingPointAt(500).BeatLength, Is.EqualTo(500).Within(0.1));
Assert.That(controlPoints.TimingPointAt(1500).BeatLength, Is.EqualTo(500).Within(0.1));
Assert.That(controlPoints.TimingPointAt(2500).BeatLength, Is.EqualTo(250).Within(0.1));
Assert.That(controlPoints.TimingPointAt(3500).BeatLength, Is.EqualTo(500).Within(0.1));
}
}

View File

@ -0,0 +1,56 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using System.IO;
using NUnit.Framework;
using osu.Game.Beatmaps.Formats;
using osu.Game.Tests.Resources;
namespace osu.Game.Tests.Beatmaps.Formats
{
[TestFixture]
public class LegacyDecoderTest
{
[Test]
public void TestDecodeComments()
{
var decoder = new LineLoggingDecoder(14);
using (var resStream = TestResources.OpenResource("comments.osu"))
using (var stream = new StreamReader(resStream))
{
decoder.Decode(stream);
Assert.That(decoder.ParsedLines, Has.None.EqualTo("// Combo1: 0, 0, 0"));
Assert.That(decoder.ParsedLines, Has.None.EqualTo("//Combo2: 0, 0, 0"));
Assert.That(decoder.ParsedLines, Has.None.EqualTo(" // Combo3: 0, 0, 0"));
Assert.That(decoder.ParsedLines, Has.One.EqualTo("Combo1: 100, 100, 100 // Comment at end of line"));
}
}
private class LineLoggingDecoder : LegacyDecoder<TestModel>
{
public readonly List<string> ParsedLines = new List<string>();
public LineLoggingDecoder(int version)
: base(version)
{
}
protected override bool ShouldSkipLine(string line)
{
var result = base.ShouldSkipLine(line);
if (!result)
ParsedLines.Add(line);
return result;
}
}
private class TestModel
{
}
}
}

View File

@ -65,7 +65,7 @@ namespace osu.Game.Tests.Chat
}
[Test]
public void TestCaseInsensitiveLinks()
public void TestInsensitiveLinks()
{
Message result = MessageFormatter.FormatMessage(new Message { Content = "look: http://puu.sh/7Ggh8xcC6/asf0asd9876.NEF" });

View File

@ -0,0 +1,9 @@
osu file format v14
[Colours]
// Combo1: 0, 0, 0
//Combo2: 0, 0, 0
// Combo3: 0, 0, 0
Combo1: 100, 100, 100 // Comment at end of line

View File

@ -0,0 +1,19 @@
osu file format v14
[TimingPoints]
// Timing then inherited
0,500,4,2,0,100,1,0
0,-66.6666666666667,4,3,0,100,0,1
// Inherited then timing (equivalent to previous)
1000,-66.6666666666667,4,3,0,100,0,1
1000,500,4,2,0,100,1,0
// Inherited then timing (different to previous)
2000,-133.333333333333,4,1,0,100,0,0
2000,250,4,2,0,100,1,0
// Timing then inherited (different to previous)
3000,500,4,2,0,100,1,0
3000,-66.6666666666667,4,3,0,100,0,1

View File

@ -9,7 +9,6 @@ using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Input.Events;
using osu.Framework.Input.States;
using osu.Framework.Platform;
@ -19,6 +18,7 @@ using osu.Game.Configuration;
using osu.Game.Database;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Scoring;
@ -35,7 +35,7 @@ using osuTK.Graphics;
namespace osu.Game.Tests.Visual.Background
{
[TestFixture]
public class TestCaseBackgroundScreenBeatmap : ManualInputManagerTestCase
public class TestSceneBackgroundScreenBeatmap : ManualInputManagerTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
@ -240,7 +240,7 @@ namespace osu.Game.Tests.Visual.Background
{
player.StoryboardEnabled.Value = false;
player.ReplacesBackground.Value = false;
player.CurrentStoryboardContainer.Add(new SpriteText
player.CurrentStoryboardContainer.Add(new OsuSpriteText
{
Size = new Vector2(250, 50),
Alpha = 1,
@ -328,7 +328,7 @@ namespace osu.Game.Tests.Visual.Background
public bool IsBlurCorrect() => ((FadeAccessibleBackground)Background).CurrentBlur == new Vector2(BACKGROUND_BLUR);
}
private class TestPlayer : Player
private class TestPlayer : Visual.TestPlayer
{
protected override BackgroundScreen CreateBackground() => new FadeAccessibleBackground(Beatmap.Value);

View File

@ -12,14 +12,14 @@ using osuTK.Graphics;
namespace osu.Game.Tests.Visual.Components
{
[TestFixture]
public class TestCaseIdleTracker : ManualInputManagerTestCase
public class TestSceneIdleTracker : ManualInputManagerTestScene
{
private readonly IdleTrackingBox box1;
private readonly IdleTrackingBox box2;
private readonly IdleTrackingBox box3;
private readonly IdleTrackingBox box4;
public TestCaseIdleTracker()
public TestSceneIdleTracker()
{
Children = new Drawable[]
{

View File

@ -15,7 +15,7 @@ using osuTK.Graphics;
namespace osu.Game.Tests.Visual.Components
{
public class TestCasePollingComponent : OsuTestCase
public class TestScenePollingComponent : OsuTestScene
{
private Container pollBox;
private TestPoller poller;

View File

@ -10,7 +10,7 @@ using osu.Game.Beatmaps;
namespace osu.Game.Tests.Visual.Components
{
public class TestCasePreviewTrackManager : OsuTestCase, IPreviewTrackOwner
public class TestScenePreviewTrackManager : OsuTestScene, IPreviewTrackOwner
{
private readonly PreviewTrackManager trackManager = new TestPreviewTrackManager();

View File

@ -11,7 +11,7 @@ using osuTK;
namespace osu.Game.Tests.Visual.Editor
{
public class TestCaseBeatDivisorControl : OsuTestCase
public class TestSceneBeatDivisorControl : OsuTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(BindableBeatDivisor) };

View File

@ -12,7 +12,7 @@ using osu.Game.Tests.Beatmaps;
namespace osu.Game.Tests.Visual.Editor
{
[TestFixture]
public class TestCaseEditorCompose : EditorClockTestCase
public class TestSceneEditorCompose : EditorClockTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(ComposeScreen) };

View File

@ -10,11 +10,11 @@ using osu.Game.Screens.Edit.Components.RadioButtons;
namespace osu.Game.Tests.Visual.Editor
{
[TestFixture]
public class TestCaseEditorComposeRadioButtons : OsuTestCase
public class TestSceneEditorComposeRadioButtons : OsuTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(DrawableRadioButton) };
public TestCaseEditorComposeRadioButtons()
public TestSceneEditorComposeRadioButtons()
{
RadioButtonCollection collection;
Add(collection = new RadioButtonCollection

View File

@ -19,7 +19,7 @@ using osuTK.Graphics;
namespace osu.Game.Tests.Visual.Editor
{
[TestFixture]
public class TestCaseEditorComposeTimeline : EditorClockTestCase
public class TestSceneEditorComposeTimeline : EditorClockTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{

View File

@ -13,11 +13,11 @@ using osu.Game.Screens.Edit.Components.Menus;
namespace osu.Game.Tests.Visual.Editor
{
[TestFixture]
public class TestCaseEditorMenuBar : OsuTestCase
public class TestSceneEditorMenuBar : OsuTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(EditorMenuBar), typeof(ScreenSelectionTabControl) };
public TestCaseEditorMenuBar()
public TestSceneEditorMenuBar()
{
Add(new Container
{

View File

@ -17,9 +17,9 @@ using osuTK.Graphics;
namespace osu.Game.Tests.Visual.Editor
{
[TestFixture]
public class TestCaseEditorSeekSnapping : EditorClockTestCase
public class TestSceneEditorSeekSnapping : EditorClockTestScene
{
public TestCaseEditorSeekSnapping()
public TestSceneEditorSeekSnapping()
{
BeatDivisor.Value = 4;
}

View File

@ -14,7 +14,7 @@ using osuTK;
namespace osu.Game.Tests.Visual.Editor
{
[TestFixture]
public class TestCaseEditorSummaryTimeline : EditorClockTestCase
public class TestSceneEditorSummaryTimeline : EditorClockTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(SummaryTimeline) };

View File

@ -25,7 +25,7 @@ namespace osu.Game.Tests.Visual.Editor
{
[TestFixture]
[Cached(Type = typeof(IPlacementHandler))]
public class TestCaseHitObjectComposer : OsuTestCase, IPlacementHandler
public class TestSceneHitObjectComposer : OsuTestScene, IPlacementHandler
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{

View File

@ -13,7 +13,7 @@ using osuTK;
namespace osu.Game.Tests.Visual.Editor
{
[TestFixture]
public class TestCasePlaybackControl : OsuTestCase
public class TestScenePlaybackControl : OsuTestScene
{
[BackgroundDependencyLoader]
private void load()

View File

@ -15,7 +15,7 @@ using osuTK.Graphics;
namespace osu.Game.Tests.Visual.Editor
{
[TestFixture]
public class TestCaseWaveContainer : OsuTestCase
public class TestSceneWaveContainer : OsuTestScene
{
[BackgroundDependencyLoader]
private void load(OsuColour colours)

View File

@ -15,7 +15,7 @@ using osuTK.Graphics;
namespace osu.Game.Tests.Visual.Editor
{
[TestFixture]
public class TestCaseWaveform : OsuTestCase
public class TestSceneWaveform : OsuTestScene
{
private WorkingBeatmap waveformBeatmap;

View File

@ -8,6 +8,7 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Primitives;
using osu.Framework.Graphics.Shapes;
using osu.Framework.MathUtils;
using osu.Framework.Testing;
using osu.Game.Graphics;
using osu.Game.Graphics.Cursor;
using osu.Game.Screens.Edit.Compose.Components.Timeline;
@ -16,40 +17,51 @@ using osuTK.Graphics;
namespace osu.Game.Tests.Visual.Editor
{
public class TestCaseZoomableScrollContainer : ManualInputManagerTestCase
public class TestSceneZoomableScrollContainer : ManualInputManagerTestScene
{
private readonly ZoomableScrollContainer scrollContainer;
private readonly Drawable innerBox;
private ZoomableScrollContainer scrollContainer;
private Drawable innerBox;
public TestCaseZoomableScrollContainer()
[SetUpSteps]
public void SetUpSteps()
{
Children = new Drawable[]
AddStep("Add new scroll container", () =>
{
new Container
Children = new Drawable[]
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.X,
Height = 250,
Width = 0.75f,
Children = new Drawable[]
new Container
{
new Box
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
RelativeSizeAxes = Axes.X,
Height = 250,
Width = 0.75f,
Children = new Drawable[]
{
RelativeSizeAxes = Axes.Both,
Colour = OsuColour.Gray(30)
},
scrollContainer = new ZoomableScrollContainer { RelativeSizeAxes = Axes.Both }
}
},
new MenuCursor()
};
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = OsuColour.Gray(30)
},
scrollContainer = new ZoomableScrollContainer { RelativeSizeAxes = Axes.Both }
}
},
new MenuCursor()
};
scrollContainer.Add(innerBox = new Box
{
RelativeSizeAxes = Axes.Both,
Colour = ColourInfo.GradientHorizontal(new Color4(0.8f, 0.6f, 0.4f, 1f), new Color4(0.4f, 0.6f, 0.8f, 1f))
scrollContainer.Add(innerBox = new Box
{
RelativeSizeAxes = Axes.Both,
Colour = ColourInfo.GradientHorizontal(new Color4(0.8f, 0.6f, 0.4f, 1f), new Color4(0.4f, 0.6f, 0.8f, 1f))
});
});
AddUntilStep("Scroll container is loaded", () => scrollContainer.LoadState >= LoadState.Loaded);
}
[Test]
public void TestWidthInitialization()
{
AddAssert("Inner container width was initialized", () => innerBox.DrawWidth > 0);
}
[Test]

View File

@ -10,7 +10,7 @@ using osu.Game.Screens.Play;
namespace osu.Game.Tests.Visual.Gameplay
{
[Description("Player instantiated with an autoplay mod.")]
public class TestCaseAutoplay : AllPlayersTestCase
public class TestSceneAutoplay : AllPlayersTestScene
{
protected override Player CreatePlayer(Ruleset ruleset)
{
@ -24,7 +24,7 @@ namespace osu.Game.Tests.Visual.Gameplay
AddUntilStep("key counter counted keys", () => ((ScoreAccessiblePlayer)Player).HUDOverlay.KeyCounter.Children.Any(kc => kc.CountPresses > 0));
}
private class ScoreAccessiblePlayer : Player
private class ScoreAccessiblePlayer : TestPlayer
{
public new ScoreProcessor ScoreProcessor => base.ScoreProcessor;
public new HUDOverlay HUDOverlay => base.HUDOverlay;

View File

@ -9,11 +9,11 @@ using osu.Game.Screens.Play;
namespace osu.Game.Tests.Visual.Gameplay
{
[TestFixture]
public class TestCaseBreakOverlay : OsuTestCase
public class TestSceneBreakOverlay : OsuTestScene
{
private readonly BreakOverlay breakOverlay;
public TestCaseBreakOverlay()
public TestSceneBreakOverlay()
{
Child = breakOverlay = new BreakOverlay(true);

View File

@ -10,7 +10,7 @@ using osu.Game.Rulesets.UI;
namespace osu.Game.Tests.Visual.Gameplay
{
public class TestCaseFrameStabilityContainer : OsuTestCase
public class TestSceneFrameStabilityContainer : OsuTestScene
{
private readonly ManualClock manualClock;
@ -18,7 +18,7 @@ namespace osu.Game.Tests.Visual.Gameplay
private ClockConsumingChild consumer;
public TestCaseFrameStabilityContainer()
public TestSceneFrameStabilityContainer()
{
Child = mainContainer = new Container
{
@ -73,6 +73,26 @@ namespace osu.Game.Tests.Visual.Gameplay
checkFrameCount(2);
}
[Test]
public void TestInitialSeekWithGameplayStart()
{
seekManualTo(1000);
createStabilityContainer(30000);
confirmSeek(1000);
checkFrameCount(0);
seekManualTo(10000);
confirmSeek(10000);
checkFrameCount(1);
seekManualTo(130000);
confirmSeek(130000);
checkFrameCount(6002);
}
[Test]
public void TestInitialSeek()
{
@ -83,7 +103,11 @@ namespace osu.Game.Tests.Visual.Gameplay
checkFrameCount(0);
}
private void createStabilityContainer() => AddStep("create container", () => mainContainer.Child = new FrameStabilityContainer().WithChild(consumer = new ClockConsumingChild()));
private const int max_frames_catchup = 50;
private void createStabilityContainer(double gameplayStartTime = double.MinValue) => AddStep("create container", () =>
mainContainer.Child = new FrameStabilityContainer(gameplayStartTime) { MaxCatchUpFrames = max_frames_catchup }
.WithChild(consumer = new ClockConsumingChild()));
private void seekManualTo(double time) => AddStep($"seek manual clock to {time}", () => manualClock.CurrentTime = time);

View File

@ -17,7 +17,7 @@ using osuTK.Input;
namespace osu.Game.Tests.Visual.Gameplay
{
[Description("player pause/fail screens")]
public class TestCaseGameplayMenuOverlay : ManualInputManagerTestCase
public class TestSceneGameplayMenuOverlay : ManualInputManagerTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(FailOverlay), typeof(PauseOverlay) };

View File

@ -13,7 +13,7 @@ using osuTK.Input;
namespace osu.Game.Tests.Visual.Gameplay
{
[Description("'Hold to Quit' UI element")]
public class TestCaseHoldForMenuButton : ManualInputManagerTestCase
public class TestSceneHoldForMenuButton : ManualInputManagerTestScene
{
private bool exitAction;

View File

@ -14,7 +14,7 @@ using osuTK.Input;
namespace osu.Game.Tests.Visual.Gameplay
{
[TestFixture]
public class TestCaseKeyCounter : ManualInputManagerTestCase
public class TestSceneKeyCounter : ManualInputManagerTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
@ -23,7 +23,7 @@ namespace osu.Game.Tests.Visual.Gameplay
typeof(KeyCounterDisplay)
};
public TestCaseKeyCounter()
public TestSceneKeyCounter()
{
KeyCounterKeyboard rewindTestKeyCounterKeyboard;
KeyCounterDisplay kc = new KeyCounterDisplay

View File

@ -11,7 +11,7 @@ using osu.Game.Users;
namespace osu.Game.Tests.Visual.Gameplay
{
[TestFixture]
public class TestCaseMedalOverlay : OsuTestCase
public class TestSceneMedalOverlay : OsuTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
@ -19,7 +19,7 @@ namespace osu.Game.Tests.Visual.Gameplay
typeof(DrawableMedal),
};
public TestCaseMedalOverlay()
public TestSceneMedalOverlay()
{
AddStep(@"display", () =>
{

View File

@ -6,6 +6,7 @@ using NUnit.Framework;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Screens;
using osu.Framework.Testing;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Cursor;
using osu.Game.Rulesets;
@ -17,7 +18,7 @@ using osuTK.Input;
namespace osu.Game.Tests.Visual.Gameplay
{
public class TestCasePause : PlayerTestCase
public class TestScenePause : PlayerTestScene
{
protected new PausePlayer Player => (PausePlayer)base.Player;
@ -25,12 +26,20 @@ namespace osu.Game.Tests.Visual.Gameplay
protected override Container<Drawable> Content => content;
public TestCasePause()
public TestScenePause()
: base(new OsuRuleset())
{
base.Content.Add(content = new MenuCursorContainer { RelativeSizeAxes = Axes.Both });
}
[SetUpSteps]
public override void SetUpSteps()
{
base.SetUpSteps();
AddStep("resume player", () => Player.GameplayClockContainer.Start());
confirmClockRunning(true);
}
[Test]
public void TestPauseResume()
{
@ -77,8 +86,8 @@ namespace osu.Game.Tests.Visual.Gameplay
AddStep("move cursor outside", () => InputManager.MoveMouseTo(Player.ScreenSpaceDrawQuad.TopLeft - new Vector2(10)));
pauseAndConfirm();
resumeAndConfirm();
resume();
pause();
confirmClockRunning(true);
@ -157,6 +166,8 @@ namespace osu.Game.Tests.Visual.Gameplay
private void confirmPaused()
{
confirmClockRunning(false);
AddAssert("player not exited", () => Player.IsCurrentScreen());
AddAssert("player not failed", () => !Player.HasFailed);
AddAssert("pause overlay shown", () => Player.PauseOverlayVisible);
}
@ -184,7 +195,7 @@ namespace osu.Game.Tests.Visual.Gameplay
protected override Player CreatePlayer(Ruleset ruleset) => new PausePlayer();
protected class PausePlayer : Player
protected class PausePlayer : TestPlayer
{
public new GameplayClockContainer GameplayClockContainer => base.GameplayClockContainer;
@ -196,10 +207,10 @@ namespace osu.Game.Tests.Visual.Gameplay
public bool PauseOverlayVisible => PauseOverlay.State == Visibility.Visible;
protected override void LoadComplete()
public override void OnEntering(IScreen last)
{
base.LoadComplete();
HUDOverlay.HoldToQuit.PauseOnFocusLost = false;
base.OnEntering(last);
GameplayClockContainer.Stop();
}
}
}

View File

@ -1,6 +1,7 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
@ -19,7 +20,7 @@ using osu.Game.Tests.Beatmaps;
namespace osu.Game.Tests.Visual.Gameplay
{
public class TestCasePlayerLoader : ManualInputManagerTestCase
public class TestScenePlayerLoader : ManualInputManagerTestScene
{
private PlayerLoader loader;
private OsuScreenStack stack;
@ -34,20 +35,20 @@ namespace osu.Game.Tests.Visual.Gameplay
[Test]
public void TestLoadContinuation()
{
AddStep("load dummy beatmap", () => stack.Push(loader = new PlayerLoader(() => new Player(false, false))));
Player player = null;
SlowLoadPlayer slowPlayer = null;
AddStep("load dummy beatmap", () => stack.Push(loader = new PlayerLoader(() => player = new TestPlayer(false, false))));
AddUntilStep("wait for current", () => loader.IsCurrentScreen());
AddStep("mouse in centre", () => InputManager.MoveMouseTo(loader.ScreenSpaceDrawQuad.Centre));
AddUntilStep("wait for no longer current", () => !loader.IsCurrentScreen());
AddUntilStep("wait for player to be current", () => player.IsCurrentScreen());
AddStep("load slow dummy beatmap", () =>
{
SlowLoadPlayer slow = null;
stack.Push(loader = new PlayerLoader(() => slow = new SlowLoadPlayer(false, false)));
Scheduler.AddDelayed(() => slow.Ready = true, 5000);
stack.Push(loader = new PlayerLoader(() => slowPlayer = new SlowLoadPlayer(false, false)));
Scheduler.AddDelayed(() => slowPlayer.AllowLoad.Set(), 5000);
});
AddUntilStep("wait for no longer current", () => !loader.IsCurrentScreen());
AddUntilStep("wait for player to be current", () => slowPlayer.IsCurrentScreen());
}
[Test]
@ -101,19 +102,19 @@ namespace osu.Game.Tests.Visual.Gameplay
public ScoreRank AdjustRank(ScoreRank rank, double accuracy) => rank;
}
private class TestPlayer : Player
private class TestPlayer : Visual.TestPlayer
{
public new Bindable<IReadOnlyList<Mod>> Mods => base.Mods;
public TestPlayer()
: base(false, false)
public TestPlayer(bool allowPause = true, bool showResults = true)
: base(allowPause, showResults)
{
}
}
protected class SlowLoadPlayer : Player
protected class SlowLoadPlayer : Visual.TestPlayer
{
public bool Ready;
public readonly ManualResetEventSlim AllowLoad = new ManualResetEventSlim(false);
public SlowLoadPlayer(bool allowPause = true, bool showResults = true)
: base(allowPause, showResults)
@ -123,8 +124,8 @@ namespace osu.Game.Tests.Visual.Gameplay
[BackgroundDependencyLoader]
private void load()
{
while (!Ready)
Thread.Sleep(1);
if (!AllowLoad.Wait(TimeSpan.FromSeconds(10)))
throw new TimeoutException();
}
}
}

View File

@ -10,7 +10,7 @@ using osu.Game.Screens.Play;
namespace osu.Game.Tests.Visual.Gameplay
{
public class TestCasePlayerReferenceLeaking : AllPlayersTestCase
public class TestScenePlayerReferenceLeaking : AllPlayersTestScene
{
private readonly WeakList<WorkingBeatmap> workingWeakReferences = new WeakList<WorkingBeatmap>();
@ -24,7 +24,9 @@ namespace osu.Game.Tests.Visual.Gameplay
GC.WaitForPendingFinalizers();
int count = 0;
workingWeakReferences.ForEachAlive(_ => count++);
foreach (var unused in workingWeakReferences)
count++;
return count == 1;
});
@ -34,7 +36,9 @@ namespace osu.Game.Tests.Visual.Gameplay
GC.WaitForPendingFinalizers();
int count = 0;
playerWeakReferences.ForEachAlive(_ => count++);
foreach (var unused in playerWeakReferences)
count++;
return count == 1;
});
}

View File

@ -13,7 +13,7 @@ using osu.Game.Screens.Play;
namespace osu.Game.Tests.Visual.Gameplay
{
[Description("Player instantiated with a replay.")]
public class TestCaseReplay : AllPlayersTestCase
public class TestSceneReplay : AllPlayersTestScene
{
protected override Player CreatePlayer(Ruleset ruleset)
{
@ -33,6 +33,8 @@ namespace osu.Game.Tests.Visual.Gameplay
public new ScoreProcessor ScoreProcessor => base.ScoreProcessor;
public new HUDOverlay HUDOverlay => base.HUDOverlay;
protected override bool PauseOnFocusLost => false;
public ScoreAccessibleReplayPlayer(Score score)
: base(score)
{

View File

@ -10,9 +10,9 @@ using osu.Game.Screens.Play.PlayerSettings;
namespace osu.Game.Tests.Visual.Gameplay
{
[TestFixture]
public class TestCaseReplaySettingsOverlay : OsuTestCase
public class TestSceneReplaySettingsOverlay : OsuTestScene
{
public TestCaseReplaySettingsOverlay()
public TestSceneReplaySettingsOverlay()
{
ExampleContainer container;

View File

@ -16,7 +16,7 @@ using osu.Game.Users;
namespace osu.Game.Tests.Visual.Gameplay
{
[TestFixture]
public class TestCaseResults : ScreenTestCase
public class TestSceneResults : ScreenTestScene
{
private BeatmapManager beatmaps;

View File

@ -5,6 +5,7 @@ using NUnit.Framework;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Framework.MathUtils;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Screens.Play.HUD;
using osuTK;
@ -12,9 +13,9 @@ using osuTK;
namespace osu.Game.Tests.Visual.Gameplay
{
[TestFixture]
public class TestCaseScoreCounter : OsuTestCase
public class TestSceneScoreCounter : OsuTestScene
{
public TestCaseScoreCounter()
public TestSceneScoreCounter()
{
int numerator = 0, denominator = 0;
@ -53,7 +54,7 @@ namespace osu.Game.Tests.Visual.Gameplay
};
Add(stars);
SpriteText starsLabel = new SpriteText
SpriteText starsLabel = new OsuSpriteText
{
Origin = Anchor.BottomLeft,
Anchor = Anchor.BottomLeft,

View File

@ -21,7 +21,7 @@ using osuTK;
namespace osu.Game.Tests.Visual.Gameplay
{
[TestFixture]
public class TestCaseScrollingHitObjects : OsuTestCase
public class TestSceneScrollingHitObjects : OsuTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[] { typeof(Playfield) };
@ -31,7 +31,7 @@ namespace osu.Game.Tests.Visual.Gameplay
private readonly ScrollingTestContainer[] scrollContainers = new ScrollingTestContainer[4];
private readonly TestPlayfield[] playfields = new TestPlayfield[4];
public TestCaseScrollingHitObjects()
public TestSceneScrollingHitObjects()
{
Add(new GridContainer
{

View File

@ -7,15 +7,15 @@ using osu.Framework.Audio.Sample;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Skinning;
using osuTK.Graphics;
namespace osu.Game.Tests.Visual.Gameplay
{
public class TestCaseSkinReloadable : OsuTestCase
public class TestSceneSkinReloadable : OsuTestScene
{
[Test]
public void TestInitialLoad()
@ -76,7 +76,7 @@ namespace osu.Game.Tests.Visual.Gameplay
Colour = Color4.Black,
RelativeSizeAxes = Axes.Both,
},
new SpriteText
new OsuSpriteText
{
Font = OsuFont.Default.With(size: 40),
Anchor = Anchor.Centre,

View File

@ -7,7 +7,7 @@ using osu.Game.Screens.Play;
namespace osu.Game.Tests.Visual.Gameplay
{
[TestFixture]
public class TestCaseSkipOverlay : OsuTestCase
public class TestSceneSkipOverlay : OsuTestScene
{
protected override void LoadComplete()
{

View File

@ -13,7 +13,7 @@ using osu.Game.Screens.Play;
namespace osu.Game.Tests.Visual.Gameplay
{
[TestFixture]
public class TestCaseSongProgress : OsuTestCase
public class TestSceneSongProgress : OsuTestScene
{
private readonly SongProgress progress;
private readonly TestSongProgressGraph graph;
@ -25,7 +25,7 @@ namespace osu.Game.Tests.Visual.Gameplay
private readonly FramedClock framedClock;
public TestCaseSongProgress()
public TestSceneSongProgress()
{
clock = new StopwatchClock(true);

View File

@ -16,12 +16,12 @@ using osuTK.Graphics;
namespace osu.Game.Tests.Visual.Gameplay
{
[TestFixture]
public class TestCaseStoryboard : OsuTestCase
public class TestSceneStoryboard : OsuTestScene
{
private readonly Container<DrawableStoryboard> storyboardContainer;
private DrawableStoryboard storyboard;
public TestCaseStoryboard()
public TestSceneStoryboard()
{
Clock = new FramedClock();

View File

@ -8,7 +8,7 @@ using osu.Game.Users;
namespace osu.Game.Tests.Visual.Menus
{
public class TestCaseDisclaimer : ScreenTestCase
public class TestSceneDisclaimer : ScreenTestScene
{
[Cached(typeof(IAPIProvider))]
private readonly DummyAPIAccess api = new DummyAPIAccess();

View File

@ -14,14 +14,14 @@ using osuTK.Graphics;
namespace osu.Game.Tests.Visual.Menus
{
[TestFixture]
public class TestCaseIntroSequence : OsuTestCase
public class TestSceneIntroSequence : OsuTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
typeof(OsuLogo),
};
public TestCaseIntroSequence()
public TestSceneIntroSequence()
{
OsuLogo logo;

View File

@ -14,14 +14,14 @@ using osuTK.Graphics;
namespace osu.Game.Tests.Visual.Menus
{
[TestFixture]
public class TestCaseLoaderAnimation : ScreenTestCase
public class TestSceneLoaderAnimation : ScreenTestScene
{
private TestLoader loader;
[Cached]
private OsuLogo logo;
public TestCaseLoaderAnimation()
public TestSceneLoaderAnimation()
{
Child = logo = new OsuLogo
{
@ -53,38 +53,12 @@ namespace osu.Game.Tests.Visual.Menus
}
[Test]
public void TestShortLoad()
public void TestDelayedLoad()
{
bool logoVisible = false;
AddStep("begin loading", () => LoadScreen(loader = new TestLoader()));
AddWaitStep("wait", 2);
AddStep("finish loading", () =>
{
logoVisible = loader.Logo?.Alpha > 0;
loader.AllowLoad.Set();
});
AddUntilStep("wait for logo visible", () => loader.Logo?.Alpha > 0);
AddStep("finish loading", () => loader.AllowLoad.Set());
AddAssert("loaded", () => loader.Logo != null && loader.ScreenLoaded);
AddAssert("logo was visible", () => logoVisible);
AddUntilStep("logo gone", () => loader.Logo?.Alpha == 0);
}
[Test]
public void TestLongLoad()
{
bool logoVisible = false;
AddStep("begin loading", () => LoadScreen(loader = new TestLoader()));
AddWaitStep("wait", 10);
AddStep("finish loading", () =>
{
logoVisible = loader.Logo?.Alpha > 0;
loader.AllowLoad.Set();
});
AddAssert("loaded", () => loader.Logo != null && loader.ScreenLoaded);
AddAssert("logo was visible", () => logoVisible);
AddUntilStep("logo gone", () => loader.Logo?.Alpha == 0);
}

View File

@ -11,7 +11,7 @@ using osu.Game.Overlays.Toolbar;
namespace osu.Game.Tests.Visual.Menus
{
[TestFixture]
public class TestCaseToolbar : OsuTestCase
public class TestSceneToolbar : OsuTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
@ -21,7 +21,7 @@ namespace osu.Game.Tests.Visual.Menus
typeof(ToolbarNotificationButton),
};
public TestCaseToolbar()
public TestSceneToolbar()
{
var toolbar = new Toolbar { State = Visibility.Visible };
ToolbarNotificationButton notificationButton = null;

View File

@ -16,7 +16,7 @@ using osuTK.Graphics;
namespace osu.Game.Tests.Visual.Multiplayer
{
public class TestCaseLoungeRoomsContainer : MultiplayerTestCase
public class TestSceneLoungeRoomsContainer : MultiplayerTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{

View File

@ -12,14 +12,14 @@ using osu.Game.Screens.Multi.Match.Components;
namespace osu.Game.Tests.Visual.Multiplayer
{
public class TestCaseMatchHeader : MultiplayerTestCase
public class TestSceneMatchHeader : MultiplayerTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
typeof(Header)
};
public TestCaseMatchHeader()
public TestSceneMatchHeader()
{
Room.Playlist.Add(new PlaylistItem
{

View File

@ -10,7 +10,7 @@ using osu.Game.Users;
namespace osu.Game.Tests.Visual.Multiplayer
{
public class TestCaseMatchHostInfo : OsuTestCase
public class TestSceneMatchHostInfo : OsuTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{
@ -19,7 +19,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
private readonly Bindable<User> host = new Bindable<User>(new User { Username = "SomeHost" });
public TestCaseMatchHostInfo()
public TestSceneMatchHostInfo()
{
HostInfo hostInfo;

View File

@ -14,7 +14,7 @@ using osu.Game.Screens.Multi.Match.Components;
namespace osu.Game.Tests.Visual.Multiplayer
{
[TestFixture]
public class TestCaseMatchInfo : MultiplayerTestCase
public class TestSceneMatchInfo : MultiplayerTestScene
{
public override IReadOnlyList<Type> RequiredTypes => new[]
{

Some files were not shown because too many files have changed in this diff Show More