From 02281d8a2a989c0b31e553ed096b76a9142af3fb Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Fri, 10 Mar 2017 15:08:53 +0900 Subject: [PATCH 1/2] Make HitRenderer not have a publicly-settable Beatmap, replace AllObjectsJudged for performance. --- .../Tests/TestCaseGamefield.cs | 18 ++-- osu.Game.Modes.Catch/CatchRuleset.cs | 9 +- osu.Game.Modes.Catch/UI/CatchHitRenderer.cs | 6 ++ osu.Game.Modes.Mania/ManiaRuleset.cs | 9 +- osu.Game.Modes.Mania/UI/ManiaHitRenderer.cs | 4 +- osu.Game.Modes.Osu/OsuRuleset.cs | 9 +- osu.Game.Modes.Osu/UI/OsuHitRenderer.cs | 6 ++ osu.Game.Modes.Taiko/TaikoRuleset.cs | 5 +- osu.Game.Modes.Taiko/UI/TaikoHitRenderer.cs | 6 ++ osu.Game/Modes/UI/HitRenderer.cs | 90 +++++++++++-------- 10 files changed, 91 insertions(+), 71 deletions(-) diff --git a/osu.Desktop.VisualTests/Tests/TestCaseGamefield.cs b/osu.Desktop.VisualTests/Tests/TestCaseGamefield.cs index 79616d777f..ede430478e 100644 --- a/osu.Desktop.VisualTests/Tests/TestCaseGamefield.cs +++ b/osu.Desktop.VisualTests/Tests/TestCaseGamefield.cs @@ -1,11 +1,11 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System.Collections.Generic; -using osu.Framework.Screens.Testing; +using OpenTK; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.MathUtils; +using osu.Framework.Screens.Testing; using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Modes.Catch.UI; @@ -14,7 +14,7 @@ using osu.Game.Modes.Objects; using osu.Game.Modes.Osu.Objects; using osu.Game.Modes.Osu.UI; using osu.Game.Modes.Taiko.UI; -using OpenTK; +using System.Collections.Generic; namespace osu.Desktop.VisualTests.Tests { @@ -55,30 +55,26 @@ namespace osu.Desktop.VisualTests.Tests Clock = new FramedClock(), Children = new Drawable[] { - new OsuHitRenderer + new OsuHitRenderer(beatmap) { - Beatmap = beatmap, Scale = new Vector2(0.5f), Anchor = Anchor.TopLeft, Origin = Anchor.TopLeft }, - new TaikoHitRenderer + new TaikoHitRenderer(beatmap) { - Beatmap = beatmap, Scale = new Vector2(0.5f), Anchor = Anchor.TopRight, Origin = Anchor.TopRight }, - new CatchHitRenderer + new CatchHitRenderer(beatmap) { - Beatmap = beatmap, Scale = new Vector2(0.5f), Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft }, - new ManiaHitRenderer + new ManiaHitRenderer(beatmap) { - Beatmap = beatmap, Scale = new Vector2(0.5f), Anchor = Anchor.BottomRight, Origin = Anchor.BottomRight diff --git a/osu.Game.Modes.Catch/CatchRuleset.cs b/osu.Game.Modes.Catch/CatchRuleset.cs index 155d9e9a1e..f397bd1248 100644 --- a/osu.Game.Modes.Catch/CatchRuleset.cs +++ b/osu.Game.Modes.Catch/CatchRuleset.cs @@ -1,13 +1,13 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System.Collections.Generic; +using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Modes.Catch.UI; using osu.Game.Modes.Objects; using osu.Game.Modes.Osu.UI; using osu.Game.Modes.UI; -using osu.Game.Beatmaps; +using System.Collections.Generic; namespace osu.Game.Modes.Catch { @@ -15,10 +15,7 @@ namespace osu.Game.Modes.Catch { public override ScoreOverlay CreateScoreOverlay() => new OsuScoreOverlay(); - public override HitRenderer CreateHitRendererWith(Beatmap beatmap) => new CatchHitRenderer - { - Beatmap = beatmap, - }; + public override HitRenderer CreateHitRendererWith(Beatmap beatmap) => new CatchHitRenderer(beatmap); public override IEnumerable GetModsFor(ModType type) { diff --git a/osu.Game.Modes.Catch/UI/CatchHitRenderer.cs b/osu.Game.Modes.Catch/UI/CatchHitRenderer.cs index dd61fdd453..ed0c8b4747 100644 --- a/osu.Game.Modes.Catch/UI/CatchHitRenderer.cs +++ b/osu.Game.Modes.Catch/UI/CatchHitRenderer.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Game.Beatmaps; using osu.Game.Modes.Catch.Objects; using osu.Game.Modes.Objects; using osu.Game.Modes.Objects.Drawables; @@ -10,6 +11,11 @@ namespace osu.Game.Modes.Catch.UI { public class CatchHitRenderer : HitRenderer { + public CatchHitRenderer(Beatmap beatmap) + : base(beatmap) + { + } + protected override HitObjectConverter Converter => new CatchConverter(); protected override Playfield CreatePlayfield() => new CatchPlayfield(); diff --git a/osu.Game.Modes.Mania/ManiaRuleset.cs b/osu.Game.Modes.Mania/ManiaRuleset.cs index 5487606b26..95b2cd6d6b 100644 --- a/osu.Game.Modes.Mania/ManiaRuleset.cs +++ b/osu.Game.Modes.Mania/ManiaRuleset.cs @@ -1,13 +1,13 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System.Collections.Generic; +using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Modes.Mania.UI; using osu.Game.Modes.Objects; using osu.Game.Modes.Osu.UI; using osu.Game.Modes.UI; -using osu.Game.Beatmaps; +using System.Collections.Generic; namespace osu.Game.Modes.Mania { @@ -15,10 +15,7 @@ namespace osu.Game.Modes.Mania { public override ScoreOverlay CreateScoreOverlay() => new OsuScoreOverlay(); - public override HitRenderer CreateHitRendererWith(Beatmap beatmap) => new ManiaHitRenderer - { - Beatmap = beatmap, - }; + public override HitRenderer CreateHitRendererWith(Beatmap beatmap) => new ManiaHitRenderer(beatmap); public override IEnumerable GetModsFor(ModType type) { diff --git a/osu.Game.Modes.Mania/UI/ManiaHitRenderer.cs b/osu.Game.Modes.Mania/UI/ManiaHitRenderer.cs index 31bc4fffe4..82dd2f2eeb 100644 --- a/osu.Game.Modes.Mania/UI/ManiaHitRenderer.cs +++ b/osu.Game.Modes.Mania/UI/ManiaHitRenderer.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Game.Beatmaps; using osu.Game.Modes.Mania.Objects; using osu.Game.Modes.Objects; using osu.Game.Modes.Objects.Drawables; @@ -12,7 +13,8 @@ namespace osu.Game.Modes.Mania.UI { private readonly int columns; - public ManiaHitRenderer(int columns = 5) + public ManiaHitRenderer(Beatmap beatmap, int columns = 5) + : base(beatmap) { this.columns = columns; } diff --git a/osu.Game.Modes.Osu/OsuRuleset.cs b/osu.Game.Modes.Osu/OsuRuleset.cs index 3cfce84448..243ce64d9e 100644 --- a/osu.Game.Modes.Osu/OsuRuleset.cs +++ b/osu.Game.Modes.Osu/OsuRuleset.cs @@ -1,14 +1,14 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System.Collections.Generic; -using System.Linq; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Modes.Objects; using osu.Game.Modes.Osu.Objects; using osu.Game.Modes.Osu.UI; using osu.Game.Modes.UI; +using System.Collections.Generic; +using System.Linq; namespace osu.Game.Modes.Osu { @@ -16,10 +16,7 @@ namespace osu.Game.Modes.Osu { public override ScoreOverlay CreateScoreOverlay() => new OsuScoreOverlay(); - public override HitRenderer CreateHitRendererWith(Beatmap beatmap) => new OsuHitRenderer - { - Beatmap = beatmap, - }; + public override HitRenderer CreateHitRendererWith(Beatmap beatmap) => new OsuHitRenderer(beatmap); public override IEnumerable GetBeatmapStatistics(WorkingBeatmap beatmap) => new[] { diff --git a/osu.Game.Modes.Osu/UI/OsuHitRenderer.cs b/osu.Game.Modes.Osu/UI/OsuHitRenderer.cs index 4801862a91..dab46aed8f 100644 --- a/osu.Game.Modes.Osu/UI/OsuHitRenderer.cs +++ b/osu.Game.Modes.Osu/UI/OsuHitRenderer.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Game.Beatmaps; using osu.Game.Modes.Objects; using osu.Game.Modes.Objects.Drawables; using osu.Game.Modes.Osu.Objects; @@ -11,6 +12,11 @@ namespace osu.Game.Modes.Osu.UI { public class OsuHitRenderer : HitRenderer { + public OsuHitRenderer(Beatmap beatmap) + : base(beatmap) + { + } + protected override HitObjectConverter Converter => new OsuHitObjectConverter(); protected override Playfield CreatePlayfield() => new OsuPlayfield(); diff --git a/osu.Game.Modes.Taiko/TaikoRuleset.cs b/osu.Game.Modes.Taiko/TaikoRuleset.cs index be23045f4d..f6fbea6198 100644 --- a/osu.Game.Modes.Taiko/TaikoRuleset.cs +++ b/osu.Game.Modes.Taiko/TaikoRuleset.cs @@ -15,10 +15,7 @@ namespace osu.Game.Modes.Taiko { public override ScoreOverlay CreateScoreOverlay() => new OsuScoreOverlay(); - public override HitRenderer CreateHitRendererWith(Beatmap beatmap) => new TaikoHitRenderer - { - Beatmap = beatmap, - }; + public override HitRenderer CreateHitRendererWith(Beatmap beatmap) => new TaikoHitRenderer(beatmap); public override IEnumerable GetModsFor(ModType type) { diff --git a/osu.Game.Modes.Taiko/UI/TaikoHitRenderer.cs b/osu.Game.Modes.Taiko/UI/TaikoHitRenderer.cs index 1b9bb682f1..e29e13823d 100644 --- a/osu.Game.Modes.Taiko/UI/TaikoHitRenderer.cs +++ b/osu.Game.Modes.Taiko/UI/TaikoHitRenderer.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Game.Beatmaps; using osu.Game.Modes.Objects; using osu.Game.Modes.Objects.Drawables; using osu.Game.Modes.Taiko.Objects; @@ -10,6 +11,11 @@ namespace osu.Game.Modes.Taiko.UI { public class TaikoHitRenderer : HitRenderer { + public TaikoHitRenderer(Beatmap beatmap) + : base(beatmap) + { + } + protected override HitObjectConverter Converter => new TaikoConverter(); protected override Playfield CreatePlayfield() => new TaikoPlayfield(); diff --git a/osu.Game/Modes/UI/HitRenderer.cs b/osu.Game/Modes/UI/HitRenderer.cs index fb28dd6c47..360551c89f 100644 --- a/osu.Game/Modes/UI/HitRenderer.cs +++ b/osu.Game/Modes/UI/HitRenderer.cs @@ -1,24 +1,22 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System; -using System.Collections.Generic; -using System.Linq; +using OpenTK; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Game.Beatmaps; using osu.Game.Modes.Objects; using osu.Game.Modes.Objects.Drawables; -using osu.Game.Beatmaps; using osu.Game.Screens.Play; -using OpenTK; +using System; +using System.Collections.Generic; namespace osu.Game.Modes.UI { public abstract class HitRenderer : Container { public event Action OnJudgement; - public event Action OnAllJudged; internal readonly PlayerInputManager InputManager = new PlayerInputManager(); @@ -28,12 +26,39 @@ namespace osu.Game.Modes.UI /// public abstract Func MapPlayfieldToScreenSpace { get; } - public abstract bool AllObjectsJudged { get; } + /// + /// The number of Judgements required to be triggered + /// before the game enters post-play routines. + /// + protected abstract int JudgementCount { get; } + + /// + /// The beatmap this HitRenderer is initialized with. + /// + protected readonly Beatmap Beatmap; + + private int maxJudgements; + private int countJudgements; + + protected HitRenderer(Beatmap beatmap) + { + Beatmap = beatmap; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + maxJudgements = JudgementCount; + } protected void TriggerOnJudgement(JudgementInfo j) { + countJudgements++; + OnJudgement?.Invoke(j); - if (AllObjectsJudged) + + if (countJudgements == maxJudgements) OnAllJudged?.Invoke(); } } @@ -41,33 +66,23 @@ namespace osu.Game.Modes.UI public abstract class HitRenderer : HitRenderer where TObject : HitObject { - private List objects; + public override Func MapPlayfieldToScreenSpace => Playfield.ScaledContent.ToScreenSpace; + public IEnumerable DrawableObjects => Playfield.HitObjects.Children; + + protected abstract HitObjectConverter Converter { get; } + protected virtual List Convert(Beatmap beatmap) => Converter.Convert(beatmap); + + protected override Container Content => content; + + private int judgementCount; + protected override int JudgementCount => judgementCount; protected Playfield Playfield; - public override Func MapPlayfieldToScreenSpace => Playfield.ScaledContent.ToScreenSpace; + private Container content; - public override bool AllObjectsJudged => Playfield.HitObjects.Children.First()?.Judgement.Result != null; //reverse depth sort means First() instead of Last(). - - public IEnumerable DrawableObjects => Playfield.HitObjects.Children; - - public Beatmap Beatmap - { - set - { - objects = Convert(value); - if (IsLoaded) - loadObjects(); - } - } - - protected abstract Playfield CreatePlayfield(); - - protected abstract HitObjectConverter Converter { get; } - - protected virtual List Convert(Beatmap beatmap) => Converter.Convert(beatmap); - - protected HitRenderer() + protected HitRenderer(Beatmap beatmap) + : base(beatmap) { RelativeSizeAxes = Axes.Both; @@ -83,9 +98,6 @@ namespace osu.Game.Modes.UI AddInternal(InputManager); } - protected override Container Content => content; - - private Container content; [BackgroundDependencyLoader] private void load() @@ -95,22 +107,26 @@ namespace osu.Game.Modes.UI private void loadObjects() { - if (objects == null) return; - foreach (TObject h in objects) + foreach (TObject h in Convert(Beatmap)) { DrawableHitObject drawableObject = GetVisualRepresentation(h); - if (drawableObject == null) continue; + if (drawableObject == null) + continue; drawableObject.OnJudgement += onJudgement; Playfield.Add(drawableObject); + + judgementCount++; } + Playfield.PostProcess(); } private void onJudgement(DrawableHitObject o, JudgementInfo j) => TriggerOnJudgement(j); protected abstract DrawableHitObject GetVisualRepresentation(TObject h); + protected abstract Playfield CreatePlayfield(); } } From 74db255c78b7445bb70ac1f7aea51716922f2ff6 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Sun, 12 Mar 2017 01:19:51 +0900 Subject: [PATCH 2/2] Move back to using an abstract method to determine if all objects have been judged. Because sliderticks provide judgements even though they are added as nested hitobjects, the count method would not work to determine if all hitobjects have been judged. This needs a little bit more thought put in... --- osu.Game/Modes/UI/HitRenderer.cs | 26 +++++--------------------- 1 file changed, 5 insertions(+), 21 deletions(-) diff --git a/osu.Game/Modes/UI/HitRenderer.cs b/osu.Game/Modes/UI/HitRenderer.cs index 360551c89f..6b574552de 100644 --- a/osu.Game/Modes/UI/HitRenderer.cs +++ b/osu.Game/Modes/UI/HitRenderer.cs @@ -11,6 +11,7 @@ using osu.Game.Modes.Objects.Drawables; using osu.Game.Screens.Play; using System; using System.Collections.Generic; +using System.Linq; namespace osu.Game.Modes.UI { @@ -27,38 +28,25 @@ namespace osu.Game.Modes.UI public abstract Func MapPlayfieldToScreenSpace { get; } /// - /// The number of Judgements required to be triggered - /// before the game enters post-play routines. + /// Whether all the HitObjects have been judged. /// - protected abstract int JudgementCount { get; } + protected abstract bool AllObjectsJudged { get; } /// /// The beatmap this HitRenderer is initialized with. /// protected readonly Beatmap Beatmap; - private int maxJudgements; - private int countJudgements; - protected HitRenderer(Beatmap beatmap) { Beatmap = beatmap; } - protected override void LoadComplete() - { - base.LoadComplete(); - - maxJudgements = JudgementCount; - } - protected void TriggerOnJudgement(JudgementInfo j) { - countJudgements++; - OnJudgement?.Invoke(j); - if (countJudgements == maxJudgements) + if (AllObjectsJudged) OnAllJudged?.Invoke(); } } @@ -73,9 +61,7 @@ namespace osu.Game.Modes.UI protected virtual List Convert(Beatmap beatmap) => Converter.Convert(beatmap); protected override Container Content => content; - - private int judgementCount; - protected override int JudgementCount => judgementCount; + protected override bool AllObjectsJudged => Playfield.HitObjects.Children.All(h => h.Judgement.Result.HasValue); protected Playfield Playfield; @@ -117,8 +103,6 @@ namespace osu.Game.Modes.UI drawableObject.OnJudgement += onJudgement; Playfield.Add(drawableObject); - - judgementCount++; } Playfield.PostProcess();