From 7f0f143a1bb3bec08df923313a882b299065ae84 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 6 Nov 2018 12:01:54 +0900 Subject: [PATCH] Move IScrollAlgorithm to ScrollingRulesetContainer + use DI --- osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs | 2 - .../UI/CatchRulesetContainer.cs | 3 + osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 3 - .../UI/TaikoRulesetContainer.cs | 3 + .../Visual/TestCaseScrollingHitObjects.cs | 67 +++++++++++++++++-- .../Scrolling/ScrollingHitObjectContainer.cs | 34 ++-------- .../UI/Scrolling/ScrollingPlayfield.cs | 5 +- .../UI/Scrolling/ScrollingRulesetContainer.cs | 36 ++++++---- 8 files changed, 97 insertions(+), 56 deletions(-) diff --git a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs index 08b7684677..167e7b4976 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs @@ -5,7 +5,6 @@ using System; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; -using osu.Game.Configuration; using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.Objects.Drawable; using osu.Game.Rulesets.Judgements; @@ -23,7 +22,6 @@ namespace osu.Game.Rulesets.Catch.UI protected override bool UserScrollSpeedAdjustment => false; - protected override ScrollVisualisationMethod VisualisationMethod => ScrollVisualisationMethod.Constant; public CatchPlayfield(BeatmapDifficulty difficulty, Func> getVisualRepresentation) { diff --git a/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs b/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs index 94233bc9f0..60b2707df6 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs @@ -3,6 +3,7 @@ using osu.Framework.Input; using osu.Game.Beatmaps; +using osu.Game.Configuration; using osu.Game.Input.Handlers; using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.Objects.Drawable; @@ -18,6 +19,8 @@ namespace osu.Game.Rulesets.Catch.UI { public class CatchRulesetContainer : ScrollingRulesetContainer { + protected override ScrollAlgorithm ScrollAlgorithm => ScrollAlgorithm.Constant; + public CatchRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap) : base(ruleset, beatmap) { diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index 824c1f817a..4c69576089 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -8,7 +8,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps.ControlPoints; -using osu.Game.Configuration; using osu.Game.Graphics; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Judgements; @@ -41,8 +40,6 @@ namespace osu.Game.Rulesets.Taiko.UI protected override bool UserScrollSpeedAdjustment => false; - protected override ScrollVisualisationMethod VisualisationMethod => ScrollVisualisationMethod.Overlapping; - private readonly Container hitExplosionContainer; private readonly Container kiaiExplosionContainer; private readonly JudgementContainer judgementContainer; diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs b/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs index c94ced3390..bd31d49a67 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs @@ -14,6 +14,7 @@ using osu.Game.Rulesets.UI; using osu.Game.Rulesets.Taiko.Replays; using System.Linq; using osu.Framework.Input; +using osu.Game.Configuration; using osu.Game.Input.Handlers; using osu.Game.Rulesets.UI.Scrolling; @@ -21,6 +22,8 @@ namespace osu.Game.Rulesets.Taiko.UI { public class TaikoRulesetContainer : ScrollingRulesetContainer { + protected override ScrollAlgorithm ScrollAlgorithm => ScrollAlgorithm.Overlapping; + public TaikoRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap) : base(ruleset, beatmap) { diff --git a/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs b/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs index eb322df185..ecee153163 100644 --- a/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs +++ b/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs @@ -4,16 +4,20 @@ using System; using System.Collections.Generic; using NUnit.Framework; +using osu.Framework.Allocation; using osu.Framework.Extensions.IEnumerableExtensions; using OpenTK; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Framework.Lists; +using osu.Game.Configuration; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Timing; using osu.Game.Rulesets.UI; using osu.Game.Rulesets.UI.Scrolling; +using osu.Game.Rulesets.UI.Scrolling.Algorithms; namespace osu.Game.Tests.Visual { @@ -44,6 +48,10 @@ namespace osu.Game.Tests.Visual } }); + AddStep("Constant scroll", () => setScrollAlgorithm(ScrollAlgorithm.Constant)); + AddStep("Overlapping scroll", () => setScrollAlgorithm(ScrollAlgorithm.Overlapping)); + AddStep("Sequential scroll", () => setScrollAlgorithm(ScrollAlgorithm.Sequential)); + AddSliderStep("Time range", 100, 10000, 5000, v => playfields.ForEach(p => p.VisibleTimeRange.Value = v)); AddStep("Add control point", () => addControlPoint(Time.Current + 5000)); } @@ -52,7 +60,7 @@ namespace osu.Game.Tests.Visual { base.LoadComplete(); - playfields.ForEach(p => p.HitObjects.AddControlPoint(new MultiplierControlPoint(0))); + playfields.ForEach(p => p.ControlPoints.Add(new MultiplierControlPoint(0))); for (int i = 0; i <= 5000; i += 1000) addHitObject(Time.Current + i); @@ -75,9 +83,9 @@ namespace osu.Game.Tests.Visual { playfields.ForEach(p => { - p.HitObjects.AddControlPoint(new MultiplierControlPoint(time) { DifficultyPoint = { SpeedMultiplier = 3 } }); - p.HitObjects.AddControlPoint(new MultiplierControlPoint(time + 2000) { DifficultyPoint = { SpeedMultiplier = 2 } }); - p.HitObjects.AddControlPoint(new MultiplierControlPoint(time + 3000) { DifficultyPoint = { SpeedMultiplier = 1 } }); + p.ControlPoints.Add(new MultiplierControlPoint(time) { DifficultyPoint = { SpeedMultiplier = 3 } }); + p.ControlPoints.Add(new MultiplierControlPoint(time + 2000) { DifficultyPoint = { SpeedMultiplier = 2 } }); + p.ControlPoints.Add(new MultiplierControlPoint(time + 3000) { DifficultyPoint = { SpeedMultiplier = 1 } }); TestDrawableControlPoint createDrawablePoint(double t) { @@ -111,11 +119,19 @@ namespace osu.Game.Tests.Visual } } + private void setScrollAlgorithm(ScrollAlgorithm algorithm) => playfields.ForEach(p => p.ScrollAlgorithm = algorithm); private class TestPlayfield : ScrollingPlayfield { public new ScrollingDirection Direction => base.Direction; + public SortedList ControlPoints => algorithm.ControlPoints; + + public ScrollAlgorithm ScrollAlgorithm { set => algorithm.Algorithm = value; } + + [Cached(Type = typeof(IScrollAlgorithm))] + private readonly TestScrollAlgorithm algorithm = new TestScrollAlgorithm(); + public TestPlayfield(ScrollingDirection direction) { base.Direction.Value = direction; @@ -139,6 +155,49 @@ namespace osu.Game.Tests.Visual } } + private class TestScrollAlgorithm : IScrollAlgorithm + { + public readonly SortedList ControlPoints = new SortedList(); + + private IScrollAlgorithm implementation; + + public TestScrollAlgorithm() + { + Algorithm = ScrollAlgorithm.Constant; + } + + public ScrollAlgorithm Algorithm + { + set + { + switch (value) + { + case ScrollAlgorithm.Constant: + implementation = new ConstantScrollAlgorithm(); + break; + case ScrollAlgorithm.Overlapping: + implementation = new OverlappingScrollAlgorithm(ControlPoints); + break; + case ScrollAlgorithm.Sequential: + implementation = new SequentialScrollAlgorithm(ControlPoints); + break; + } + } + } + + public double GetDisplayStartTime(double time, double timeRange) + => implementation.GetDisplayStartTime(time, timeRange); + + public float GetLength(double startTime, double endTime, double timeRange, float scrollLength) + => implementation.GetLength(startTime, endTime, timeRange, scrollLength); + + public float PositionAt(double time, double currentTime, double timeRange, float scrollLength) + => implementation.PositionAt(time, currentTime, timeRange, scrollLength); + + public void Reset() + => implementation.Reset(); + } + private class TestDrawableControlPoint : DrawableHitObject { public TestDrawableControlPoint(ScrollingDirection direction, double time) diff --git a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs index 489604afc9..6bcba211da 100644 --- a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs +++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs @@ -1,11 +1,11 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Framework.Allocation; using osu.Framework.Caching; using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Lists; -using osu.Game.Configuration; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Timing; @@ -31,29 +31,17 @@ namespace osu.Game.Rulesets.UI.Scrolling public readonly Bindable Direction = new Bindable(); - private readonly IScrollAlgorithm algorithm; + [Resolved] + private IScrollAlgorithm algorithm { get; set; } private Cached initialStateCache = new Cached(); - public ScrollingHitObjectContainer(ScrollVisualisationMethod visualisationMethod) + public ScrollingHitObjectContainer() { RelativeSizeAxes = Axes.Both; TimeRange.ValueChanged += _ => initialStateCache.Invalidate(); Direction.ValueChanged += _ => initialStateCache.Invalidate(); - - switch (visualisationMethod) - { - case ScrollVisualisationMethod.Sequential: - algorithm = new SequentialScrollAlgorithm(ControlPoints); - break; - case ScrollVisualisationMethod.Overlapping: - algorithm = new OverlappingScrollAlgorithm(ControlPoints); - break; - case ScrollVisualisationMethod.Constant: - algorithm = new ConstantScrollAlgorithm(); - break; - } } public override void Add(DrawableHitObject hitObject) @@ -70,20 +58,6 @@ namespace osu.Game.Rulesets.UI.Scrolling return result; } - public void AddControlPoint(MultiplierControlPoint controlPoint) - { - ControlPoints.Add(controlPoint); - initialStateCache.Invalidate(); - } - - public bool RemoveControlPoint(MultiplierControlPoint controlPoint) - { - var result = ControlPoints.Remove(controlPoint); - if (result) - initialStateCache.Invalidate(); - return result; - } - public override bool Invalidate(Invalidation invalidation = Invalidation.All, Drawable source = null, bool shallPropagate = true) { if ((invalidation & (Invalidation.RequiredParentSizeToFit | Invalidation.DrawInfo)) > 0) diff --git a/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs index 5e2704c9ee..b555b6616a 100644 --- a/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs +++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs @@ -5,7 +5,6 @@ using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Input.Bindings; -using osu.Game.Configuration; using osu.Game.Input.Bindings; using osu.Game.Rulesets.Objects.Drawables; @@ -63,8 +62,6 @@ namespace osu.Game.Rulesets.UI.Scrolling /// protected readonly Bindable Direction = new Bindable(); - protected virtual ScrollVisualisationMethod VisualisationMethod => ScrollVisualisationMethod.Sequential; - [BackgroundDependencyLoader] private void load() { @@ -93,7 +90,7 @@ namespace osu.Game.Rulesets.UI.Scrolling protected sealed override HitObjectContainer CreateHitObjectContainer() { - var container = new ScrollingHitObjectContainer(VisualisationMethod); + var container = new ScrollingHitObjectContainer(); container.Direction.BindTo(Direction); return container; } diff --git a/osu.Game/Rulesets/UI/Scrolling/ScrollingRulesetContainer.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingRulesetContainer.cs index 41cdd6c06f..2f6ef730b3 100644 --- a/osu.Game/Rulesets/UI/Scrolling/ScrollingRulesetContainer.cs +++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingRulesetContainer.cs @@ -4,13 +4,14 @@ using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; -using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Lists; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Configuration; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Timing; +using osu.Game.Rulesets.UI.Scrolling.Algorithms; namespace osu.Game.Rulesets.UI.Scrolling { @@ -27,11 +28,28 @@ namespace osu.Game.Rulesets.UI.Scrolling /// inside this . /// /// - protected readonly SortedList DefaultControlPoints = new SortedList(Comparer.Default); + private readonly SortedList controlPoints = new SortedList(Comparer.Default); + + protected virtual ScrollAlgorithm ScrollAlgorithm => ScrollAlgorithm.Sequential; + + [Cached(Type = typeof(IScrollAlgorithm))] + private readonly IScrollAlgorithm algorithm; protected ScrollingRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap) : base(ruleset, beatmap) { + switch (ScrollAlgorithm) + { + case ScrollAlgorithm.Sequential: + algorithm = new SequentialScrollAlgorithm(controlPoints); + break; + case ScrollAlgorithm.Overlapping: + algorithm = new OverlappingScrollAlgorithm(controlPoints); + break; + case ScrollAlgorithm.Constant: + algorithm = new ConstantScrollAlgorithm(); + break; + } } [BackgroundDependencyLoader] @@ -75,19 +93,11 @@ namespace osu.Game.Rulesets.UI.Scrolling // Collapse sections with the same start time .GroupBy(s => s.StartTime).Select(g => g.Last()).OrderBy(s => s.StartTime); - DefaultControlPoints.AddRange(timingChanges); + controlPoints.AddRange(timingChanges); // If we have no control points, add a default one - if (DefaultControlPoints.Count == 0) - DefaultControlPoints.Add(new MultiplierControlPoint { Velocity = Beatmap.BeatmapInfo.BaseDifficulty.SliderMultiplier }); - - DefaultControlPoints.ForEach(c => applySpeedAdjustment(c, Playfield)); - } - - private void applySpeedAdjustment(MultiplierControlPoint controlPoint, ScrollingPlayfield playfield) - { - playfield.HitObjects.AddControlPoint(controlPoint); - playfield.NestedPlayfields?.OfType().ForEach(p => applySpeedAdjustment(controlPoint, p)); + if (controlPoints.Count == 0) + controlPoints.Add(new MultiplierControlPoint { Velocity = Beatmap.BeatmapInfo.BaseDifficulty.SliderMultiplier }); } } }