mirror of
https://github.com/ppy/osu.git
synced 2024-11-11 12:57:36 +08:00
Move analysis container implementation completely local to osu! ruleset
This commit is contained in:
parent
0e16508fd6
commit
a417fec234
@ -1,13 +1,12 @@
|
||||
// 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.
|
||||
|
||||
#nullable disable
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Replays;
|
||||
using osu.Game.Rulesets.Osu.Beatmaps;
|
||||
using osu.Game.Rulesets.Osu.Replays;
|
||||
@ -21,91 +20,50 @@ namespace osu.Game.Rulesets.Osu.Tests
|
||||
{
|
||||
public partial class TestSceneOsuAnalysisContainer : OsuTestScene
|
||||
{
|
||||
private TestOsuAnalysisContainer analysisContainer;
|
||||
private TestOsuAnalysisContainer analysisContainer = null!;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
[SetUpSteps]
|
||||
public void SetUpSteps()
|
||||
{
|
||||
Child = analysisContainer = createAnalysisContainer();
|
||||
AddStep("create analysis container", () =>
|
||||
{
|
||||
DrawableOsuRuleset drawableRuleset = new DrawableOsuRuleset(new OsuRuleset(), new OsuBeatmap());
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
drawableRuleset,
|
||||
analysisContainer = new TestOsuAnalysisContainer(fabricateReplay(), drawableRuleset),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestHitMarkers()
|
||||
{
|
||||
AddStep("enable hit markers", () => analysisContainer.AnalysisSettings.HitMarkersEnabled.Value = true);
|
||||
AddStep("enable hit markers", () => analysisContainer.Settings.HitMarkersEnabled.Value = true);
|
||||
AddAssert("hit markers visible", () => analysisContainer.HitMarkersVisible);
|
||||
AddStep("disable hit markers", () => analysisContainer.AnalysisSettings.HitMarkersEnabled.Value = false);
|
||||
AddStep("disable hit markers", () => analysisContainer.Settings.HitMarkersEnabled.Value = false);
|
||||
AddAssert("hit markers not visible", () => !analysisContainer.HitMarkersVisible);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAimMarker()
|
||||
{
|
||||
AddStep("enable aim markers", () => analysisContainer.AnalysisSettings.AimMarkersEnabled.Value = true);
|
||||
AddStep("enable aim markers", () => analysisContainer.Settings.AimMarkersEnabled.Value = true);
|
||||
AddAssert("aim markers visible", () => analysisContainer.AimMarkersVisible);
|
||||
AddStep("disable aim markers", () => analysisContainer.AnalysisSettings.AimMarkersEnabled.Value = false);
|
||||
AddStep("disable aim markers", () => analysisContainer.Settings.AimMarkersEnabled.Value = false);
|
||||
AddAssert("aim markers not visible", () => !analysisContainer.AimMarkersVisible);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAimLines()
|
||||
{
|
||||
AddStep("enable aim lines", () => analysisContainer.AnalysisSettings.AimLinesEnabled.Value = true);
|
||||
AddStep("enable aim lines", () => analysisContainer.Settings.AimLinesEnabled.Value = true);
|
||||
AddAssert("aim lines visible", () => analysisContainer.AimLinesVisible);
|
||||
AddStep("disable aim lines", () => analysisContainer.AnalysisSettings.AimLinesEnabled.Value = false);
|
||||
AddStep("disable aim lines", () => analysisContainer.Settings.AimLinesEnabled.Value = false);
|
||||
AddAssert("aim lines not visible", () => !analysisContainer.AimLinesVisible);
|
||||
}
|
||||
|
||||
private TestOsuAnalysisContainer createAnalysisContainer()
|
||||
{
|
||||
var replay = new Replay();
|
||||
var ruleset = new OsuRuleset();
|
||||
var beatmap = new OsuBeatmap();
|
||||
var drawableRuleset = new DrawableOsuRuleset(ruleset, beatmap);
|
||||
// Load playfield cursor to avoid errors
|
||||
Add(drawableRuleset);
|
||||
|
||||
return new TestOsuAnalysisContainer(replay, drawableRuleset);
|
||||
}
|
||||
|
||||
private partial class TestOsuAnalysisContainer : OsuAnalysisContainer
|
||||
{
|
||||
public TestOsuAnalysisContainer(Replay replay, DrawableRuleset drawableRuleset)
|
||||
: base(replay, drawableRuleset)
|
||||
{
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
Replay = fabricateReplay();
|
||||
LoadReplay();
|
||||
|
||||
makeReplayLoop();
|
||||
}
|
||||
|
||||
private void makeReplayLoop()
|
||||
{
|
||||
Scheduler.AddDelayed(() =>
|
||||
{
|
||||
Replay = fabricateReplay();
|
||||
|
||||
HitMarkers.Clear();
|
||||
AimMarkers.Clear();
|
||||
AimLines.Clear();
|
||||
|
||||
LoadReplay();
|
||||
|
||||
makeReplayLoop();
|
||||
}, 15000);
|
||||
}
|
||||
|
||||
public bool HitMarkersVisible => HitMarkers.Alpha > 0 && HitMarkers.Entries.Any();
|
||||
|
||||
public bool AimMarkersVisible => AimMarkers.Alpha > 0 && AimMarkers.Entries.Any();
|
||||
|
||||
public bool AimLinesVisible => AimLines.Alpha > 0 && AimLines.Vertices.Count > 1;
|
||||
|
||||
private Replay fabricateReplay()
|
||||
{
|
||||
var frames = new List<ReplayFrame>();
|
||||
@ -137,6 +95,17 @@ namespace osu.Game.Rulesets.Osu.Tests
|
||||
|
||||
return new Replay { Frames = frames };
|
||||
}
|
||||
|
||||
private partial class TestOsuAnalysisContainer : OsuAnalysisContainer
|
||||
{
|
||||
public TestOsuAnalysisContainer(Replay replay, DrawableRuleset drawableRuleset)
|
||||
: base(replay, drawableRuleset)
|
||||
{
|
||||
}
|
||||
|
||||
public bool HitMarkersVisible => HitMarkers.Alpha > 0 && HitMarkers.Entries.Any();
|
||||
public bool AimMarkersVisible => AimMarkers.Alpha > 0 && AimMarkers.Entries.Any();
|
||||
public bool AimLinesVisible => AimLines.Alpha > 0 && AimLines.Vertices.Count > 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -36,6 +36,14 @@ namespace osu.Game.Rulesets.Osu.UI
|
||||
{
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
if (HasReplayLoaded.Value)
|
||||
LoadComponentAsync(new OsuAnalysisContainer(ReplayScore.Replay, this), PlayfieldAdjustmentContainer.Add);
|
||||
|
||||
base.LoadComplete();
|
||||
}
|
||||
|
||||
public override DrawableHitObject<OsuHitObject> CreateDrawableRepresentation(OsuHitObject h) => null;
|
||||
|
||||
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true; // always show the gameplay cursor
|
||||
@ -68,7 +76,5 @@ namespace osu.Game.Rulesets.Osu.UI
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public override AnalysisContainer CreateAnalysisContainer(Replay replay) => new OsuAnalysisContainer(replay, this);
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Lines;
|
||||
using osu.Framework.Graphics.Performance;
|
||||
using osu.Framework.Graphics.Pooling;
|
||||
@ -18,62 +19,62 @@ using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.UI
|
||||
{
|
||||
public partial class OsuAnalysisContainer : AnalysisContainer
|
||||
public partial class OsuAnalysisContainer : CompositeDrawable
|
||||
{
|
||||
public new OsuAnalysisSettings AnalysisSettings => (OsuAnalysisSettings)base.AnalysisSettings;
|
||||
protected readonly HitMarkersContainer HitMarkers;
|
||||
protected readonly AimMarkersContainer AimMarkers;
|
||||
protected readonly AimLinesContainer AimLines;
|
||||
|
||||
protected new DrawableOsuRuleset DrawableRuleset => (DrawableOsuRuleset)base.DrawableRuleset;
|
||||
public OsuAnalysisSettings Settings = null!;
|
||||
|
||||
protected HitMarkersContainer HitMarkers;
|
||||
protected AimMarkersContainer AimMarkers;
|
||||
protected AimLinesContainer AimLines;
|
||||
private readonly Replay replay;
|
||||
private readonly DrawableRuleset drawableRuleset;
|
||||
|
||||
public OsuAnalysisContainer(Replay replay, DrawableRuleset drawableRuleset)
|
||||
: base(replay, drawableRuleset)
|
||||
{
|
||||
this.replay = replay;
|
||||
this.drawableRuleset = drawableRuleset;
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
AimLines = new AimLinesContainer { Depth = float.MaxValue },
|
||||
HitMarkers = new HitMarkersContainer(),
|
||||
AimMarkers = new AimMarkersContainer { Depth = float.MinValue }
|
||||
AimLines = new AimLinesContainer(),
|
||||
AimMarkers = new AimMarkersContainer(),
|
||||
};
|
||||
}
|
||||
|
||||
protected override OsuAnalysisSettings CreateAnalysisSettings(Ruleset ruleset)
|
||||
{
|
||||
var settings = new OsuAnalysisSettings((OsuRuleset)ruleset);
|
||||
settings.HitMarkersEnabled.ValueChanged += e => toggleHitMarkers(e.NewValue);
|
||||
settings.AimMarkersEnabled.ValueChanged += e => toggleAimMarkers(e.NewValue);
|
||||
settings.AimLinesEnabled.ValueChanged += e => toggleAimLines(e.NewValue);
|
||||
settings.CursorHideEnabled.ValueChanged += e => toggleCursorHidden(e.NewValue);
|
||||
return settings;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
toggleHitMarkers(AnalysisSettings.HitMarkersEnabled.Value);
|
||||
toggleAimMarkers(AnalysisSettings.AimMarkersEnabled.Value);
|
||||
toggleAimLines(AnalysisSettings.AimLinesEnabled.Value);
|
||||
toggleCursorHidden(AnalysisSettings.CursorHideEnabled.Value);
|
||||
AddInternal(Settings = new OsuAnalysisSettings());
|
||||
|
||||
LoadReplay();
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
Settings.HitMarkersEnabled.BindValueChanged(e => toggleHitMarkers(e.NewValue), true);
|
||||
Settings.AimMarkersEnabled.BindValueChanged(e => toggleAimMarkers(e.NewValue), true);
|
||||
Settings.AimLinesEnabled.BindValueChanged(e => toggleAimLines(e.NewValue), true);
|
||||
Settings.CursorHideEnabled.BindValueChanged(e => toggleCursorHidden(e.NewValue), true);
|
||||
}
|
||||
|
||||
private void toggleHitMarkers(bool value) => HitMarkers.FadeTo(value ? 1 : 0);
|
||||
|
||||
private void toggleAimMarkers(bool value) => AimMarkers.FadeTo(value ? 1 : 0);
|
||||
|
||||
private void toggleAimLines(bool value) => AimLines.FadeTo(value ? 1 : 0);
|
||||
|
||||
private void toggleCursorHidden(bool value) => DrawableRuleset.Playfield.Cursor.FadeTo(value ? 0 : 1);
|
||||
private void toggleCursorHidden(bool value) => drawableRuleset.Playfield.Cursor.FadeTo(value ? 0 : 1);
|
||||
|
||||
protected void LoadReplay()
|
||||
{
|
||||
bool leftHeld = false;
|
||||
bool rightHeld = false;
|
||||
|
||||
foreach (var frame in Replay.Frames)
|
||||
foreach (var frame in replay.Frames)
|
||||
{
|
||||
var osuFrame = (OsuReplayFrame)frame;
|
||||
|
||||
|
@ -9,13 +9,8 @@ using osu.Game.Screens.Play.PlayerSettings;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.UI
|
||||
{
|
||||
public partial class OsuAnalysisSettings : AnalysisSettings
|
||||
public partial class OsuAnalysisSettings : PlayerSettingsGroup
|
||||
{
|
||||
public OsuAnalysisSettings(Ruleset ruleset)
|
||||
: base(ruleset)
|
||||
{
|
||||
}
|
||||
|
||||
[SettingSource("Hit markers", SettingControlType = typeof(PlayerCheckbox))]
|
||||
public BindableBool HitMarkersEnabled { get; } = new BindableBool();
|
||||
|
||||
@ -28,10 +23,18 @@ namespace osu.Game.Rulesets.Osu.UI
|
||||
[SettingSource("Hide cursor", SettingControlType = typeof(PlayerCheckbox))]
|
||||
public BindableBool CursorHideEnabled { get; } = new BindableBool();
|
||||
|
||||
public OsuAnalysisSettings()
|
||||
: base("Analysis Settings")
|
||||
{
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(IRulesetConfigCache cache)
|
||||
{
|
||||
var config = (OsuRulesetConfigManager)cache.GetConfigFor(Ruleset)!;
|
||||
AddRange(this.CreateSettingsControls());
|
||||
|
||||
var config = (OsuRulesetConfigManager)cache.GetConfigFor(new OsuRuleset())!;
|
||||
|
||||
config.BindWith(OsuRulesetSetting.ReplayHitMarkersEnabled, HitMarkersEnabled);
|
||||
config.BindWith(OsuRulesetSetting.ReplayAimMarkersEnabled, AimMarkersEnabled);
|
||||
config.BindWith(OsuRulesetSetting.ReplayAimLinesEnabled, AimLinesEnabled);
|
||||
|
@ -406,7 +406,5 @@ namespace osu.Game.Rulesets
|
||||
/// Can be overridden to avoid showing scroll speed changes in the editor.
|
||||
/// </summary>
|
||||
public virtual bool EditorShowScrollSpeed => true;
|
||||
|
||||
public virtual DifficultySection? CreateEditorDifficultySection() => null;
|
||||
}
|
||||
}
|
||||
|
@ -1,27 +0,0 @@
|
||||
// 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 osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Replays;
|
||||
using osu.Game.Screens.Play.PlayerSettings;
|
||||
|
||||
namespace osu.Game.Rulesets.UI
|
||||
{
|
||||
public abstract partial class AnalysisContainer : Container
|
||||
{
|
||||
protected Replay Replay;
|
||||
protected DrawableRuleset DrawableRuleset;
|
||||
|
||||
public AnalysisSettings AnalysisSettings;
|
||||
|
||||
protected AnalysisContainer(Replay replay, DrawableRuleset drawableRuleset)
|
||||
{
|
||||
Replay = replay;
|
||||
DrawableRuleset = drawableRuleset;
|
||||
|
||||
AnalysisSettings = CreateAnalysisSettings(drawableRuleset.Ruleset);
|
||||
}
|
||||
|
||||
protected abstract AnalysisSettings CreateAnalysisSettings(Ruleset ruleset);
|
||||
}
|
||||
}
|
@ -596,8 +596,6 @@ namespace osu.Game.Rulesets.UI
|
||||
/// Invoked when the user requests to pause while the resume overlay is active.
|
||||
/// </summary>
|
||||
public abstract void CancelResume();
|
||||
|
||||
public virtual AnalysisContainer CreateAnalysisContainer(Replay replay) => null;
|
||||
}
|
||||
|
||||
public class BeatmapInvalidForRulesetException : ArgumentException
|
||||
|
@ -291,12 +291,6 @@ namespace osu.Game.Rulesets.UI
|
||||
/// </summary>
|
||||
protected virtual HitObjectContainer CreateHitObjectContainer() => new HitObjectContainer();
|
||||
|
||||
/// <summary>
|
||||
/// Adds an analysis container to internal children for replays.
|
||||
/// </summary>
|
||||
/// <param name="analysisContainer"></param>
|
||||
public virtual void AddAnalysisContainer(AnalysisContainer analysisContainer) => AddInternal(analysisContainer);
|
||||
|
||||
#region Pooling support
|
||||
|
||||
private readonly Dictionary<Type, IDrawablePool> pools = new Dictionary<Type, IDrawablePool>();
|
||||
|
@ -1,21 +0,0 @@
|
||||
// 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 osu.Game.Configuration;
|
||||
using osu.Game.Rulesets;
|
||||
|
||||
namespace osu.Game.Screens.Play.PlayerSettings
|
||||
{
|
||||
public partial class AnalysisSettings : PlayerSettingsGroup
|
||||
{
|
||||
protected Ruleset Ruleset;
|
||||
|
||||
public AnalysisSettings(Ruleset ruleset)
|
||||
: base("Analysis Settings")
|
||||
{
|
||||
Ruleset = ruleset;
|
||||
|
||||
AddRange(this.CreateSettingsControls());
|
||||
}
|
||||
}
|
||||
}
|
@ -71,14 +71,6 @@ namespace osu.Game.Screens.Play
|
||||
playbackSettings.UserPlaybackRate.BindTo(master.UserPlaybackRate);
|
||||
|
||||
HUDOverlay.PlayerSettingsOverlay.AddAtStart(playbackSettings);
|
||||
|
||||
var analysisContainer = DrawableRuleset.CreateAnalysisContainer(GameplayState.Score.Replay);
|
||||
|
||||
if (analysisContainer != null)
|
||||
{
|
||||
HUDOverlay.PlayerSettingsOverlay.AddAtStart(analysisContainer.AnalysisSettings);
|
||||
DrawableRuleset.Playfield.AddAnalysisContainer(analysisContainer);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void PrepareReplay()
|
||||
|
Loading…
Reference in New Issue
Block a user