From 214154c5124a67670337cfed99b688420b81ac38 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Thu, 21 Dec 2017 20:23:10 +0100 Subject: [PATCH 01/49] hide unnecessary lines on empty BeatmapInfoWedge adding back deleted line ooops meh --- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 34 +++++++++++---------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 3ef6ceeaeb..d18aebe43b 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -95,7 +95,7 @@ namespace osu.Game.Screens.Select List labels = new List(); - if (beatmap != null) + if (beatmap != null && !(working is DummyWorkingBeatmap)) { HitObject lastObject = beatmap.HitObjects.LastOrDefault(); double endTime = (lastObject as IHasEndTime)?.EndTime ?? lastObject?.StartTime ?? 0; @@ -200,21 +200,7 @@ namespace osu.Game.Screens.Select Margin = new MarginPadding { Top = 10 }, Direction = FillDirection.Horizontal, AutoSizeAxes = Axes.Both, - Children = new[] - { - new OsuSpriteText - { - Font = @"Exo2.0-Medium", - Text = "mapped by ", - TextSize = 15, - }, - new OsuSpriteText - { - Font = @"Exo2.0-Bold", - Text = metadata.Author.Username, - TextSize = 15, - }, - } + Children = working is DummyWorkingBeatmap ? Array.Empty() : getMapper(metadata) }, new FillFlowContainer { @@ -228,6 +214,22 @@ namespace osu.Game.Screens.Select }; } + private OsuSpriteText[] getMapper(BeatmapMetadata metadata) => new[] + { + new OsuSpriteText + { + Font = @"Exo2.0-Medium", + Text = "mapped by ", + TextSize = 15, + }, + new OsuSpriteText + { + Font = @"Exo2.0-Bold", + Text = metadata.Author.Username, + TextSize = 15, + } + }; + private string getBPMRange(Beatmap beatmap) { double bpmMax = beatmap.ControlPointInfo.BPMMaximum; From 07f55a2a606a7d8a12973b637aa7e875c692b105 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Fri, 22 Dec 2017 10:18:25 +0100 Subject: [PATCH 02/49] remove references to DummyWorkingBeatmap determine content by data that is present instead --- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 106 +++++++++++--------- 1 file changed, 60 insertions(+), 46 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index d18aebe43b..9b9a009ac0 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -89,34 +89,8 @@ namespace osu.Game.Screens.Select [BackgroundDependencyLoader] private void load() { - BeatmapInfo beatmapInfo = working.BeatmapInfo; - BeatmapMetadata metadata = beatmapInfo.Metadata ?? working.BeatmapSetInfo?.Metadata ?? new BeatmapMetadata(); - Beatmap beatmap = working.Beatmap; - - List labels = new List(); - - if (beatmap != null && !(working is DummyWorkingBeatmap)) - { - HitObject lastObject = beatmap.HitObjects.LastOrDefault(); - double endTime = (lastObject as IHasEndTime)?.EndTime ?? lastObject?.StartTime ?? 0; - - labels.Add(new InfoLabel(new BeatmapStatistic - { - Name = "Length", - Icon = FontAwesome.fa_clock_o, - Content = beatmap.HitObjects.Count == 0 ? "-" : TimeSpan.FromMilliseconds(endTime - beatmap.HitObjects.First().StartTime).ToString(@"m\:ss"), - })); - - labels.Add(new InfoLabel(new BeatmapStatistic - { - Name = "BPM", - Icon = FontAwesome.fa_circle, - Content = getBPMRange(beatmap), - })); - - //get statistics from the current ruleset. - labels.AddRange(beatmapInfo.Ruleset.CreateInstance().GetBeatmapStatistics(working).Select(s => new InfoLabel(s))); - } + var beatmapInfo = working.BeatmapInfo; + var metadata = beatmapInfo.Metadata ?? working.BeatmapSetInfo?.Metadata ?? new BeatmapMetadata(); PixelSnapping = true; CacheDrawnFrameBuffer = true; @@ -186,7 +160,7 @@ namespace osu.Game.Screens.Select new OsuSpriteText { Font = @"Exo2.0-MediumItalic", - Text = !string.IsNullOrEmpty(metadata.Source) ? metadata.Source + " — " + metadata.Title : metadata.Title, + Text = string.IsNullOrEmpty(metadata.Source) ? metadata.Title : metadata.Source + " — " + metadata.Title, TextSize = 28, }, new OsuSpriteText @@ -200,46 +174,86 @@ namespace osu.Game.Screens.Select Margin = new MarginPadding { Top = 10 }, Direction = FillDirection.Horizontal, AutoSizeAxes = Axes.Both, - Children = working is DummyWorkingBeatmap ? Array.Empty() : getMapper(metadata) + Children = getMapper(metadata) }, new FillFlowContainer { Margin = new MarginPadding { Top = 20 }, Spacing = new Vector2(20, 0), AutoSizeAxes = Axes.Both, - Children = labels - }, + Children = getInfoLabels() + } } - }, + } }; } - private OsuSpriteText[] getMapper(BeatmapMetadata metadata) => new[] + private InfoLabel[] getInfoLabels() { - new OsuSpriteText + var beatmap = working.Beatmap; + var info = working.BeatmapInfo; + + List labels = new List(); + + if (beatmap?.HitObjects?.Count > 0) { - Font = @"Exo2.0-Medium", - Text = "mapped by ", - TextSize = 15, - }, - new OsuSpriteText - { - Font = @"Exo2.0-Bold", - Text = metadata.Author.Username, - TextSize = 15, + HitObject lastObject = beatmap.HitObjects.LastOrDefault(); + double endTime = (lastObject as IHasEndTime)?.EndTime ?? lastObject?.StartTime ?? 0; + + labels.Add(new InfoLabel(new BeatmapStatistic + { + Name = "Length", + Icon = FontAwesome.fa_clock_o, + Content = beatmap.HitObjects.Count == 0 ? "-" : TimeSpan.FromMilliseconds(endTime - beatmap.HitObjects.First().StartTime).ToString(@"m\:ss"), + })); + + labels.Add(new InfoLabel(new BeatmapStatistic + { + Name = "BPM", + Icon = FontAwesome.fa_circle, + Content = getBPMRange(beatmap), + })); + + //get statistics from the current ruleset. + labels.AddRange(info.Ruleset.CreateInstance().GetBeatmapStatistics(working).Select(s => new InfoLabel(s))); } - }; + + return labels.ToArray(); + } private string getBPMRange(Beatmap beatmap) { double bpmMax = beatmap.ControlPointInfo.BPMMaximum; double bpmMin = beatmap.ControlPointInfo.BPMMinimum; - if (Precision.AlmostEquals(bpmMin, bpmMax)) return $"{bpmMin:0}"; + if (Precision.AlmostEquals(bpmMin, bpmMax)) + return $"{bpmMin:0}"; return $"{bpmMin:0}-{bpmMax:0} (mostly {beatmap.ControlPointInfo.BPMMode:0})"; } + private OsuSpriteText[] getMapper(BeatmapMetadata metadata) + { + if (string.IsNullOrEmpty(metadata.Author?.Username)) + return Array.Empty(); + + return new[] + { + new OsuSpriteText + { + Font = @"Exo2.0-Medium", + Text = "mapped by ", + TextSize = 15, + }, + new OsuSpriteText + { + Font = @"Exo2.0-Bold", + Text = metadata.Author.Username, + TextSize = 15, + } + }; + } + public class InfoLabel : Container, IHasTooltip { public string TooltipText { get; private set; } From ed827d5424fcadfa24e76a13cfbe1100916cfb00 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Fri, 22 Dec 2017 12:33:52 +0100 Subject: [PATCH 03/49] more visual tests for BeatmapInfoWedge also fix Author showing when not wanted --- .../Visual/TestCaseBeatmapInfoWedge.cs | 117 ++++++++++++++---- osu.Game/Beatmaps/DummyWorkingBeatmap.cs | 3 +- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 25 ++-- 3 files changed, 109 insertions(+), 36 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs b/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs index 0168cedc86..353f351a54 100644 --- a/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs +++ b/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs @@ -1,36 +1,48 @@ // 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.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; +using osu.Game.Graphics.Sprites; +using osu.Game.Rulesets; +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Osu; using osu.Game.Screens.Select; +using osu.Game.Tests.Beatmaps; namespace osu.Game.Tests.Visual { public class TestCaseBeatmapInfoWedge : OsuTestCase { - private BeatmapManager beatmaps; - private readonly Random random; - private readonly BeatmapInfoWedge infoWedge; + private TestBeatmapInfoWedge infoWedge; + private readonly List beatmaps = new List(); private readonly Bindable beatmap = new Bindable(); - public TestCaseBeatmapInfoWedge() + [BackgroundDependencyLoader] + private void load(OsuGameBase game, RulesetStore rulesets) { - random = new Random(0123); + beatmap.BindTo(game.Beatmap); - Add(infoWedge = new BeatmapInfoWedge + Add(infoWedge = new TestBeatmapInfoWedge { Size = new Vector2(0.5f, 245), RelativeSizeAxes = Axes.X, Margin = new MarginPadding { Top = 20, - }, + } + }); + + AddStep("hide", () => + { + infoWedge.State = Visibility.Hidden; + Content.FadeOut(100); }); AddStep("show", () => @@ -39,31 +51,88 @@ namespace osu.Game.Tests.Visual infoWedge.State = Visibility.Visible; infoWedge.UpdateBeatmap(beatmap); }); - AddStep("hide", () => + + foreach (var rulesetInfo in rulesets.AvailableRulesets) { - infoWedge.State = Visibility.Hidden; - Content.FadeOut(100); + var ruleset = rulesetInfo.CreateInstance(); + beatmaps.Add(createTestBeatmap(rulesetInfo)); + + var name = rulesetInfo.ShortName; + selectBeatmap(name); + + // TODO: check InfoLabels of other rulesets + switch (ruleset) + { + case OsuRuleset osu: + testOsuBeatmap(osu); + break; + } + } + + testNullBeatmap(); + } + + private void testOsuBeatmap(OsuRuleset ruleset) + { + AddAssert("check version", () => infoWedge.Info.VersionLabel.Text == $"{ruleset.ShortName}Version"); + AddAssert("check title", () => infoWedge.Info.TitleLabel.Text == $"{ruleset.ShortName}Source — {ruleset.ShortName}Title"); + AddAssert("check artist", () => infoWedge.Info.ArtistLabel.Text == $"{ruleset.ShortName}Artist"); + AddAssert("check author", () => infoWedge.Info.MapperContainer.Children.OfType().Any(s => s.Text == $"{ruleset.ShortName}Author")); + // TODO: check InfoLabels + } + + private void testNullBeatmap() + { + selectNullBeatmap(); + AddAssert("check empty version", () => string.IsNullOrEmpty(infoWedge.Info.VersionLabel.Text)); + AddAssert("check default title", () => infoWedge.Info.TitleLabel.Text == beatmap.Default.BeatmapInfo.Metadata.Title); + AddAssert("check default artist", () => infoWedge.Info.ArtistLabel.Text == beatmap.Default.BeatmapInfo.Metadata.Artist); + AddAssert("check empty author", () => !infoWedge.Info.MapperContainer.Children.Any()); + AddAssert("check empty infos", () => !infoWedge.Info.InfoLabelContainer.Children.Any()); + } + + private void selectBeatmap(string name) + { + AddStep($"select {name} beatmap", () => + { + beatmap.Value = new TestWorkingBeatmap(beatmaps.First(b => b.BeatmapInfo.Ruleset.ShortName == name)); + infoWedge.UpdateBeatmap(beatmap); }); - AddStep("random beatmap", randomBeatmap); - AddStep("null beatmap", () => infoWedge.UpdateBeatmap(beatmap.Default)); } - [BackgroundDependencyLoader] - private void load(OsuGameBase game, BeatmapManager beatmaps) + private void selectNullBeatmap() { - this.beatmaps = beatmaps; - beatmap.BindTo(game.Beatmap); + AddStep("select null beatmap", () => + { + beatmap.Value = beatmap.Default; + infoWedge.UpdateBeatmap(beatmap); + }); } - private void randomBeatmap() + private Beatmap createTestBeatmap(RulesetInfo ruleset) { - var sets = beatmaps.GetAllUsableBeatmapSets(); - if (sets.Count == 0) - return; + return new Beatmap + { + BeatmapInfo = new BeatmapInfo + { + Metadata = new BeatmapMetadata + { + AuthorString = $"{ruleset.ShortName}Author", + Artist = $"{ruleset.ShortName}Artist", + Source = $"{ruleset.ShortName}Source", + Title = $"{ruleset.ShortName}Title" + }, + Ruleset = ruleset, + StarDifficulty = 6, + Version = $"{ruleset.ShortName}Version" + }, + HitObjects = new List() // TODO: Fill it with something depending on ruleset? + }; + } - var b = sets[random.Next(0, sets.Count)].Beatmaps[0]; - beatmap.Value = beatmaps.GetWorkingBeatmap(b); - infoWedge.UpdateBeatmap(beatmap); + private class TestBeatmapInfoWedge : BeatmapInfoWedge + { + public new BufferedWedgeInfo Info => base.Info; } } } diff --git a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs index 1434943da0..3ec83ed8d5 100644 --- a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs @@ -21,8 +21,7 @@ namespace osu.Game.Beatmaps Metadata = new BeatmapMetadata { Artist = "please load a beatmap!", - Title = "no beatmaps available!", - AuthorString = "no one", + Title = "no beatmaps available!" }, BeatmapSet = new BeatmapSetInfo(), BaseDifficulty = new BeatmapDifficulty diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 9b9a009ac0..5d4f950a51 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -27,7 +27,7 @@ namespace osu.Game.Screens.Select { private static readonly Vector2 wedged_container_shear = new Vector2(0.15f, 0); - private Drawable info; + protected BufferedWedgeInfo Info; public BeatmapInfoWedge() { @@ -63,23 +63,28 @@ namespace osu.Game.Screens.Select LoadComponentAsync(new BufferedWedgeInfo(beatmap) { Shear = -Shear, - Depth = info?.Depth + 1 ?? 0, + Depth = Info?.Depth + 1 ?? 0, }, newInfo => { // ensure we ourselves are visible if not already. if (!IsPresent) this.FadeIn(250); - info?.FadeOut(250); - info?.Expire(); + Info?.FadeOut(250); + Info?.Expire(); - Add(info = newInfo); + Add(Info = newInfo); }); } public class BufferedWedgeInfo : BufferedContainer { private readonly WorkingBeatmap working; + public OsuSpriteText VersionLabel { get; private set; } + public OsuSpriteText TitleLabel { get; private set; } + public OsuSpriteText ArtistLabel { get; private set; } + public FillFlowContainer MapperContainer { get; private set; } + public FillFlowContainer InfoLabelContainer { get; private set; } public BufferedWedgeInfo(WorkingBeatmap working) { @@ -139,7 +144,7 @@ namespace osu.Game.Screens.Select AutoSizeAxes = Axes.Both, Children = new Drawable[] { - new OsuSpriteText + VersionLabel = new OsuSpriteText { Font = @"Exo2.0-MediumItalic", Text = beatmapInfo.Version, @@ -157,26 +162,26 @@ namespace osu.Game.Screens.Select AutoSizeAxes = Axes.Both, Children = new Drawable[] { - new OsuSpriteText + TitleLabel = new OsuSpriteText { Font = @"Exo2.0-MediumItalic", Text = string.IsNullOrEmpty(metadata.Source) ? metadata.Title : metadata.Source + " — " + metadata.Title, TextSize = 28, }, - new OsuSpriteText + ArtistLabel = new OsuSpriteText { Font = @"Exo2.0-MediumItalic", Text = metadata.Artist, TextSize = 17, }, - new FillFlowContainer + MapperContainer = new FillFlowContainer { Margin = new MarginPadding { Top = 10 }, Direction = FillDirection.Horizontal, AutoSizeAxes = Axes.Both, Children = getMapper(metadata) }, - new FillFlowContainer + InfoLabelContainer = new FillFlowContainer { Margin = new MarginPadding { Top = 20 }, Spacing = new Vector2(20, 0), From 2313ff0ddbe0b04c04beda6fe4df5947ec32711f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 22 Dec 2017 22:19:11 +0900 Subject: [PATCH 04/49] Fix beatmap info wedge not showing up when zero beatmaps are loaded Closes #1722. --- osu.Game/Screens/Select/BeatmapCarousel.cs | 2 +- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 2 ++ osu.Game/Screens/Select/SongSelect.cs | 1 - 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index ff1dd95eac..e0fcba5b3c 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -509,7 +509,7 @@ namespace osu.Game.Screens.Select currentY += DrawHeight / 2; scrollableContent.Height = currentY; - if (selectedBeatmapSet != null && selectedBeatmapSet.State.Value != CarouselItemState.Selected) + if (selectedBeatmapSet == null || selectedBeatmapSet.State.Value != CarouselItemState.Selected) { selectedBeatmapSet = null; SelectionChanged?.Invoke(null); diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 3ef6ceeaeb..1baacb78ee 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -66,6 +66,8 @@ namespace osu.Game.Screens.Select Depth = info?.Depth + 1 ?? 0, }, newInfo => { + State = beatmap == null ? Visibility.Hidden : Visibility.Visible; + // ensure we ourselves are visible if not already. if (!IsPresent) this.FadeIn(250); diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 68ee08e721..9a7dbf002e 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -399,7 +399,6 @@ namespace osu.Game.Screens.Select backgroundModeBeatmap.FadeTo(1, 250); } - beatmapInfoWedge.State = Visibility.Visible; beatmapInfoWedge.UpdateBeatmap(beatmap); } From 6a8fd74e055bd3a35931c1112c86298e4cd6f91f Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Fri, 22 Dec 2017 17:38:22 +0100 Subject: [PATCH 05/49] fix failing tests 1) waiting for loading to finish so Drawables are all present to do asserts on 2) fix NullRef in ResultPage because of removed line in DummyWorkingBeatmap (author one) --- osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs | 8 ++++++++ osu.Game/Screens/Ranking/ResultsPageScore.cs | 9 ++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs b/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs index 353f351a54..1ef6291ee4 100644 --- a/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs +++ b/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs @@ -20,6 +20,7 @@ namespace osu.Game.Tests.Visual { public class TestCaseBeatmapInfoWedge : OsuTestCase { + private RulesetStore rulesets; private TestBeatmapInfoWedge infoWedge; private readonly List beatmaps = new List(); private readonly Bindable beatmap = new Bindable(); @@ -27,7 +28,14 @@ namespace osu.Game.Tests.Visual [BackgroundDependencyLoader] private void load(OsuGameBase game, RulesetStore rulesets) { + this.rulesets = rulesets; + beatmap.BindTo(game.Beatmap); + } + + protected override void LoadComplete() + { + base.LoadComplete(); Add(infoWedge = new TestBeatmapInfoWedge { diff --git a/osu.Game/Screens/Ranking/ResultsPageScore.cs b/osu.Game/Screens/Ranking/ResultsPageScore.cs index 911b688669..396d7f3c18 100644 --- a/osu.Game/Screens/Ranking/ResultsPageScore.cs +++ b/osu.Game/Screens/Ranking/ResultsPageScore.cs @@ -324,7 +324,14 @@ namespace osu.Game.Screens.Ranking title.Colour = artist.Colour = colours.BlueDarker; versionMapper.Colour = colours.Gray8; - versionMapper.Text = $"{beatmap.Version} - mapped by {beatmap.Metadata.Author.Username}"; + var creator = beatmap.Metadata.Author?.Username; + if (!string.IsNullOrEmpty(creator)) { + versionMapper.Text = $"mapped by {creator}"; + + if (!string.IsNullOrEmpty(beatmap.Version)) + versionMapper.Text = $"{beatmap.Version} - " + versionMapper.Text; + } + title.Current = localisation.GetUnicodePreference(beatmap.Metadata.TitleUnicode, beatmap.Metadata.Title); artist.Current = localisation.GetUnicodePreference(beatmap.Metadata.ArtistUnicode, beatmap.Metadata.Artist); } From 49e855a29ae3d4538d618e7c6de255e4afa29741 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Sat, 23 Dec 2017 11:56:53 +0100 Subject: [PATCH 06/49] finished up visual tests --- .../Visual/TestCaseBeatmapInfoWedge.cs | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs b/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs index 1ef6291ee4..61c904aa60 100644 --- a/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs +++ b/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs @@ -68,11 +68,15 @@ namespace osu.Game.Tests.Visual var name = rulesetInfo.ShortName; selectBeatmap(name); - // TODO: check InfoLabels of other rulesets + // TODO: adjust cases once more info is shown for other gamemodes switch (ruleset) { case OsuRuleset osu: testOsuBeatmap(osu); + testInfoLabels(5); + break; + default: + testInfoLabels(2); break; } } @@ -86,7 +90,12 @@ namespace osu.Game.Tests.Visual AddAssert("check title", () => infoWedge.Info.TitleLabel.Text == $"{ruleset.ShortName}Source — {ruleset.ShortName}Title"); AddAssert("check artist", () => infoWedge.Info.ArtistLabel.Text == $"{ruleset.ShortName}Artist"); AddAssert("check author", () => infoWedge.Info.MapperContainer.Children.OfType().Any(s => s.Text == $"{ruleset.ShortName}Author")); - // TODO: check InfoLabels + } + + private void testInfoLabels(int expectedCount) + { + AddAssert("check infolabels exists", () => infoWedge.Info.InfoLabelContainer.Children.Any()); + AddAssert("check infolabels count", () => infoWedge.Info.InfoLabelContainer.Children.Count == expectedCount); } private void testNullBeatmap() @@ -96,7 +105,7 @@ namespace osu.Game.Tests.Visual AddAssert("check default title", () => infoWedge.Info.TitleLabel.Text == beatmap.Default.BeatmapInfo.Metadata.Title); AddAssert("check default artist", () => infoWedge.Info.ArtistLabel.Text == beatmap.Default.BeatmapInfo.Metadata.Artist); AddAssert("check empty author", () => !infoWedge.Info.MapperContainer.Children.Any()); - AddAssert("check empty infos", () => !infoWedge.Info.InfoLabelContainer.Children.Any()); + AddAssert("check no infolabels", () => !infoWedge.Info.InfoLabelContainer.Children.Any()); } private void selectBeatmap(string name) @@ -119,6 +128,10 @@ namespace osu.Game.Tests.Visual private Beatmap createTestBeatmap(RulesetInfo ruleset) { + List objects = new List(); + for (double i = 0; i < 50000; i += 1000) + objects.Add(new HitObject { StartTime = i }); + return new Beatmap { BeatmapInfo = new BeatmapInfo @@ -134,7 +147,7 @@ namespace osu.Game.Tests.Visual StarDifficulty = 6, Version = $"{ruleset.ShortName}Version" }, - HitObjects = new List() // TODO: Fill it with something depending on ruleset? + HitObjects = objects }; } From 68d76d4380f2816088cd7f0344331e79aa4df907 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 23 Dec 2017 20:58:09 +0900 Subject: [PATCH 07/49] Fix taiko strong hits not being handled --- osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index d960ab6b48..c397ea47ef 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -174,7 +174,7 @@ namespace osu.Game.Rulesets.Objects.Drawables { judgementOccurred = false; - if (AllJudged || State != ArmedState.Idle) + if (AllJudged) return false; if (NestedHitObjects != null) From cf316b3c51661a7a21ae1b47c90b9f169c19b8f6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 24 Dec 2017 15:39:25 +0900 Subject: [PATCH 08/49] Add tests for initial load states of PlaySongSelect --- .../Visual/TestCasePlaySongSelect.cs | 48 ++++++++++++++++--- osu.Game/Screens/Select/BeatmapCarousel.cs | 1 - osu.Game/Screens/Select/SongSelect.cs | 34 ++++++------- 3 files changed, 59 insertions(+), 24 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs b/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs index 6435df7c2c..34b99c6ca6 100644 --- a/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs @@ -26,6 +26,7 @@ namespace osu.Game.Tests.Visual private RulesetStore rulesets; private DependencyContainer dependencies; + private WorkingBeatmap defaultBeatmap; public override IReadOnlyList RequiredTypes => new[] { @@ -47,10 +48,16 @@ namespace osu.Game.Tests.Visual protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) => dependencies = new DependencyContainer(parent); + private class TestSongSelect : PlaySongSelect + { + public WorkingBeatmap CurrentBeatmap => Beatmap.Value; + public new BeatmapCarousel Carousel => base.Carousel; + } + [BackgroundDependencyLoader] private void load(BeatmapManager baseManager) { - PlaySongSelect songSelect; + TestSongSelect songSelect = null; if (manager == null) { @@ -64,14 +71,43 @@ namespace osu.Game.Tests.Visual dependencies.Cache(rulesets = new RulesetStore(contextFactory)); dependencies.Cache(manager = new BeatmapManager(storage, contextFactory, rulesets, null) { - DefaultBeatmap = baseManager.GetWorkingBeatmap(null) + DefaultBeatmap = defaultBeatmap = baseManager.GetWorkingBeatmap(null) }); - - for (int i = 0; i < 100; i += 10) - manager.Import(createTestBeatmapSet(i)); } - Add(songSelect = new PlaySongSelect()); + void loadNewSongSelect(bool deleteMaps = false) => AddStep("reload song select", () => + { + if (deleteMaps) manager.DeleteAll(); + + if (songSelect != null) + { + Remove(songSelect); + songSelect.Dispose(); + } + + Add(songSelect = new TestSongSelect()); + }); + + loadNewSongSelect(true); + + AddWaitStep(1); + + AddAssert("dummy selected", () => songSelect.CurrentBeatmap == defaultBeatmap); + + AddStep("import test maps", () => + { + for (int i = 0; i < 100; i += 10) + manager.Import(createTestBeatmapSet(i)); + }); + + AddWaitStep(1); + AddStep("select random", () => songSelect.Carousel.SelectNextRandom()); + + AddWaitStep(1); + AddAssert("random map selected", () => songSelect.CurrentBeatmap != defaultBeatmap); + + loadNewSongSelect(); + AddAssert("random map selected", () => songSelect.CurrentBeatmap != defaultBeatmap); AddStep(@"Sort by Artist", delegate { songSelect.FilterControl.Sort = SortMode.Artist; }); AddStep(@"Sort by Title", delegate { songSelect.FilterControl.Sort = SortMode.Title; }); diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index bfba9a7d6b..b4ca6f10f9 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -142,7 +142,6 @@ namespace osu.Game.Screens.Select if (newSet == null) { itemsCache.Invalidate(); - SelectNext(); return; } diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 9a7dbf002e..a15699d97a 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -55,7 +55,7 @@ namespace osu.Game.Screens.Select protected Container LeftContent; - private readonly BeatmapCarousel carousel; + protected readonly BeatmapCarousel Carousel; private readonly BeatmapInfoWedge beatmapInfoWedge; private DialogOverlay dialogOverlay; private BeatmapManager beatmaps; @@ -103,7 +103,7 @@ namespace osu.Game.Screens.Select Right = left_area_padding * 2, } }, - carousel = new BeatmapCarousel + Carousel = new BeatmapCarousel { RelativeSizeAxes = Axes.Y, Size = new Vector2(carousel_width, 1), @@ -116,7 +116,7 @@ namespace osu.Game.Screens.Select { RelativeSizeAxes = Axes.X, Height = filter_height, - FilterChanged = c => carousel.Filter(c), + FilterChanged = c => Carousel.Filter(c), Exit = Exit, }, beatmapInfoWedge = new BeatmapInfoWedge @@ -130,7 +130,7 @@ namespace osu.Game.Screens.Select Right = left_area_padding, }, }, - new ResetScrollContainer(() => carousel.ScrollToSelected()) + new ResetScrollContainer(() => Carousel.ScrollToSelected()) { RelativeSizeAxes = Axes.Y, Width = 250, @@ -190,15 +190,15 @@ namespace osu.Game.Screens.Select initialAddSetsTask = new CancellationTokenSource(); - carousel.BeatmapSets = this.beatmaps.GetAllUsableBeatmapSets(); + Carousel.BeatmapSets = this.beatmaps.GetAllUsableBeatmapSets(); - Beatmap.DisabledChanged += disabled => carousel.AllowSelection = !disabled; + Beatmap.DisabledChanged += disabled => Carousel.AllowSelection = !disabled; Beatmap.TriggerChange(); Beatmap.ValueChanged += b => { if (IsCurrentScreen) - carousel.SelectBeatmap(b?.BeatmapInfo); + Carousel.SelectBeatmap(b?.BeatmapInfo); }; } @@ -212,9 +212,9 @@ namespace osu.Game.Screens.Select { // if we have a pending filter operation, we want to run it now. // it could change selection (ie. if the ruleset has been changed). - carousel.FlushPendingFilterOperations(); + Carousel.FlushPendingFilterOperations(); - carousel.SelectBeatmap(beatmap); + Carousel.SelectBeatmap(beatmap); if (selectionChangedDebounce?.Completed == false) { @@ -282,9 +282,9 @@ namespace osu.Game.Screens.Select private void triggerRandom() { if (GetContainingInputManager().CurrentState.Keyboard.ShiftPressed) - carousel.SelectPreviousRandom(); + Carousel.SelectPreviousRandom(); else - carousel.SelectNextRandom(); + Carousel.SelectNextRandom(); } protected override void OnEntering(Screen last) @@ -416,17 +416,17 @@ namespace osu.Game.Screens.Select } } - private void onBeatmapSetAdded(BeatmapSetInfo s) => carousel.UpdateBeatmapSet(s); - private void onBeatmapSetRemoved(BeatmapSetInfo s) => carousel.RemoveBeatmapSet(s); - private void onBeatmapRestored(BeatmapInfo b) => carousel.UpdateBeatmapSet(beatmaps.QueryBeatmapSet(s => s.ID == b.BeatmapSetInfoID)); - private void onBeatmapHidden(BeatmapInfo b) => carousel.UpdateBeatmapSet(beatmaps.QueryBeatmapSet(s => s.ID == b.BeatmapSetInfoID)); + private void onBeatmapSetAdded(BeatmapSetInfo s) => Carousel.UpdateBeatmapSet(s); + private void onBeatmapSetRemoved(BeatmapSetInfo s) => Carousel.RemoveBeatmapSet(s); + private void onBeatmapRestored(BeatmapInfo b) => Carousel.UpdateBeatmapSet(beatmaps.QueryBeatmapSet(s => s.ID == b.BeatmapSetInfoID)); + private void onBeatmapHidden(BeatmapInfo b) => Carousel.UpdateBeatmapSet(beatmaps.QueryBeatmapSet(s => s.ID == b.BeatmapSetInfoID)); private void carouselBeatmapsLoaded() { if (Beatmap.Value.BeatmapSetInfo?.DeletePending == false) - carousel.SelectBeatmap(Beatmap.Value.BeatmapInfo); + Carousel.SelectBeatmap(Beatmap.Value.BeatmapInfo); else - carousel.SelectNextRandom(); + Carousel.SelectNextRandom(); } private void delete(BeatmapSetInfo beatmap) From a04ebd0595e423c02e38b57b5e386020d19f7157 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 24 Dec 2017 15:39:44 +0900 Subject: [PATCH 09/49] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 08f85f9bf9..64e04b9ff2 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 08f85f9bf9a7376aec8dfcde8c7c96d267d8c295 +Subproject commit 64e04b9ff2d5ba53e5c3a46cfa42a79baeffc014 From 482e10966cfb5fd80c892695bfda6f250b6ae4ee Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 24 Dec 2017 17:02:46 +0900 Subject: [PATCH 10/49] Ensure a selection is made on entering song select if no selection is current --- osu.Game.Tests/Visual/TestCasePlaySongSelect.cs | 3 --- osu.Game/Screens/Select/BeatmapCarousel.cs | 4 +++- osu.Game/Screens/Select/SongSelect.cs | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs b/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs index 34b99c6ca6..87f71d215b 100644 --- a/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs @@ -100,9 +100,6 @@ namespace osu.Game.Tests.Visual manager.Import(createTestBeatmapSet(i)); }); - AddWaitStep(1); - AddStep("select random", () => songSelect.Carousel.SelectNextRandom()); - AddWaitStep(1); AddAssert("random map selected", () => songSelect.CurrentBeatmap != defaultBeatmap); diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index b4ca6f10f9..c33993c68c 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -75,7 +75,8 @@ namespace osu.Game.Screens.Select scrollableContent.Clear(false); itemsCache.Invalidate(); scrollPositionCache.Invalidate(); - BeatmapSetsChanged?.Invoke(); + + Schedule(() => BeatmapSetsChanged?.Invoke()); })); } } @@ -154,6 +155,7 @@ namespace osu.Game.Screens.Select select((CarouselItem)newSet.Beatmaps.FirstOrDefault(b => b.Beatmap.ID == selectedBeatmap?.Beatmap.ID) ?? newSet); itemsCache.Invalidate(); + Schedule(() => BeatmapSetsChanged?.Invoke()); }); } diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index a15699d97a..75c4a68388 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -423,7 +423,7 @@ namespace osu.Game.Screens.Select private void carouselBeatmapsLoaded() { - if (Beatmap.Value.BeatmapSetInfo?.DeletePending == false) + if (!Beatmap.IsDefault && Beatmap.Value.BeatmapSetInfo?.DeletePending == false) Carousel.SelectBeatmap(Beatmap.Value.BeatmapInfo); else Carousel.SelectNextRandom(); From a7ee6985b050fbf6df3f2880c87f7a1085cec863 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 25 Dec 2017 01:06:33 +0900 Subject: [PATCH 11/49] Add wait step --- osu.Game.Tests/Visual/TestCasePlaySongSelect.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs b/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs index 87f71d215b..e27e786a05 100644 --- a/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs @@ -104,6 +104,7 @@ namespace osu.Game.Tests.Visual AddAssert("random map selected", () => songSelect.CurrentBeatmap != defaultBeatmap); loadNewSongSelect(); + AddWaitStep(1); AddAssert("random map selected", () => songSelect.CurrentBeatmap != defaultBeatmap); AddStep(@"Sort by Artist", delegate { songSelect.FilterControl.Sort = SortMode.Artist; }); From 8529eb1d3a2350da13d8fb445a7d13375afa1c97 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 25 Dec 2017 14:49:39 +0900 Subject: [PATCH 12/49] Make strong hit misses not count as misses --- osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs index 81b23af1a9..07f7b83cef 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs @@ -36,7 +36,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables if (!userTriggered) { if (timeOffset > second_hit_window) - AddJudgement(new TaikoStrongHitJudgement { Result = HitResult.Miss }); + AddJudgement(new TaikoStrongHitJudgement { Result = HitResult.None }); return; } From 844e39a9f6f177be8bc4f41fe8ff69425052d622 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 25 Dec 2017 15:04:22 +0900 Subject: [PATCH 13/49] Make Swells play samples while they're being hit --- .../Objects/Drawables/DrawableSwell.cs | 37 ++++++++++++++----- osu.Game.Rulesets.Taiko/Objects/Swell.cs | 28 +++++++++++++- .../Objects/SwellSampleMapping.cs | 28 ++++++++++++++ .../osu.Game.Rulesets.Taiko.csproj | 1 + 4 files changed, 83 insertions(+), 11 deletions(-) create mode 100644 osu.Game.Rulesets.Taiko/Objects/SwellSampleMapping.cs diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs index 738902846b..d657598554 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs @@ -14,6 +14,7 @@ using OpenTK; using OpenTK.Graphics; using osu.Framework.Graphics.Shapes; using osu.Game.Rulesets.Taiko.Judgements; +using osu.Framework.Audio; namespace osu.Game.Rulesets.Taiko.Objects.Drawables { @@ -34,10 +35,6 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables private readonly CircularContainer targetRing; private readonly CircularContainer expandingRing; - private readonly TaikoAction[] rimActions = { TaikoAction.LeftRim, TaikoAction.RightRim }; - private readonly TaikoAction[] centreActions = { TaikoAction.LeftCentre, TaikoAction.RightCentre }; - private TaikoAction[] lastAction; - /// /// The amount of times the user has hit this swell. /// @@ -120,11 +117,14 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load(OsuColour colours, AudioManager audio) { MainPiece.AccentColour = colours.YellowDark; expandingRing.Colour = colours.YellowLight; targetRing.BorderColour = colours.YellowDark.Opacity(0.25f); + + foreach (var mapping in HitObject.ProgressionSamples) + mapping.RetrieveChannels(audio); } protected override void LoadComplete() @@ -205,22 +205,39 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables } } + private bool? lastWasCentre; + public override bool OnPressed(TaikoAction action) { // Don't handle keys before the swell starts if (Time.Current < HitObject.StartTime) return false; - // Find the keyset which this key corresponds to - var keySet = rimActions.Contains(action) ? rimActions : centreActions; + var isCentre = action == TaikoAction.LeftCentre || action == TaikoAction.RightCentre; - // Ensure alternating keysets - if (keySet == lastAction) + // Ensure alternating centre and rim hits + if (lastWasCentre == isCentre) return false; - lastAction = keySet; + lastWasCentre = isCentre; UpdateJudgement(true); + if (AllJudged) + return true; + + // While the swell hasn't been fully judged, input is still blocked so it doesn't fall through to other hitobjects + // This causes the playfield to not play sounds, so they need to be handled locally + + var mappingIndex = HitObject.ProgressionSamples.BinarySearch(new SwellSampleMapping { Time = Time.Current }); + if (mappingIndex < 0) + mappingIndex = ~mappingIndex - 1; + + var mapping = HitObject.ProgressionSamples[mappingIndex]; + if (isCentre) + mapping.CentreChannel.Play(); + else + mapping.RimChannel.Play(); + return true; } } diff --git a/osu.Game.Rulesets.Taiko/Objects/Swell.cs b/osu.Game.Rulesets.Taiko/Objects/Swell.cs index f74a543ca9..b4fa736045 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Swell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Swell.cs @@ -1,6 +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 System.Linq; +using osu.Game.Audio; +using osu.Game.Beatmaps; +using osu.Game.Beatmaps.ControlPoints; using osu.Game.Rulesets.Objects.Types; namespace osu.Game.Rulesets.Taiko.Objects @@ -15,5 +20,26 @@ namespace osu.Game.Rulesets.Taiko.Objects /// The number of hits required to complete the swell successfully. /// public int RequiredHits = 10; + + public List ProgressionSamples = new List(); + + protected override void ApplyDefaultsToSelf(ControlPointInfo controlPointInfo, BeatmapDifficulty difficulty) + { + base.ApplyDefaultsToSelf(controlPointInfo, difficulty); + + var progressionSamplePoints = + new[] { controlPointInfo.SamplePointAt(StartTime) } + .Concat(controlPointInfo.SamplePoints.Where(p => p.Time > StartTime && p.Time <= EndTime)); + + foreach (var point in progressionSamplePoints) + { + ProgressionSamples.Add(new SwellSampleMapping + { + Time = point.Time, + Centre = point.GetSampleInfo(), + Rim = point.GetSampleInfo(SampleInfo.HIT_CLAP) + }); + } + } } -} \ No newline at end of file +} diff --git a/osu.Game.Rulesets.Taiko/Objects/SwellSampleMapping.cs b/osu.Game.Rulesets.Taiko/Objects/SwellSampleMapping.cs new file mode 100644 index 0000000000..99d0e1d0fd --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Objects/SwellSampleMapping.cs @@ -0,0 +1,28 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using osu.Framework.Audio; +using osu.Framework.Audio.Sample; +using osu.Game.Audio; + +namespace osu.Game.Rulesets.Taiko.Objects +{ + public class SwellSampleMapping : IComparable + { + public double Time; + public SampleInfo Centre; + public SampleInfo Rim; + + public SampleChannel CentreChannel { get; private set; } + public SampleChannel RimChannel { get; private set; } + + public void RetrieveChannels(AudioManager audio) + { + CentreChannel = Centre.GetChannel(audio.Sample); + RimChannel = Rim.GetChannel(audio.Sample); + } + + public int CompareTo(SwellSampleMapping other) => Time.CompareTo(other.Time); + } +} diff --git a/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj b/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj index bb02db62b9..9fa3936153 100644 --- a/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj +++ b/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj @@ -74,6 +74,7 @@ + From d288d8a51f370a6f91141c046ad3a67b4a1a6c5a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 25 Dec 2017 15:35:28 +0900 Subject: [PATCH 14/49] Remove SampleInfoList --- osu.Game.Rulesets.Catch/Objects/JuiceStream.cs | 6 +++--- .../Beatmaps/ManiaBeatmapConverter.cs | 2 +- .../Legacy/DistanceObjectPatternGenerator.cs | 3 ++- .../Legacy/EndTimeObjectPatternGenerator.cs | 3 ++- osu.Game.Rulesets.Osu/Objects/Slider.cs | 6 +++--- .../Beatmaps/TaikoBeatmapConverter.cs | 6 +++--- osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs | 3 ++- .../Tests/TestCaseTaikoPlayfield.cs | 14 ++++++++++++-- osu.Game/Audio/SampleInfoList.cs | 18 ------------------ osu.Game/Rulesets/Objects/HitObject.cs | 2 +- .../Legacy/Catch/ConvertHitObjectParser.cs | 2 +- .../Objects/Legacy/ConvertHitObjectParser.cs | 8 ++++---- .../Rulesets/Objects/Legacy/ConvertSlider.cs | 2 +- .../Legacy/Mania/ConvertHitObjectParser.cs | 2 +- .../Legacy/Osu/ConvertHitObjectParser.cs | 4 ++-- .../Legacy/Taiko/ConvertHitObjectParser.cs | 4 ++-- osu.Game/Rulesets/Objects/Types/IHasRepeats.cs | 2 +- osu.Game/osu.Game.csproj | 1 - 18 files changed, 41 insertions(+), 47 deletions(-) delete mode 100644 osu.Game/Audio/SampleInfoList.cs diff --git a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs index 8e496c3b0c..7d0d80a0ce 100644 --- a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs @@ -86,7 +86,7 @@ namespace osu.Game.Rulesets.Catch.Objects StartTime = lastTickTime, ComboColour = ComboColour, X = Curve.PositionAt(distanceProgress).X / CatchPlayfield.BASE_WIDTH, - Samples = new SampleInfoList(Samples.Select(s => new SampleInfo + Samples = new List(Samples.Select(s => new SampleInfo { Bank = s.Bank, Name = @"slidertick", @@ -108,7 +108,7 @@ namespace osu.Game.Rulesets.Catch.Objects StartTime = repeatStartTime + t, ComboColour = ComboColour, X = Curve.PositionAt(progress).X / CatchPlayfield.BASE_WIDTH, - Samples = new SampleInfoList(Samples.Select(s => new SampleInfo + Samples = new List(Samples.Select(s => new SampleInfo { Bank = s.Bank, Name = @"slidertick", @@ -147,7 +147,7 @@ namespace osu.Game.Rulesets.Catch.Objects set { Curve.ControlPoints = value; } } - public List RepeatSamples { get; set; } = new List(); + public List> RepeatSamples { get; set; } = new List>(); public CurveType CurveType { diff --git a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs index d5a799b4ed..407d4db143 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs @@ -192,7 +192,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps /// /// The time to retrieve the sample info list from. /// - private SampleInfoList sampleInfoListAt(double time) + private List sampleInfoListAt(double time) { var curveData = HitObject as IHasCurve; diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs index 270c264e0c..8251dea5f7 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using System.Collections.Generic; using System.Linq; using osu.Game.Audio; using osu.Game.Beatmaps; @@ -435,7 +436,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy /// /// The time to retrieve the sample info list from. /// - private SampleInfoList sampleInfoListAt(double time) + private List sampleInfoListAt(double time) { var curveData = HitObject as IHasCurve; diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs index 3e9fc1ae27..8e832960df 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.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 System.Collections.Generic; using osu.Game.Beatmaps; using osu.Game.Rulesets.Mania.MathUtils; using osu.Game.Rulesets.Objects; @@ -77,7 +78,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy }; if (hold.Head.Samples == null) - hold.Head.Samples = new SampleInfoList(); + hold.Head.Samples = new List(); hold.Head.Samples.Add(new SampleInfo { Name = SampleInfo.HIT_NORMAL }); diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs index 4f5a44e61d..5f9f11c783 100644 --- a/osu.Game.Rulesets.Osu/Objects/Slider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs @@ -57,7 +57,7 @@ namespace osu.Game.Rulesets.Osu.Objects /// internal float LazyTravelDistance; - public List RepeatSamples { get; set; } = new List(); + public List> RepeatSamples { get; set; } = new List>(); public int RepeatCount { get; set; } = 1; private int stackHeight; @@ -138,7 +138,7 @@ namespace osu.Game.Rulesets.Osu.Objects StackHeight = StackHeight, Scale = Scale, ComboColour = ComboColour, - Samples = new SampleInfoList(Samples.Select(s => new SampleInfo + Samples = new List(Samples.Select(s => new SampleInfo { Bank = s.Bank, Name = @"slidertick", @@ -170,7 +170,7 @@ namespace osu.Game.Rulesets.Osu.Objects StackHeight = StackHeight, Scale = Scale, ComboColour = ComboColour, - Samples = new SampleInfoList(RepeatSamples[repeat]) + Samples = new List(RepeatSamples[repeat]) }); } } diff --git a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs index 9b4a6c47a9..690b80b12c 100644 --- a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs +++ b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs @@ -78,7 +78,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps var curveData = obj as IHasCurve; // Old osu! used hit sounding to determine various hit type information - SampleInfoList samples = obj.Samples; + List samples = obj.Samples; bool strong = samples.Any(s => s.Name == SampleInfo.HIT_FINISH); @@ -115,12 +115,12 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps if (!isForCurrentRuleset && tickSpacing > 0 && osuDuration < 2 * speedAdjustedBeatLength) { - List allSamples = curveData != null ? curveData.RepeatSamples : new List(new[] { samples }); + List> allSamples = curveData != null ? curveData.RepeatSamples : new List>(new[] { samples }); int i = 0; for (double j = obj.StartTime; j <= obj.StartTime + taikoDuration + tickSpacing / 8; j += tickSpacing) { - SampleInfoList currentSamples = allSamples[i]; + List currentSamples = allSamples[i]; bool isRim = currentSamples.Any(s => s.Name == SampleInfo.HIT_CLAP || s.Name == SampleInfo.HIT_WHISTLE); strong = currentSamples.Any(s => s.Name == SampleInfo.HIT_FINISH); diff --git a/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs b/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs index 4104b59979..5a566fd091 100644 --- a/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs +++ b/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs @@ -3,6 +3,7 @@ using osu.Game.Rulesets.Objects.Types; using System; +using System.Collections.Generic; using System.Linq; using osu.Game.Audio; using osu.Game.Beatmaps; @@ -75,7 +76,7 @@ namespace osu.Game.Rulesets.Taiko.Objects TickSpacing = tickSpacing, StartTime = t, IsStrong = IsStrong, - Samples = new SampleInfoList(Samples.Select(s => new SampleInfo + Samples = new List(Samples.Select(s => new SampleInfo { Bank = s.Bank, Name = @"slidertick", diff --git a/osu.Game.Rulesets.Taiko/Tests/TestCaseTaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/Tests/TestCaseTaikoPlayfield.cs index bca4806108..b1e6e9c4ce 100644 --- a/osu.Game.Rulesets.Taiko/Tests/TestCaseTaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/Tests/TestCaseTaikoPlayfield.cs @@ -165,11 +165,15 @@ namespace osu.Game.Rulesets.Taiko.Tests private void addSwell(double duration = default_duration) { - rulesetContainer.Playfield.Add(new DrawableSwell(new Swell + var swell = new Swell { StartTime = rulesetContainer.Playfield.Time.Current + scroll_time, Duration = duration, - })); + }; + + swell.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); + + rulesetContainer.Playfield.Add(new DrawableSwell(swell)); } private void addDrumRoll(bool strong, double duration = default_duration) @@ -184,6 +188,8 @@ namespace osu.Game.Rulesets.Taiko.Tests Duration = duration, }; + d.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); + rulesetContainer.Playfield.Add(new DrawableDrumRoll(d)); } @@ -195,6 +201,8 @@ namespace osu.Game.Rulesets.Taiko.Tests IsStrong = strong }; + h.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); + if (strong) rulesetContainer.Playfield.Add(new DrawableCentreHitStrong(h)); else @@ -209,6 +217,8 @@ namespace osu.Game.Rulesets.Taiko.Tests IsStrong = strong }; + h.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty()); + if (strong) rulesetContainer.Playfield.Add(new DrawableRimHitStrong(h)); else diff --git a/osu.Game/Audio/SampleInfoList.cs b/osu.Game/Audio/SampleInfoList.cs deleted file mode 100644 index 06dd716a4a..0000000000 --- a/osu.Game/Audio/SampleInfoList.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using System.Collections.Generic; - -namespace osu.Game.Audio -{ - public class SampleInfoList : List - { - public SampleInfoList() - { - } - - public SampleInfoList(IEnumerable elements) : base(elements) - { - } - } -} \ No newline at end of file diff --git a/osu.Game/Rulesets/Objects/HitObject.cs b/osu.Game/Rulesets/Objects/HitObject.cs index e950516bf4..56f7a2e1a2 100644 --- a/osu.Game/Rulesets/Objects/HitObject.cs +++ b/osu.Game/Rulesets/Objects/HitObject.cs @@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Objects /// and can be treated as the default samples for the hit object. /// /// - public SampleInfoList Samples; + public List Samples; [JsonIgnore] public SampleControlPoint SampleControlPoint; diff --git a/osu.Game/Rulesets/Objects/Legacy/Catch/ConvertHitObjectParser.cs b/osu.Game/Rulesets/Objects/Legacy/Catch/ConvertHitObjectParser.cs index 667f921e04..fbf02f5345 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Catch/ConvertHitObjectParser.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Catch/ConvertHitObjectParser.cs @@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Catch }; } - protected override HitObject CreateSlider(Vector2 position, bool newCombo, List controlPoints, double length, CurveType curveType, int repeatCount, List repeatSamples) + protected override HitObject CreateSlider(Vector2 position, bool newCombo, List controlPoints, double length, CurveType curveType, int repeatCount, List> repeatSamples) { return new ConvertSlider { diff --git a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs index 0d7d617405..bdbd7a9e65 100644 --- a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs +++ b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs @@ -127,7 +127,7 @@ namespace osu.Game.Rulesets.Objects.Legacy } // Generate the final per-node samples - var nodeSamples = new List(nodes); + var nodeSamples = new List>(nodes); for (int i = 0; i <= repeatCount; i++) nodeSamples.Add(convertSoundType(nodeSoundTypes[i], nodeBankInfos[i])); @@ -216,7 +216,7 @@ namespace osu.Game.Rulesets.Objects.Legacy /// The slider repeat count. /// The samples to be played when the repeat nodes are hit. This includes the head and tail of the slider. /// The hit object. - protected abstract HitObject CreateSlider(Vector2 position, bool newCombo, List controlPoints, double length, CurveType curveType, int repeatCount, List repeatSamples); + protected abstract HitObject CreateSlider(Vector2 position, bool newCombo, List controlPoints, double length, CurveType curveType, int repeatCount, List> repeatSamples); /// /// Creates a legacy Spinner-type hit object. @@ -234,9 +234,9 @@ namespace osu.Game.Rulesets.Objects.Legacy /// The hold end time. protected abstract HitObject CreateHold(Vector2 position, bool newCombo, double endTime); - private SampleInfoList convertSoundType(LegacySoundType type, SampleBankInfo bankInfo) + private List convertSoundType(LegacySoundType type, SampleBankInfo bankInfo) { - var soundTypes = new SampleInfoList + var soundTypes = new List { new SampleInfo { diff --git a/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs b/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs index 698b74cc28..6dc8a07630 100644 --- a/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs +++ b/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs @@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Objects.Legacy public double Distance { get; set; } - public List RepeatSamples { get; set; } + public List> RepeatSamples { get; set; } public int RepeatCount { get; set; } = 1; public double EndTime => StartTime + RepeatCount * Distance / Velocity; diff --git a/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHitObjectParser.cs b/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHitObjectParser.cs index 86dd40b06e..2060b84222 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHitObjectParser.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHitObjectParser.cs @@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Mania }; } - protected override HitObject CreateSlider(Vector2 position, bool newCombo, List controlPoints, double length, CurveType curveType, int repeatCount, List repeatSamples) + protected override HitObject CreateSlider(Vector2 position, bool newCombo, List controlPoints, double length, CurveType curveType, int repeatCount, List> repeatSamples) { return new ConvertSlider { diff --git a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHitObjectParser.cs b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHitObjectParser.cs index 24c205db13..0062d29446 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHitObjectParser.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHitObjectParser.cs @@ -2,9 +2,9 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using OpenTK; -using osu.Game.Audio; using osu.Game.Rulesets.Objects.Types; using System.Collections.Generic; +using osu.Game.Audio; namespace osu.Game.Rulesets.Objects.Legacy.Osu { @@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Osu }; } - protected override HitObject CreateSlider(Vector2 position, bool newCombo, List controlPoints, double length, CurveType curveType, int repeatCount, List repeatSamples) + protected override HitObject CreateSlider(Vector2 position, bool newCombo, List controlPoints, double length, CurveType curveType, int repeatCount, List> repeatSamples) { return new ConvertSlider { diff --git a/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertHitObjectParser.cs b/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertHitObjectParser.cs index 0554cfd97d..529a28ac15 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertHitObjectParser.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertHitObjectParser.cs @@ -2,9 +2,9 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using OpenTK; -using osu.Game.Audio; using osu.Game.Rulesets.Objects.Types; using System.Collections.Generic; +using osu.Game.Audio; namespace osu.Game.Rulesets.Objects.Legacy.Taiko { @@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Taiko }; } - protected override HitObject CreateSlider(Vector2 position, bool newCombo, List controlPoints, double length, CurveType curveType, int repeatCount, List repeatSamples) + protected override HitObject CreateSlider(Vector2 position, bool newCombo, List controlPoints, double length, CurveType curveType, int repeatCount, List> repeatSamples) { return new ConvertSlider { diff --git a/osu.Game/Rulesets/Objects/Types/IHasRepeats.cs b/osu.Game/Rulesets/Objects/Types/IHasRepeats.cs index 5abad2d661..2fe2424d49 100644 --- a/osu.Game/Rulesets/Objects/Types/IHasRepeats.cs +++ b/osu.Game/Rulesets/Objects/Types/IHasRepeats.cs @@ -19,6 +19,6 @@ namespace osu.Game.Rulesets.Objects.Types /// /// The samples to be played when each repeat node is hit (0 -> first repeat node, 1 -> second repeat node, etc). /// - List RepeatSamples { get; } + List> RepeatSamples { get; } } } diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 94678106bf..1c5d20842d 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -239,7 +239,6 @@ - From 0fb620a8d3c730da1f10d1d5ab45482d783a3b2d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 25 Dec 2017 16:41:18 +0900 Subject: [PATCH 15/49] Make HitObject.Samples non-nullable --- osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs | 5 +++-- osu.Game/Rulesets/Objects/HitObject.cs | 8 +++++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index c397ea47ef..be161b9ad3 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -84,10 +84,11 @@ namespace osu.Game.Rulesets.Objects.Drawables [BackgroundDependencyLoader] private void load(AudioManager audio) { - if (HitObject.Samples != null) + if (Samples.Count > 0) { if (HitObject.SampleControlPoint == null) - throw new ArgumentNullException(nameof(HitObject.SampleControlPoint), $"{nameof(HitObject)} must always have an attached {nameof(HitObject.SampleControlPoint)}."); + throw new ArgumentNullException(nameof(HitObject.SampleControlPoint), $"{nameof(HitObject)}s must always have an attached {nameof(HitObject.SampleControlPoint)}." + + $" This is an indication that {nameof(HitObject.ApplyDefaults)} has not been invoked on {this}."); foreach (SampleInfo s in HitObject.Samples) { diff --git a/osu.Game/Rulesets/Objects/HitObject.cs b/osu.Game/Rulesets/Objects/HitObject.cs index 56f7a2e1a2..4f06f6afe1 100644 --- a/osu.Game/Rulesets/Objects/HitObject.cs +++ b/osu.Game/Rulesets/Objects/HitObject.cs @@ -25,6 +25,8 @@ namespace osu.Game.Rulesets.Objects /// public virtual double StartTime { get; set; } + private List samples; + /// /// The samples to be played when this hit object is hit. /// @@ -32,7 +34,11 @@ namespace osu.Game.Rulesets.Objects /// and can be treated as the default samples for the hit object. /// /// - public List Samples; + public List Samples + { + get => samples ?? (samples = new List()); + set => samples = value; + } [JsonIgnore] public SampleControlPoint SampleControlPoint; From 8bfdee586b6cde7effbc17b8c3ae6b7ed1ae4dec Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 25 Dec 2017 16:47:29 +0900 Subject: [PATCH 16/49] Rename SwellSampleMapping -> DrumSampleMapping --- .../Audio/DrumSampleMapping.cs | 40 +++++++++++++++++++ .../Objects/Drawables/DrawableSwell.cs | 3 +- osu.Game.Rulesets.Taiko/Objects/Swell.cs | 15 ++----- .../Objects/SwellSampleMapping.cs | 28 ------------- .../osu.Game.Rulesets.Taiko.csproj | 2 +- 5 files changed, 47 insertions(+), 41 deletions(-) create mode 100644 osu.Game.Rulesets.Taiko/Audio/DrumSampleMapping.cs delete mode 100644 osu.Game.Rulesets.Taiko/Objects/SwellSampleMapping.cs diff --git a/osu.Game.Rulesets.Taiko/Audio/DrumSampleMapping.cs b/osu.Game.Rulesets.Taiko/Audio/DrumSampleMapping.cs new file mode 100644 index 0000000000..25fa9951df --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Audio/DrumSampleMapping.cs @@ -0,0 +1,40 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using osu.Framework.Audio; +using osu.Framework.Audio.Sample; +using osu.Game.Audio; +using osu.Game.Beatmaps.ControlPoints; + +namespace osu.Game.Rulesets.Taiko.Audio +{ + public class DrumSampleMapping : IComparable + { + public double Time; + public readonly SampleInfo Centre; + public readonly SampleInfo Rim; + + public SampleChannel CentreChannel { get; private set; } + public SampleChannel RimChannel { get; private set; } + + public DrumSampleMapping() + { + } + + public DrumSampleMapping(SampleControlPoint samplePoint) + { + Time = samplePoint.Time; + Centre = samplePoint.GetSampleInfo(); + Rim = samplePoint.GetSampleInfo(SampleInfo.HIT_CLAP); + } + + public void RetrieveChannels(AudioManager audio) + { + CentreChannel = Centre.GetChannel(audio.Sample); + RimChannel = Rim.GetChannel(audio.Sample); + } + + public int CompareTo(DrumSampleMapping other) => Time.CompareTo(other.Time); + } +} diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs index d657598554..5131572abd 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs @@ -15,6 +15,7 @@ using OpenTK.Graphics; using osu.Framework.Graphics.Shapes; using osu.Game.Rulesets.Taiko.Judgements; using osu.Framework.Audio; +using osu.Game.Rulesets.Taiko.Audio; namespace osu.Game.Rulesets.Taiko.Objects.Drawables { @@ -228,7 +229,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables // While the swell hasn't been fully judged, input is still blocked so it doesn't fall through to other hitobjects // This causes the playfield to not play sounds, so they need to be handled locally - var mappingIndex = HitObject.ProgressionSamples.BinarySearch(new SwellSampleMapping { Time = Time.Current }); + var mappingIndex = HitObject.ProgressionSamples.BinarySearch(new DrumSampleMapping { Time = Time.Current }); if (mappingIndex < 0) mappingIndex = ~mappingIndex - 1; diff --git a/osu.Game.Rulesets.Taiko/Objects/Swell.cs b/osu.Game.Rulesets.Taiko/Objects/Swell.cs index b4fa736045..849c88ee4d 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Swell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Swell.cs @@ -7,6 +7,7 @@ using osu.Game.Audio; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Rulesets.Objects.Types; +using osu.Game.Rulesets.Taiko.Audio; namespace osu.Game.Rulesets.Taiko.Objects { @@ -21,25 +22,17 @@ namespace osu.Game.Rulesets.Taiko.Objects /// public int RequiredHits = 10; - public List ProgressionSamples = new List(); + public List ProgressionSamples = new List(); protected override void ApplyDefaultsToSelf(ControlPointInfo controlPointInfo, BeatmapDifficulty difficulty) { base.ApplyDefaultsToSelf(controlPointInfo, difficulty); - var progressionSamplePoints = - new[] { controlPointInfo.SamplePointAt(StartTime) } + var progressionSamplePoints = new[] { controlPointInfo.SamplePointAt(StartTime) } .Concat(controlPointInfo.SamplePoints.Where(p => p.Time > StartTime && p.Time <= EndTime)); foreach (var point in progressionSamplePoints) - { - ProgressionSamples.Add(new SwellSampleMapping - { - Time = point.Time, - Centre = point.GetSampleInfo(), - Rim = point.GetSampleInfo(SampleInfo.HIT_CLAP) - }); - } + ProgressionSamples.Add(new DrumSampleMapping(point)); } } } diff --git a/osu.Game.Rulesets.Taiko/Objects/SwellSampleMapping.cs b/osu.Game.Rulesets.Taiko/Objects/SwellSampleMapping.cs deleted file mode 100644 index 99d0e1d0fd..0000000000 --- a/osu.Game.Rulesets.Taiko/Objects/SwellSampleMapping.cs +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using System; -using osu.Framework.Audio; -using osu.Framework.Audio.Sample; -using osu.Game.Audio; - -namespace osu.Game.Rulesets.Taiko.Objects -{ - public class SwellSampleMapping : IComparable - { - public double Time; - public SampleInfo Centre; - public SampleInfo Rim; - - public SampleChannel CentreChannel { get; private set; } - public SampleChannel RimChannel { get; private set; } - - public void RetrieveChannels(AudioManager audio) - { - CentreChannel = Centre.GetChannel(audio.Sample); - RimChannel = Rim.GetChannel(audio.Sample); - } - - public int CompareTo(SwellSampleMapping other) => Time.CompareTo(other.Time); - } -} diff --git a/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj b/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj index 9fa3936153..f1c29c1a34 100644 --- a/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj +++ b/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj @@ -44,6 +44,7 @@ + @@ -74,7 +75,6 @@ - From ac8b345bfebba4530c67bbf9d0087472825ace18 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 25 Dec 2017 17:29:20 +0900 Subject: [PATCH 17/49] Make TaikoPlayfield use the new DrumSampleMapping --- osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 37 +++++++++----------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index 2cc95fc981..96ef86e3ce 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -23,6 +23,7 @@ using osu.Framework.Audio.Sample; using System.Collections.Generic; using osu.Game.Audio; using System; +using osu.Game.Rulesets.Taiko.Audio; namespace osu.Game.Rulesets.Taiko.UI { @@ -62,7 +63,7 @@ namespace osu.Game.Rulesets.Taiko.UI private readonly Box background; private readonly ControlPointInfo controlPointInfo; - private Dictionary drumSampleMappings; + private readonly List drumSampleMappings = new List(); public TaikoPlayfield(ControlPointInfo controlPointInfo) : base(Axes.X) @@ -207,15 +208,16 @@ namespace osu.Game.Rulesets.Taiko.UI [BackgroundDependencyLoader] private void load(OsuColour colours, AudioManager audio) { - drumSampleMappings = new Dictionary(); - foreach (var s in controlPointInfo.SamplePoints) + // We may have 0 sample points, but we need at least the default one + var samplePoints = new[] { controlPointInfo.SamplePointAt(double.MinValue) } + .Concat(controlPointInfo.SamplePoints); + + foreach (var s in samplePoints) { - drumSampleMappings.Add(s, - new DrumSamples - { - Centre = s.GetSampleInfo().GetChannel(audio.Sample), - Rim = s.GetSampleInfo(SampleInfo.HIT_CLAP).GetChannel(audio.Sample) - }); + var mapping = new DrumSampleMapping(s); + mapping.RetrieveChannels(audio); + + drumSampleMappings.Add(mapping); } overlayBackgroundContainer.BorderColour = colours.Gray0; @@ -285,25 +287,20 @@ namespace osu.Game.Rulesets.Taiko.UI public bool OnPressed(TaikoAction action) { - var samplePoint = controlPointInfo.SamplePointAt(Clock.CurrentTime); + var mappingIndex = drumSampleMappings.BinarySearch(new DrumSampleMapping { Time = Time.Current }); + if (mappingIndex < 0) + mappingIndex = ~mappingIndex - 1; - if (!drumSampleMappings.TryGetValue(samplePoint, out var samples)) - throw new InvalidOperationException("Current sample set not found."); + var mapping = drumSampleMappings[mappingIndex]; if (action == TaikoAction.LeftCentre || action == TaikoAction.RightCentre) - samples.Centre.Play(); + mapping.CentreChannel.Play(); else - samples.Rim.Play(); + mapping.RimChannel.Play(); return true; } public bool OnReleased(TaikoAction action) => false; - - private class DrumSamples - { - public SampleChannel Centre; - public SampleChannel Rim; - } } } From affdd81563b21d0fdfec753bc2dcdc46cb417ad9 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 25 Dec 2017 17:29:44 +0900 Subject: [PATCH 18/49] Remove unused usings --- osu.Game.Rulesets.Taiko/Objects/Swell.cs | 1 - osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 3 --- 2 files changed, 4 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Objects/Swell.cs b/osu.Game.Rulesets.Taiko/Objects/Swell.cs index 849c88ee4d..714e5d29ee 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Swell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Swell.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Linq; -using osu.Game.Audio; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Rulesets.Objects.Types; diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index 96ef86e3ce..229e44cf27 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -19,10 +19,7 @@ using osu.Game.Rulesets.Taiko.Objects.Drawables; using osu.Framework.Input.Bindings; using osu.Game.Beatmaps.ControlPoints; using osu.Framework.Audio; -using osu.Framework.Audio.Sample; using System.Collections.Generic; -using osu.Game.Audio; -using System; using osu.Game.Rulesets.Taiko.Audio; namespace osu.Game.Rulesets.Taiko.UI From 320a6b0480036653aa0e3f976918c00422ccedff Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 25 Dec 2017 17:12:21 +0900 Subject: [PATCH 19/49] Reduce notification output when exceptions are encountered --- osu.Game/OsuGame.cs | 40 +++++++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 67f6e6f4e2..95a7e696ea 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -220,15 +220,7 @@ namespace osu.Game Depth = -6, }, overlayContent.Add); - Logger.NewEntry += entry => - { - if (entry.Level < LogLevel.Important) return; - - notifications.Post(new SimpleNotification - { - Text = $@"{entry.Level}: {entry.Message}" - }); - }; + forwardLoggedErrorsToNotifications(); dependencies.Cache(settings); dependencies.Cache(social); @@ -290,6 +282,36 @@ namespace osu.Game Cursor.State = Visibility.Hidden; } + private void forwardLoggedErrorsToNotifications() + { + int recentErrorCount = 0; + + const double debounce = 5000; + + Logger.NewEntry += entry => + { + if (entry.Level < LogLevel.Error || entry.Target == null) return; + + if (recentErrorCount < 2) + { + notifications.Post(new SimpleNotification + { + Icon = FontAwesome.fa_bomb, + Text = (recentErrorCount == 0 ? entry.Message : "Subsequent errors occurred and have been logged.") + "\nClick to view log files.", + Activated = () => + { + Host.Storage.GetStorageForDirectory("logs").OpenInNativeExplorer(); + return true; + } + }); + } + + recentErrorCount++; + + Scheduler.AddDelayed(() => recentErrorCount--, debounce); + }; + } + private Task asyncLoadStream; private void loadComponentSingleFile(T d, Action add) From 6f5f4f76e5f548ac35c256122c5b23be3b8a647f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 25 Dec 2017 18:21:15 +0900 Subject: [PATCH 20/49] Use Logger.Error when exceptions are involved --- osu.Game/OsuGameBase.cs | 3 +-- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 2 +- osu.Game/Screens/Play/Player.cs | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 0ddff5e5aa..ea0bf22112 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -177,8 +177,7 @@ namespace osu.Game } catch (MigrationFailedException e) { - Logger.Log((e.InnerException ?? e).ToString(), LoggingTarget.Database, LogLevel.Error); - Logger.Log("Migration failed! We'll be starting with a fresh database.", LoggingTarget.Database, LogLevel.Error); + Logger.Error(e.InnerException ?? e, "Migration failed! We'll be starting with a fresh database.", LoggingTarget.Database); // if we failed, let's delete the database and start fresh. // todo: we probably want a better (non-destructive) migrations/recovery process at a later point than this. diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index 4487f74364..36740b96cb 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Edit } catch (Exception e) { - Logger.Log($"Could not load this beatmap sucessfully ({e})!", LoggingTarget.Runtime, LogLevel.Error); + Logger.Error(e, "Could not load beatmap sucessfully!"); return; } diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 340fc39d52..2cbb203c37 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -125,7 +125,7 @@ namespace osu.Game.Screens.Play } catch (Exception e) { - Logger.Log($"Could not load this beatmap sucessfully ({e})!", LoggingTarget.Runtime, LogLevel.Error); + Logger.Error(e, "Could not load beatmap sucessfully!"); //couldn't load, hard abort! Exit(); From 96e4518e606d2282820c7bbceb8057fc049df94c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 25 Dec 2017 18:22:58 +0900 Subject: [PATCH 21/49] Add thread safety --- osu.Game/OsuGame.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 95a7e696ea..750808a291 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -16,6 +16,7 @@ using osu.Game.Screens; using osu.Game.Screens.Menu; using OpenTK; using System.Linq; +using System.Threading; using System.Threading.Tasks; using osu.Framework.Input.Bindings; using osu.Framework.Platform; @@ -306,9 +307,9 @@ namespace osu.Game }); } - recentErrorCount++; + Interlocked.Increment(ref recentErrorCount); - Scheduler.AddDelayed(() => recentErrorCount--, debounce); + Scheduler.AddDelayed(() => Interlocked.Decrement(ref recentErrorCount), debounce); }; } From 40dd66cb974fe56d80cc7de451573a118e8afa6e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 25 Dec 2017 18:31:19 +0900 Subject: [PATCH 22/49] Make TestCaseNotificationOverlay dynamically testable --- osu.Game.Tests/Visual/TestCaseNotificationOverlay.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/osu.Game.Tests/Visual/TestCaseNotificationOverlay.cs b/osu.Game.Tests/Visual/TestCaseNotificationOverlay.cs index b93c2d812f..40d7a77c10 100644 --- a/osu.Game.Tests/Visual/TestCaseNotificationOverlay.cs +++ b/osu.Game.Tests/Visual/TestCaseNotificationOverlay.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 System; using System.Collections.Generic; using System.Linq; using osu.Framework.Graphics; @@ -15,6 +16,15 @@ namespace osu.Game.Tests.Visual private readonly NotificationOverlay manager; private readonly List progressingNotifications = new List(); + public override IReadOnlyList RequiredTypes => new[] + { + typeof(Notification), + typeof(ProgressNotification), + typeof(ProgressCompletionNotification), + typeof(SimpleNotification), + typeof(IHasCompletionTarget), + }; + public TestCaseNotificationOverlay() { progressingNotifications.Clear(); From 861bf55773a153a35cc68c190236851608377ec3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 25 Dec 2017 18:31:32 +0900 Subject: [PATCH 23/49] Adjust notification padding a touch --- osu.Game/Overlays/Notifications/Notification.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Notifications/Notification.cs b/osu.Game/Overlays/Notifications/Notification.cs index 422051364e..dc2dcf2d74 100644 --- a/osu.Game/Overlays/Notifications/Notification.cs +++ b/osu.Game/Overlays/Notifications/Notification.cs @@ -91,7 +91,6 @@ namespace osu.Game.Overlays.Notifications AutoSizeAxes = Axes.Y, Padding = new MarginPadding { - Top = 5, Left = 45, Right = 30 }, @@ -261,4 +260,4 @@ namespace osu.Game.Overlays.Notifications } } } -} \ No newline at end of file +} From f76878e2fea6b2e7fd23163cd9d42dc6211f623d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 26 Dec 2017 00:34:12 +0900 Subject: [PATCH 24/49] Add a very basic popup testcase --- osu.Game.Tests/Visual/TestCasePopupDialog.cs | 37 ++++++++++++++++++++ osu.Game.Tests/osu.Game.Tests.csproj | 1 + 2 files changed, 38 insertions(+) create mode 100644 osu.Game.Tests/Visual/TestCasePopupDialog.cs diff --git a/osu.Game.Tests/Visual/TestCasePopupDialog.cs b/osu.Game.Tests/Visual/TestCasePopupDialog.cs new file mode 100644 index 0000000000..ed9c47a253 --- /dev/null +++ b/osu.Game.Tests/Visual/TestCasePopupDialog.cs @@ -0,0 +1,37 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Graphics; +using osu.Game.Graphics; +using osu.Game.Overlays.Dialog; + +namespace osu.Game.Tests.Visual +{ + public class TestCasePopupDialog : OsuTestCase + { + public TestCasePopupDialog() + { + var popup = new PopupDialog + { + RelativeSizeAxes = Axes.Both, + State = Framework.Graphics.Containers.Visibility.Visible, + Icon = FontAwesome.fa_assistive_listening_systems, + HeaderText = @"This is a test popup", + BodyText = "I can say lots of stuff and even wrap my words!", + Buttons = new PopupDialogButton[] + { + new PopupDialogCancelButton + { + Text = @"Yes. That you can.", + }, + new PopupDialogOkButton + { + Text = @"You're a fake!", + }, + } + }; + + Add(popup); + } + } +} diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj index ff012bb6e2..134fc4a6ac 100644 --- a/osu.Game.Tests/osu.Game.Tests.csproj +++ b/osu.Game.Tests/osu.Game.Tests.csproj @@ -134,6 +134,7 @@ + From 929633efaa8ad611969e678a9cfe796d4014b86b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 26 Dec 2017 00:34:40 +0900 Subject: [PATCH 25/49] Make body text in popups word wrap properly --- osu.Game/Overlays/Dialog/PopupDialog.cs | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/osu.Game/Overlays/Dialog/PopupDialog.cs b/osu.Game/Overlays/Dialog/PopupDialog.cs index 9b19b8150e..d2bd50cad6 100644 --- a/osu.Game/Overlays/Dialog/PopupDialog.cs +++ b/osu.Game/Overlays/Dialog/PopupDialog.cs @@ -32,7 +32,7 @@ namespace osu.Game.Overlays.Dialog private readonly FillFlowContainer buttonsContainer; private readonly SpriteIcon icon; private readonly SpriteText header; - private readonly SpriteText body; + private readonly TextFlowContainer body; public FontAwesome Icon { @@ -48,7 +48,6 @@ namespace osu.Game.Overlays.Dialog public string BodyText { - get { return body.Text; } set { body.Text = value; } } @@ -220,17 +219,15 @@ namespace osu.Game.Overlays.Dialog { Origin = Anchor.TopCentre, Anchor = Anchor.TopCentre, - Text = @"Header", TextSize = 25, Shadow = true, }, - body = new OsuSpriteText + body = new OsuTextFlowContainer(t => t.TextSize = 18) { - Origin = Anchor.TopCentre, - Anchor = Anchor.TopCentre, - Text = @"Body", - TextSize = 18, - Shadow = true, + Padding = new MarginPadding(15), + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + TextAnchor = Anchor.TopCentre, }, }, }, From 3c1654e5e496d8c22927019ca9a90d0177045b58 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 26 Dec 2017 00:44:35 +0900 Subject: [PATCH 26/49] Fix many instances of non-osu-prefixed text classes being used Results in incorrect default formatting. --- osu.Game/Overlays/BeatmapSet/Info.cs | 3 ++- osu.Game/Overlays/MedalSplash/DrawableMedal.cs | 3 ++- osu.Game/Overlays/Notifications/ProgressNotification.cs | 3 ++- osu.Game/Overlays/Notifications/SimpleNotification.cs | 5 +++-- osu.Game/Overlays/OnScreenDisplay.cs | 7 ++++--- osu.Game/Overlays/Profile/ProfileHeader.cs | 2 +- osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs | 3 ++- osu.Game/Screens/Ranking/Results.cs | 9 +++++---- osu.Game/Screens/Ranking/ResultsPageScore.cs | 4 ++-- osu.Game/Screens/Select/BeatmapDetails.cs | 5 +++-- osu.Game/Tests/Visual/TestCasePerformancePoints.cs | 3 +-- osu.sln.DotSettings | 5 +++++ 12 files changed, 32 insertions(+), 20 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Info.cs b/osu.Game/Overlays/BeatmapSet/Info.cs index bd108a193b..b4aea898b2 100644 --- a/osu.Game/Overlays/BeatmapSet/Info.cs +++ b/osu.Game/Overlays/BeatmapSet/Info.cs @@ -8,6 +8,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps; using osu.Game.Graphics; +using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using OpenTK; using OpenTK.Graphics; @@ -176,7 +177,7 @@ namespace osu.Game.Overlays.BeatmapSet Shadow = false, Margin = new MarginPadding { Top = 20 }, }, - textFlow = new TextFlowContainer + textFlow = new OsuTextFlowContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, diff --git a/osu.Game/Overlays/MedalSplash/DrawableMedal.cs b/osu.Game/Overlays/MedalSplash/DrawableMedal.cs index 53d77dab6c..c6be428987 100644 --- a/osu.Game/Overlays/MedalSplash/DrawableMedal.cs +++ b/osu.Game/Overlays/MedalSplash/DrawableMedal.cs @@ -10,6 +10,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; using osu.Game.Graphics; +using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Users; @@ -88,7 +89,7 @@ namespace osu.Game.Overlays.MedalSplash Alpha = 0f, Scale = new Vector2(1f / scale_when_full), }, - description = new TextFlowContainer + description = new OsuTextFlowContainer { TextAnchor = Anchor.TopCentre, Anchor = Anchor.TopCentre, diff --git a/osu.Game/Overlays/Notifications/ProgressNotification.cs b/osu.Game/Overlays/Notifications/ProgressNotification.cs index 12c7fe64ba..9211c227f8 100644 --- a/osu.Game/Overlays/Notifications/ProgressNotification.cs +++ b/osu.Game/Overlays/Notifications/ProgressNotification.cs @@ -7,6 +7,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; +using osu.Game.Graphics.Containers; using OpenTK; using OpenTK.Graphics; @@ -114,7 +115,7 @@ namespace osu.Game.Overlays.Notifications RelativeSizeAxes = Axes.Both, }); - Content.Add(textDrawable = new TextFlowContainer(t => + Content.Add(textDrawable = new OsuTextFlowContainer(t => { t.TextSize = 16; }) diff --git a/osu.Game/Overlays/Notifications/SimpleNotification.cs b/osu.Game/Overlays/Notifications/SimpleNotification.cs index daf1ac838d..0b8b365c48 100644 --- a/osu.Game/Overlays/Notifications/SimpleNotification.cs +++ b/osu.Game/Overlays/Notifications/SimpleNotification.cs @@ -7,6 +7,7 @@ using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; +using osu.Game.Graphics.Containers; using OpenTK; namespace osu.Game.Overlays.Notifications @@ -58,7 +59,7 @@ namespace osu.Game.Overlays.Notifications } }); - Content.Add(textDrawable = new TextFlowContainer(t => t.TextSize = 16) + Content.Add(textDrawable = new OsuTextFlowContainer(t => t.TextSize = 16) { Colour = OsuColour.Gray(128), AutoSizeAxes = Axes.Y, @@ -87,4 +88,4 @@ namespace osu.Game.Overlays.Notifications } } } -} \ No newline at end of file +} diff --git a/osu.Game/Overlays/OnScreenDisplay.cs b/osu.Game/Overlays/OnScreenDisplay.cs index dcab942522..ce0feeb4c6 100644 --- a/osu.Game/Overlays/OnScreenDisplay.cs +++ b/osu.Game/Overlays/OnScreenDisplay.cs @@ -14,6 +14,7 @@ using osu.Game.Graphics; using OpenTK; using OpenTK.Graphics; using osu.Framework.Extensions.Color4Extensions; +using osu.Game.Graphics.Sprites; namespace osu.Game.Overlays { @@ -63,7 +64,7 @@ namespace osu.Game.Overlays Width = 240, RelativeSizeAxes = Axes.Y, }, - textLine1 = new SpriteText + textLine1 = new OsuSpriteText { Padding = new MarginPadding(10), Font = @"Exo2.0-Black", @@ -72,7 +73,7 @@ namespace osu.Game.Overlays Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, }, - textLine2 = new SpriteText + textLine2 = new OsuSpriteText { TextSize = 24, Font = @"Exo2.0-Light", @@ -97,7 +98,7 @@ namespace osu.Game.Overlays Origin = Anchor.TopCentre, AutoSizeAxes = Axes.Both }, - textLine3 = new SpriteText + textLine3 = new OsuSpriteText { Padding = new MarginPadding { Bottom = 15 }, Font = @"Exo2.0-Bold", diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index a706799664..4cdb6ec958 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -473,7 +473,7 @@ namespace osu.Game.Overlays.Profile Width = width, Height = 26 }); - Add(numberText = new SpriteText + Add(numberText = new OsuSpriteText { Anchor = Anchor.BottomCentre, Origin = Anchor.BottomCentre, diff --git a/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs b/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs index 8a835634b8..904ed609e8 100644 --- a/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs +++ b/osu.Game/Overlays/Profile/Sections/Kudosu/KudosuInfo.cs @@ -10,6 +10,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Input; using osu.Game.Graphics; +using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; using osu.Game.Users; @@ -120,7 +121,7 @@ namespace osu.Game.Overlays.Profile.Sections.Kudosu } } }, - new TextFlowContainer(t => { t.TextSize = 19; }) + new OsuTextFlowContainer(t => { t.TextSize = 19; }) { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, diff --git a/osu.Game/Screens/Ranking/Results.cs b/osu.Game/Screens/Ranking/Results.cs index 8e27cb235c..406887624c 100644 --- a/osu.Game/Screens/Ranking/Results.cs +++ b/osu.Game/Screens/Ranking/Results.cs @@ -17,6 +17,7 @@ using OpenTK.Graphics; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics.Sprites; namespace osu.Game.Screens.Ranking { @@ -183,7 +184,7 @@ namespace osu.Game.Screens.Ranking Height = 50, Margin = new MarginPadding { Bottom = 110 }, }, - new SpriteText + new OsuSpriteText { Text = $"{score.MaxCombo}x", TextSize = 40, @@ -194,7 +195,7 @@ namespace osu.Game.Screens.Ranking Anchor = Anchor.CentreLeft, Origin = Anchor.BottomCentre, }, - new SpriteText + new OsuSpriteText { Text = "max combo", TextSize = 20, @@ -204,7 +205,7 @@ namespace osu.Game.Screens.Ranking Anchor = Anchor.CentreLeft, Origin = Anchor.TopCentre, }, - new SpriteText + new OsuSpriteText { Text = $"{score.Accuracy:P2}", TextSize = 40, @@ -215,7 +216,7 @@ namespace osu.Game.Screens.Ranking Anchor = Anchor.CentreLeft, Origin = Anchor.BottomCentre, }, - new SpriteText + new OsuSpriteText { Text = "accuracy", TextSize = 20, diff --git a/osu.Game/Screens/Ranking/ResultsPageScore.cs b/osu.Game/Screens/Ranking/ResultsPageScore.cs index 911b688669..4c776aa7ab 100644 --- a/osu.Game/Screens/Ranking/ResultsPageScore.cs +++ b/osu.Game/Screens/Ranking/ResultsPageScore.cs @@ -201,14 +201,14 @@ namespace osu.Game.Screens.Ranking { Children = new Drawable[] { - new SpriteText { + new OsuSpriteText { Text = statistic.Value.ToString().PadLeft(4, '0'), Colour = colours.Gray7, TextSize = 30, Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, }, - new SpriteText { + new OsuSpriteText { Text = statistic.Key, Colour = colours.Gray7, Font = @"Exo2.0-Bold", diff --git a/osu.Game/Screens/Select/BeatmapDetails.cs b/osu.Game/Screens/Select/BeatmapDetails.cs index a9a778fe17..79d76dd00e 100644 --- a/osu.Game/Screens/Select/BeatmapDetails.cs +++ b/osu.Game/Screens/Select/BeatmapDetails.cs @@ -17,6 +17,7 @@ using osu.Framework.Graphics.Shapes; using osu.Framework.Extensions.Color4Extensions; using osu.Game.Screens.Select.Details; using osu.Game.Beatmaps; +using osu.Game.Graphics.Containers; namespace osu.Game.Screens.Select { @@ -334,7 +335,7 @@ namespace osu.Game.Screens.Select TextSize = 14, }, }, - textFlow = new TextFlowContainer + textFlow = new OsuTextFlowContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, @@ -359,7 +360,7 @@ namespace osu.Game.Screens.Select private void setTextAsync(string text) { - LoadComponentAsync(new TextFlowContainer(s => s.TextSize = 14) + LoadComponentAsync(new OsuTextFlowContainer(s => s.TextSize = 14) { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, diff --git a/osu.Game/Tests/Visual/TestCasePerformancePoints.cs b/osu.Game/Tests/Visual/TestCasePerformancePoints.cs index f71bece279..8984fc843f 100644 --- a/osu.Game/Tests/Visual/TestCasePerformancePoints.cs +++ b/osu.Game/Tests/Visual/TestCasePerformancePoints.cs @@ -12,7 +12,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Sprites; using osu.Framework.Input; using osu.Game.Beatmaps; using osu.Game.Graphics.Sprites; @@ -224,7 +223,7 @@ namespace osu.Game.Tests.Visual if (!api.IsLoggedIn) { - InternalChild = new SpriteText + InternalChild = new OsuSpriteText { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, diff --git a/osu.sln.DotSettings b/osu.sln.DotSettings index 2f52881d6d..20007e3306 100644 --- a/osu.sln.DotSettings +++ b/osu.sln.DotSettings @@ -172,6 +172,7 @@ NEXT_LINE NEXT_LINE True + NEVER False False True @@ -655,7 +656,11 @@ Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-frame <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> True + True + True + True True True + True True True From 3c8d30f8e67158ce5b105ce28eff9b726aa09093 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 26 Dec 2017 00:37:50 +0900 Subject: [PATCH 27/49] Add a dialog offering to import beatmaps from stable --- osu.Game/Beatmaps/BeatmapManager.cs | 6 ++-- .../Sections/Maintenance/GeneralSettings.cs | 3 +- .../Screens/Select/ImportFromStablePopup.cs | 33 +++++++++++++++++++ osu.Game/Screens/Select/PlaySongSelect.cs | 15 +++++++-- osu.Game/osu.Game.csproj | 1 + 5 files changed, 52 insertions(+), 6 deletions(-) create mode 100644 osu.Game/Screens/Select/ImportFromStablePopup.cs diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 0325785016..c86860f7b0 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -697,10 +697,12 @@ namespace osu.Game.Beatmaps } } + public bool StableInstallationAvailable => GetStableStorage?.Invoke() != null; + /// /// This is a temporary method and will likely be replaced by a full-fledged (and more correctly placed) migration process in the future. /// - public void ImportFromStable() + public async Task ImportFromStable() { var stable = GetStableStorage?.Invoke(); @@ -710,7 +712,7 @@ namespace osu.Game.Beatmaps return; } - Import(stable.GetDirectories("Songs")); + await Task.Factory.StartNew(() => Import(stable.GetDirectories("Songs")), TaskCreationOptions.LongRunning); } public void DeleteAll() diff --git a/osu.Game/Overlays/Settings/Sections/Maintenance/GeneralSettings.cs b/osu.Game/Overlays/Settings/Sections/Maintenance/GeneralSettings.cs index e288445c6d..9ab4143613 100644 --- a/osu.Game/Overlays/Settings/Sections/Maintenance/GeneralSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Maintenance/GeneralSettings.cs @@ -30,8 +30,7 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance Action = () => { importButton.Enabled.Value = false; - Task.Factory.StartNew(beatmaps.ImportFromStable) - .ContinueWith(t => Schedule(() => importButton.Enabled.Value = true), TaskContinuationOptions.LongRunning); + beatmaps.ImportFromStable().ContinueWith(t => Schedule(() => importButton.Enabled.Value = true)); } }, deleteButton = new DangerousSettingsButton diff --git a/osu.Game/Screens/Select/ImportFromStablePopup.cs b/osu.Game/Screens/Select/ImportFromStablePopup.cs new file mode 100644 index 0000000000..489ab79fa4 --- /dev/null +++ b/osu.Game/Screens/Select/ImportFromStablePopup.cs @@ -0,0 +1,33 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using osu.Game.Graphics; +using osu.Game.Overlays.Dialog; + +namespace osu.Game.Screens.Select +{ + public class ImportFromStablePopup : PopupDialog + { + public ImportFromStablePopup(Action importFromStable) + { + HeaderText = @"You have no beatmaps!"; + BodyText = "An existing copy of osu! was found, though.\nWould you like to import your beatmaps?"; + + Icon = FontAwesome.fa_trash_o; + + Buttons = new PopupDialogButton[] + { + new PopupDialogOkButton + { + Text = @"Yes please!", + Action = importFromStable + }, + new PopupDialogCancelButton + { + Text = @"No, I'd like to start from scratch", + }, + }; + } + } +} diff --git a/osu.Game/Screens/Select/PlaySongSelect.cs b/osu.Game/Screens/Select/PlaySongSelect.cs index 4a0ee31fbb..727cdb9959 100644 --- a/osu.Game/Screens/Select/PlaySongSelect.cs +++ b/osu.Game/Screens/Select/PlaySongSelect.cs @@ -11,6 +11,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Screens; using osu.Game.Beatmaps; using osu.Game.Graphics; +using osu.Game.Overlays; using osu.Game.Overlays.Mods; using osu.Game.Screens.Edit; using osu.Game.Screens.Play; @@ -45,8 +46,8 @@ namespace osu.Game.Screens.Select private SampleChannel sampleConfirm; - [BackgroundDependencyLoader] - private void load(OsuColour colours, AudioManager audio) + [BackgroundDependencyLoader(true)] + private void load(OsuColour colours, AudioManager audio, BeatmapManager beatmaps, DialogOverlay dialogOverlay) { sampleConfirm = audio.Sample.Get(@"SongSelect/confirm-selection"); @@ -59,6 +60,16 @@ namespace osu.Game.Screens.Select ValidForResume = false; Push(new Editor()); }, Key.Number3); + + if (dialogOverlay != null) + { + Schedule(() => + { + // if we have no beatmaps but osu-stable is found, let's prompt the user to import. + if (!beatmaps.GetAllUsableBeatmapSets().Any() && beatmaps.StableInstallationAvailable) + dialogOverlay.Push(new ImportFromStablePopup(() => beatmaps.ImportFromStable())); + }); + } } protected override void UpdateBeatmap(WorkingBeatmap beatmap) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 94678106bf..fa25fa7048 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -310,6 +310,7 @@ + From dff082ed940ad1cd93e0a52f62bd8dd46a5546f6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 26 Dec 2017 01:12:46 +0900 Subject: [PATCH 28/49] Make toolbar testable and add the most basic of visual tests --- osu.Game.Tests/Visual/TestCaseToolbar.cs | 25 +++++++++++++++++++ osu.Game.Tests/osu.Game.Tests.csproj | 1 + .../Overlays/Toolbar/ToolbarChatButton.cs | 2 +- .../Overlays/Toolbar/ToolbarDirectButton.cs | 2 +- .../Overlays/Toolbar/ToolbarModeSelector.cs | 7 ++++-- .../Overlays/Toolbar/ToolbarMusicButton.cs | 2 +- .../Toolbar/ToolbarNotificationButton.cs | 2 +- .../Toolbar/ToolbarOverlayToggleButton.cs | 7 ++++-- .../Overlays/Toolbar/ToolbarSettingsButton.cs | 2 +- .../Overlays/Toolbar/ToolbarSocialButton.cs | 2 +- 10 files changed, 42 insertions(+), 10 deletions(-) create mode 100644 osu.Game.Tests/Visual/TestCaseToolbar.cs diff --git a/osu.Game.Tests/Visual/TestCaseToolbar.cs b/osu.Game.Tests/Visual/TestCaseToolbar.cs new file mode 100644 index 0000000000..9045249b9a --- /dev/null +++ b/osu.Game.Tests/Visual/TestCaseToolbar.cs @@ -0,0 +1,25 @@ +// 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 osu.Framework.Graphics.Containers; +using osu.Game.Overlays.Toolbar; + +namespace osu.Game.Tests.Visual +{ + public class TestCaseToolbar : OsuTestCase + { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(ToolbarButton), + typeof(ToolbarModeSelector), + typeof(ToolbarModeButton), + }; + + public TestCaseToolbar() + { + Add(new Toolbar { State = Visibility.Visible }); + } + } +} diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj index ff012bb6e2..71703d264a 100644 --- a/osu.Game.Tests/osu.Game.Tests.csproj +++ b/osu.Game.Tests/osu.Game.Tests.csproj @@ -148,6 +148,7 @@ + diff --git a/osu.Game/Overlays/Toolbar/ToolbarChatButton.cs b/osu.Game/Overlays/Toolbar/ToolbarChatButton.cs index ed206e7e1d..b0171feb30 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarChatButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarChatButton.cs @@ -13,7 +13,7 @@ namespace osu.Game.Overlays.Toolbar SetIcon(FontAwesome.fa_comments); } - [BackgroundDependencyLoader] + [BackgroundDependencyLoader(true)] private void load(ChatOverlay chat) { StateContainer = chat; diff --git a/osu.Game/Overlays/Toolbar/ToolbarDirectButton.cs b/osu.Game/Overlays/Toolbar/ToolbarDirectButton.cs index 7d25440e2c..5c64ae69ec 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarDirectButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarDirectButton.cs @@ -13,7 +13,7 @@ namespace osu.Game.Overlays.Toolbar SetIcon(FontAwesome.fa_osu_chevron_down_o); } - [BackgroundDependencyLoader] + [BackgroundDependencyLoader(true)] private void load(DirectOverlay direct) { StateContainer = direct; diff --git a/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs b/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs index 319dd63bc9..f38c772890 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarModeSelector.cs @@ -64,7 +64,7 @@ namespace osu.Game.Overlays.Toolbar }; } - [BackgroundDependencyLoader] + [BackgroundDependencyLoader(true)] private void load(RulesetStore rulesets, OsuGame game) { foreach (var r in rulesets.AvailableRulesets) @@ -81,7 +81,10 @@ namespace osu.Game.Overlays.Toolbar ruleset.ValueChanged += rulesetChanged; ruleset.DisabledChanged += disabledChanged; - ruleset.BindTo(game.Ruleset); + if (game != null) + ruleset.BindTo(game.Ruleset); + else + ruleset.Value = rulesets.AvailableRulesets.FirstOrDefault(); } public override bool HandleInput => !ruleset.Disabled; diff --git a/osu.Game/Overlays/Toolbar/ToolbarMusicButton.cs b/osu.Game/Overlays/Toolbar/ToolbarMusicButton.cs index d150aacdf9..81c57a984f 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarMusicButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarMusicButton.cs @@ -13,7 +13,7 @@ namespace osu.Game.Overlays.Toolbar Icon = FontAwesome.fa_music; } - [BackgroundDependencyLoader] + [BackgroundDependencyLoader(true)] private void load(MusicController music) { StateContainer = music; diff --git a/osu.Game/Overlays/Toolbar/ToolbarNotificationButton.cs b/osu.Game/Overlays/Toolbar/ToolbarNotificationButton.cs index e11a22d675..dbe8b48424 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarNotificationButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarNotificationButton.cs @@ -18,7 +18,7 @@ namespace osu.Game.Overlays.Toolbar TooltipSub = "Waiting for 'ya"; } - [BackgroundDependencyLoader] + [BackgroundDependencyLoader(true)] private void load(NotificationOverlay notificationOverlay) { StateContainer = notificationOverlay; diff --git a/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs b/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs index 69fdd27d5d..59314b8771 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarOverlayToggleButton.cs @@ -21,8 +21,11 @@ namespace osu.Game.Overlays.Toolbar set { stateContainer = value; - Action = stateContainer.ToggleVisibility; - stateContainer.StateChanged += stateChanged; + if (stateContainer != null) + { + Action = stateContainer.ToggleVisibility; + stateContainer.StateChanged += stateChanged; + } } } diff --git a/osu.Game/Overlays/Toolbar/ToolbarSettingsButton.cs b/osu.Game/Overlays/Toolbar/ToolbarSettingsButton.cs index cf4f664e81..d0d76dd5d2 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarSettingsButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarSettingsButton.cs @@ -15,7 +15,7 @@ namespace osu.Game.Overlays.Toolbar TooltipSub = "Change your settings"; } - [BackgroundDependencyLoader] + [BackgroundDependencyLoader(true)] private void load(SettingsOverlay settings) { StateContainer = settings; diff --git a/osu.Game/Overlays/Toolbar/ToolbarSocialButton.cs b/osu.Game/Overlays/Toolbar/ToolbarSocialButton.cs index 234d6f0f9a..74d1da4384 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarSocialButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarSocialButton.cs @@ -13,7 +13,7 @@ namespace osu.Game.Overlays.Toolbar Icon = FontAwesome.fa_users; } - [BackgroundDependencyLoader] + [BackgroundDependencyLoader(true)] private void load(SocialOverlay chat) { StateContainer = chat; From bb33d0211a5802c6706c3a18570cbc16ffa4c227 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 26 Dec 2017 01:36:58 +0900 Subject: [PATCH 29/49] Add a count of unread notifications to the toolbar --- osu.Game.Tests/Visual/TestCaseToolbar.cs | 16 ++++- .../Toolbar/ToolbarNotificationButton.cs | 64 +++++++++++++++++++ 2 files changed, 79 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/TestCaseToolbar.cs b/osu.Game.Tests/Visual/TestCaseToolbar.cs index 9045249b9a..9f538af09b 100644 --- a/osu.Game.Tests/Visual/TestCaseToolbar.cs +++ b/osu.Game.Tests/Visual/TestCaseToolbar.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Linq; using osu.Framework.Graphics.Containers; using osu.Game.Overlays.Toolbar; @@ -15,11 +16,24 @@ namespace osu.Game.Tests.Visual typeof(ToolbarButton), typeof(ToolbarModeSelector), typeof(ToolbarModeButton), + typeof(ToolbarNotificationButton), }; public TestCaseToolbar() { - Add(new Toolbar { State = Visibility.Visible }); + var toolbar = new Toolbar { State = Visibility.Visible }; + + Add(toolbar); + + var notificationButton = toolbar.Children.OfType().Last().Children.OfType().First(); + + void setNotifications(int count) => AddStep($"set notification count to {count}", () => notificationButton.NotificationCount.Value = count); + + setNotifications(1); + setNotifications(2); + setNotifications(3); + setNotifications(0); + setNotifications(144); } } } diff --git a/osu.Game/Overlays/Toolbar/ToolbarNotificationButton.cs b/osu.Game/Overlays/Toolbar/ToolbarNotificationButton.cs index dbe8b48424..78a04d156a 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarNotificationButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarNotificationButton.cs @@ -2,8 +2,14 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Framework.Allocation; +using osu.Framework.Configuration; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using OpenTK; +using OpenTK.Graphics; namespace osu.Game.Overlays.Toolbar { @@ -11,17 +17,75 @@ namespace osu.Game.Overlays.Toolbar { protected override Anchor TooltipAnchor => Anchor.TopRight; + public BindableInt NotificationCount = new BindableInt(); + + private CountCircle countDisplay; + public ToolbarNotificationButton() { Icon = FontAwesome.fa_bars; TooltipMain = "Notifications"; TooltipSub = "Waiting for 'ya"; + + Add(countDisplay = new CountCircle + { + Alpha = 0, + Height = 16, + RelativePositionAxes = Axes.Both, + Origin = Anchor.TopCentre, + Position = new Vector2(0.7f, 0.05f), + }); } [BackgroundDependencyLoader(true)] private void load(NotificationOverlay notificationOverlay) { StateContainer = notificationOverlay; + + NotificationCount.ValueChanged += count => + { + if (count == 0) + countDisplay.FadeOut(200, Easing.OutQuint); + else + countDisplay.FadeIn(200, Easing.OutQuint); + + countDisplay.Count = count; + }; + } + + private class CountCircle : CompositeDrawable + { + private readonly OsuSpriteText count; + + public int Count + { + set { count.Text = value.ToString("#,0"); } + } + + public CountCircle() + { + AutoSizeAxes = Axes.X; + + InternalChildren = new Drawable[] + { + new Circle + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Red + }, + count = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Y = -1, + TextSize = 14, + Padding = new MarginPadding(5), + Colour = Color4.White, + UseFullGlyphHeight = true, + Font = "Exo2.0-Bold", + } + }; + } } } } From 1fc240f6c594ad7f1469f4276a0778034c59bb2e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 26 Dec 2017 01:50:05 +0900 Subject: [PATCH 30/49] Expose unread notification count --- .../Visual/TestCaseNotificationOverlay.cs | 7 ++++ osu.Game/Overlays/NotificationOverlay.cs | 42 ++++++++++++------- .../Notifications/NotificationSection.cs | 4 +- 3 files changed, 37 insertions(+), 16 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseNotificationOverlay.cs b/osu.Game.Tests/Visual/TestCaseNotificationOverlay.cs index b93c2d812f..233914767d 100644 --- a/osu.Game.Tests/Visual/TestCaseNotificationOverlay.cs +++ b/osu.Game.Tests/Visual/TestCaseNotificationOverlay.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Linq; using osu.Framework.Graphics; +using osu.Framework.Graphics.Sprites; using osu.Framework.MathUtils; using osu.Game.Overlays; using osu.Game.Overlays.Notifications; @@ -25,6 +26,12 @@ namespace osu.Game.Tests.Visual Origin = Anchor.TopRight }); + SpriteText displayedCount = new SpriteText(); + + Content.Add(displayedCount); + + manager.UnreadCount.ValueChanged += count => { displayedCount.Text = $"displayed count: {count}"; }; + AddStep(@"toggle", manager.ToggleVisibility); AddStep(@"simple #1", sendHelloNotification); AddStep(@"simple #2", sendAmazingNotification); diff --git a/osu.Game/Overlays/NotificationOverlay.cs b/osu.Game/Overlays/NotificationOverlay.cs index a4b5486596..2f1c3285ef 100644 --- a/osu.Game/Overlays/NotificationOverlay.cs +++ b/osu.Game/Overlays/NotificationOverlay.cs @@ -11,6 +11,7 @@ using OpenTK.Graphics; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics.Containers; using System; +using osu.Framework.Configuration; namespace osu.Game.Overlays { @@ -75,34 +76,38 @@ namespace osu.Game.Overlays }; } + private int totalCount => sections.Select(c => c.DisplayedCount).Sum(); + private int unreadCount => sections.Select(c => c.UnreadCount).Sum(); + + public readonly BindableInt UnreadCount = new BindableInt(); + private int runningDepth; private void notificationClosed() { // hide ourselves if all notifications have been dismissed. - if (sections.Select(c => c.DisplayedCount).Sum() == 0) + if (totalCount == 0) State = Visibility.Hidden; + + updateCounts(); } - public void Post(Notification notification) + public void Post(Notification notification) => Schedule(() => { - Schedule(() => - { - State = Visibility.Visible; + ++runningDepth; + notification.Depth = notification.DisplayOnTop ? runningDepth : -runningDepth; - ++runningDepth; - notification.Depth = notification.DisplayOnTop ? runningDepth : -runningDepth; + notification.Closed += notificationClosed; - notification.Closed += notificationClosed; + var hasCompletionTarget = notification as IHasCompletionTarget; + if (hasCompletionTarget != null) + hasCompletionTarget.CompletionTarget = Post; - var hasCompletionTarget = notification as IHasCompletionTarget; - if (hasCompletionTarget != null) - hasCompletionTarget.CompletionTarget = Post; + var ourType = notification.GetType(); + sections.Children.FirstOrDefault(s => s.AcceptTypes.Any(accept => accept.IsAssignableFrom(ourType)))?.Add(notification); - var ourType = notification.GetType(); - sections.Children.FirstOrDefault(s => s.AcceptTypes.Any(accept => accept.IsAssignableFrom(ourType)))?.Add(notification); - }); - } + updateCounts(); + }); protected override void PopIn() { @@ -122,9 +127,16 @@ namespace osu.Game.Overlays this.FadeTo(0, TRANSITION_LENGTH, Easing.OutQuint); } + private void updateCounts() + { + UnreadCount.Value = unreadCount; + } + private void markAllRead() { sections.Children.ForEach(s => s.MarkAllRead()); + + updateCounts(); } protected override void UpdateAfterChildren() diff --git a/osu.Game/Overlays/Notifications/NotificationSection.cs b/osu.Game/Overlays/Notifications/NotificationSection.cs index 09768ba0ea..2bd0321d12 100644 --- a/osu.Game/Overlays/Notifications/NotificationSection.cs +++ b/osu.Game/Overlays/Notifications/NotificationSection.cs @@ -26,6 +26,8 @@ namespace osu.Game.Overlays.Notifications public int DisplayedCount => notifications.Count(n => !n.WasClosed); + public int UnreadCount => notifications.Count(n => !n.WasClosed && !n.Read); + public void Add(Notification notification) => notifications.Add(notification); public IEnumerable AcceptTypes; @@ -157,4 +159,4 @@ namespace osu.Game.Overlays.Notifications notifications?.Children.ForEach(n => n.Read = true); } } -} \ No newline at end of file +} From 0886107ec911c79d6d3f25317b31c0586ddc0ba2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 26 Dec 2017 01:56:57 +0900 Subject: [PATCH 31/49] Connect counter with button display --- .../Toolbar/ToolbarNotificationButton.cs | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/osu.Game/Overlays/Toolbar/ToolbarNotificationButton.cs b/osu.Game/Overlays/Toolbar/ToolbarNotificationButton.cs index 78a04d156a..faf802f5e7 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarNotificationButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarNotificationButton.cs @@ -19,7 +19,7 @@ namespace osu.Game.Overlays.Toolbar public BindableInt NotificationCount = new BindableInt(); - private CountCircle countDisplay; + private readonly CountCircle countDisplay; public ToolbarNotificationButton() { @@ -32,8 +32,8 @@ namespace osu.Game.Overlays.Toolbar Alpha = 0, Height = 16, RelativePositionAxes = Axes.Both, - Origin = Anchor.TopCentre, - Position = new Vector2(0.7f, 0.05f), + Origin = Anchor.Centre, + Position = new Vector2(0.7f, 0.25f), }); } @@ -42,24 +42,34 @@ namespace osu.Game.Overlays.Toolbar { StateContainer = notificationOverlay; + if (notificationOverlay != null) + NotificationCount.BindTo(notificationOverlay.UnreadCount); + NotificationCount.ValueChanged += count => { if (count == 0) countDisplay.FadeOut(200, Easing.OutQuint); else + { + countDisplay.Count = count; countDisplay.FadeIn(200, Easing.OutQuint); - - countDisplay.Count = count; + } }; } private class CountCircle : CompositeDrawable { private readonly OsuSpriteText count; + private readonly Circle circle; public int Count { - set { count.Text = value.ToString("#,0"); } + set + { + count.Text = value.ToString("#,0"); + circle.FlashColour(Color4.White, 600, Easing.OutQuint); + this.ScaleTo(1.1f).Then().ScaleTo(1, 600, Easing.OutElastic); + } } public CountCircle() @@ -68,7 +78,7 @@ namespace osu.Game.Overlays.Toolbar InternalChildren = new Drawable[] { - new Circle + circle = new Circle { RelativeSizeAxes = Axes.Both, Colour = Color4.Red From 798c2c66667cdb7f5b2c54d59731d3ae71486894 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 25 Dec 2017 12:57:45 +0900 Subject: [PATCH 32/49] Add special logic to song select to avoid obvious clipping when notifications are displayed Not sure if we will keep this going forward (there will likely be an opaque tab control on the notifications overlay similar to options) but let's go with this for now. --- osu.Game/Screens/Select/FilterControl.cs | 4 +- osu.Game/Screens/Select/SongSelect.cs | 48 +++++++++++++++++------- 2 files changed, 37 insertions(+), 15 deletions(-) diff --git a/osu.Game/Screens/Select/FilterControl.cs b/osu.Game/Screens/Select/FilterControl.cs index 1b86cec613..2dbd63f77b 100644 --- a/osu.Game/Screens/Select/FilterControl.cs +++ b/osu.Game/Screens/Select/FilterControl.cs @@ -75,7 +75,7 @@ namespace osu.Game.Screens.Select { Children = new Drawable[] { - new Box + Background = new Box { Colour = Color4.Black, Alpha = 0.8f, @@ -167,6 +167,8 @@ namespace osu.Game.Screens.Select private Bindable showConverted; + public readonly Box Background; + [BackgroundDependencyLoader(permitNulls: true)] private void load(OsuColour colours, OsuGame osu, OsuConfigManager config) { diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 68ee08e721..8189624ce1 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -103,21 +103,41 @@ namespace osu.Game.Screens.Select Right = left_area_padding * 2, } }, - carousel = new BeatmapCarousel + new Container { - RelativeSizeAxes = Axes.Y, - Size = new Vector2(carousel_width, 1), - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - SelectionChanged = carouselSelectionChanged, - BeatmapSetsChanged = carouselBeatmapsLoaded, - }, - FilterControl = new FilterControl - { - RelativeSizeAxes = Axes.X, - Height = filter_height, - FilterChanged = c => carousel.Filter(c), - Exit = Exit, + RelativeSizeAxes = Axes.Both, + Masking = true, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Width = 2, //avoid horizontal masking so the panels don't clip when screen stack is pushed. + Child = new Container + { + RelativeSizeAxes = Axes.Both, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Width = 0.5f, + Children = new Drawable[] + { + carousel = new BeatmapCarousel + { + Masking = false, + RelativeSizeAxes = Axes.Y, + Size = new Vector2(carousel_width, 1), + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + SelectionChanged = carouselSelectionChanged, + BeatmapSetsChanged = carouselBeatmapsLoaded, + }, + FilterControl = new FilterControl + { + RelativeSizeAxes = Axes.X, + Height = filter_height, + FilterChanged = c => carousel.Filter(c), + Background = { Width = 2 }, + Exit = Exit, + }, + } + }, }, beatmapInfoWedge = new BeatmapInfoWedge { From 14162b5d46a56f4f8da0e01829c25c67c331b1e9 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 26 Dec 2017 14:18:23 +0900 Subject: [PATCH 33/49] Make InputDrum handle all Normals/Claps, hitobjects all others --- .../Audio/DrumSampleMapping.cs | 47 +++++++++++-------- .../Objects/Drawables/DrawableSwell.cs | 19 -------- .../Drawables/DrawableTaikoHitObject.cs | 7 +++ osu.Game.Rulesets.Taiko/Objects/Swell.cs | 13 ----- osu.Game.Rulesets.Taiko/UI/InputDrum.cs | 36 ++++++++++++-- osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 38 ++------------- .../Objects/Drawables/DrawableHitObject.cs | 6 ++- 7 files changed, 72 insertions(+), 94 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Audio/DrumSampleMapping.cs b/osu.Game.Rulesets.Taiko/Audio/DrumSampleMapping.cs index 25fa9951df..9d0037b97a 100644 --- a/osu.Game.Rulesets.Taiko/Audio/DrumSampleMapping.cs +++ b/osu.Game.Rulesets.Taiko/Audio/DrumSampleMapping.cs @@ -1,7 +1,8 @@ // 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 osu.Framework.Audio; using osu.Framework.Audio.Sample; using osu.Game.Audio; @@ -9,32 +10,38 @@ using osu.Game.Beatmaps.ControlPoints; namespace osu.Game.Rulesets.Taiko.Audio { - public class DrumSampleMapping : IComparable + public class DrumSampleMapping { - public double Time; - public readonly SampleInfo Centre; - public readonly SampleInfo Rim; + private readonly ControlPointInfo controlPoints; + private readonly Dictionary mappings = new Dictionary(); - public SampleChannel CentreChannel { get; private set; } - public SampleChannel RimChannel { get; private set; } - - public DrumSampleMapping() + public DrumSampleMapping(ControlPointInfo controlPoints, AudioManager audio) { + this.controlPoints = controlPoints; + + IEnumerable samplePoints; + if (controlPoints.SamplePoints.Count == 0) + // Get the default sample point + samplePoints = new[] { controlPoints.SamplePointAt(double.MinValue) }; + else + samplePoints = controlPoints.SamplePoints; + + foreach (var s in samplePoints.Distinct()) + { + mappings[s] = new DrumSample + { + Centre = s.GetSampleInfo().GetChannel(audio.Sample), + Rim = s.GetSampleInfo(SampleInfo.HIT_CLAP).GetChannel(audio.Sample) + }; + } } - public DrumSampleMapping(SampleControlPoint samplePoint) - { - Time = samplePoint.Time; - Centre = samplePoint.GetSampleInfo(); - Rim = samplePoint.GetSampleInfo(SampleInfo.HIT_CLAP); - } + public DrumSample SampleAt(double time) => mappings[controlPoints.SamplePointAt(time)]; - public void RetrieveChannels(AudioManager audio) + public class DrumSample { - CentreChannel = Centre.GetChannel(audio.Sample); - RimChannel = Rim.GetChannel(audio.Sample); + public SampleChannel Centre; + public SampleChannel Rim; } - - public int CompareTo(DrumSampleMapping other) => Time.CompareTo(other.Time); } } diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs index 5131572abd..3099c6984c 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs @@ -123,9 +123,6 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables MainPiece.AccentColour = colours.YellowDark; expandingRing.Colour = colours.YellowLight; targetRing.BorderColour = colours.YellowDark.Opacity(0.25f); - - foreach (var mapping in HitObject.ProgressionSamples) - mapping.RetrieveChannels(audio); } protected override void LoadComplete() @@ -223,22 +220,6 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables UpdateJudgement(true); - if (AllJudged) - return true; - - // While the swell hasn't been fully judged, input is still blocked so it doesn't fall through to other hitobjects - // This causes the playfield to not play sounds, so they need to be handled locally - - var mappingIndex = HitObject.ProgressionSamples.BinarySearch(new DrumSampleMapping { Time = Time.Current }); - if (mappingIndex < 0) - mappingIndex = ~mappingIndex - 1; - - var mapping = HitObject.ProgressionSamples[mappingIndex]; - if (isCentre) - mapping.CentreChannel.Play(); - else - mapping.RimChannel.Play(); - return true; } } diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs index 7976cbbbc1..cf0df260b1 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs @@ -6,6 +6,10 @@ using osu.Framework.Input.Bindings; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces; using OpenTK; +using System; +using System.Linq; +using osu.Game.Audio; +using System.Collections.Generic; namespace osu.Game.Rulesets.Taiko.Objects.Drawables { @@ -35,6 +39,9 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables MainPiece.KiaiMode = HitObject.Kiai; } + // Normal and clap samples are handled by the drum + protected override IEnumerable GetSamples() => HitObject.Samples.Where(s => s.Name != SampleInfo.HIT_NORMAL && s.Name != SampleInfo.HIT_CLAP); + protected virtual TaikoPiece CreateMainPiece() => new CirclePiece(); public abstract bool OnPressed(TaikoAction action); diff --git a/osu.Game.Rulesets.Taiko/Objects/Swell.cs b/osu.Game.Rulesets.Taiko/Objects/Swell.cs index 714e5d29ee..95ea9f8aa4 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Swell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Swell.cs @@ -20,18 +20,5 @@ namespace osu.Game.Rulesets.Taiko.Objects /// The number of hits required to complete the swell successfully. /// public int RequiredHits = 10; - - public List ProgressionSamples = new List(); - - protected override void ApplyDefaultsToSelf(ControlPointInfo controlPointInfo, BeatmapDifficulty difficulty) - { - base.ApplyDefaultsToSelf(controlPointInfo, difficulty); - - var progressionSamplePoints = new[] { controlPointInfo.SamplePointAt(StartTime) } - .Concat(controlPointInfo.SamplePoints.Where(p => p.Time > StartTime && p.Time <= EndTime)); - - foreach (var point in progressionSamplePoints) - ProgressionSamples.Add(new DrumSampleMapping(point)); - } } } diff --git a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs index 5e79166bec..8c02b21733 100644 --- a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs +++ b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs @@ -2,14 +2,20 @@ // 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.Audio; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; using osu.Framework.Input.Bindings; +using osu.Game.Audio; +using osu.Game.Beatmaps.ControlPoints; using osu.Game.Graphics; +using osu.Game.Rulesets.Taiko.Audio; namespace osu.Game.Rulesets.Taiko.UI { @@ -18,16 +24,26 @@ namespace osu.Game.Rulesets.Taiko.UI /// internal class InputDrum : Container { - public InputDrum() + private const float middle_split = 0.025f; + + private readonly ControlPointInfo controlPoints; + + public InputDrum(ControlPointInfo controlPoints) { + this.controlPoints = controlPoints; + RelativeSizeAxes = Axes.Both; FillMode = FillMode.Fit; + } - const float middle_split = 0.025f; + [BackgroundDependencyLoader] + private void load(AudioManager audio) + { + var sampleMappings = new DrumSampleMapping(controlPoints, audio); Children = new Drawable[] { - new TaikoHalfDrum(false) + new TaikoHalfDrum(false, sampleMappings) { Name = "Left Half", Anchor = Anchor.Centre, @@ -38,7 +54,7 @@ namespace osu.Game.Rulesets.Taiko.UI RimAction = TaikoAction.LeftRim, CentreAction = TaikoAction.LeftCentre }, - new TaikoHalfDrum(true) + new TaikoHalfDrum(true, sampleMappings) { Name = "Right Half", Anchor = Anchor.Centre, @@ -72,8 +88,12 @@ namespace osu.Game.Rulesets.Taiko.UI private readonly Sprite centre; private readonly Sprite centreHit; - public TaikoHalfDrum(bool flipped) + private readonly DrumSampleMapping sampleMappings; + + public TaikoHalfDrum(bool flipped, DrumSampleMapping sampleMappings) { + this.sampleMappings = sampleMappings; + Masking = true; Children = new Drawable[] @@ -128,15 +148,21 @@ namespace osu.Game.Rulesets.Taiko.UI Drawable target = null; Drawable back = null; + var drumSample = sampleMappings.SampleAt(Time.Current); + if (action == CentreAction) { target = centreHit; back = centre; + + drumSample.Centre.Play(); } else if (action == RimAction) { target = rimHit; back = rim; + + drumSample.Rim.Play(); } if (target != null) diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index 229e44cf27..14f8de0f48 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -24,7 +24,7 @@ using osu.Game.Rulesets.Taiko.Audio; namespace osu.Game.Rulesets.Taiko.UI { - public class TaikoPlayfield : ScrollingPlayfield, IKeyBindingHandler + public class TaikoPlayfield : ScrollingPlayfield { /// /// Default height of a when inside a . @@ -59,13 +59,9 @@ namespace osu.Game.Rulesets.Taiko.UI private readonly Box overlayBackground; private readonly Box background; - private readonly ControlPointInfo controlPointInfo; - private readonly List drumSampleMappings = new List(); - - public TaikoPlayfield(ControlPointInfo controlPointInfo) + public TaikoPlayfield(ControlPointInfo controlPoints) : base(Axes.X) { - this.controlPointInfo = controlPointInfo; AddRangeInternal(new Drawable[] { backgroundContainer = new Container @@ -158,7 +154,7 @@ namespace osu.Game.Rulesets.Taiko.UI { RelativeSizeAxes = Axes.Both, }, - new InputDrum + new InputDrum(controlPoints) { Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, @@ -205,17 +201,7 @@ namespace osu.Game.Rulesets.Taiko.UI [BackgroundDependencyLoader] private void load(OsuColour colours, AudioManager audio) { - // We may have 0 sample points, but we need at least the default one - var samplePoints = new[] { controlPointInfo.SamplePointAt(double.MinValue) } - .Concat(controlPointInfo.SamplePoints); - foreach (var s in samplePoints) - { - var mapping = new DrumSampleMapping(s); - mapping.RetrieveChannels(audio); - - drumSampleMappings.Add(mapping); - } overlayBackgroundContainer.BorderColour = colours.Gray0; overlayBackground.Colour = colours.Gray1; @@ -281,23 +267,5 @@ namespace osu.Game.Rulesets.Taiko.UI kiaiExplosionContainer.Add(new KiaiHitExplosion(judgedObject, isRim)); } } - - public bool OnPressed(TaikoAction action) - { - var mappingIndex = drumSampleMappings.BinarySearch(new DrumSampleMapping { Time = Time.Current }); - if (mappingIndex < 0) - mappingIndex = ~mappingIndex - 1; - - var mapping = drumSampleMappings[mappingIndex]; - - if (action == TaikoAction.LeftCentre || action == TaikoAction.RightCentre) - mapping.CentreChannel.Play(); - else - mapping.RimChannel.Play(); - - return true; - } - - public bool OnReleased(TaikoAction action) => false; } } diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index be161b9ad3..ab4c04be3f 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -72,6 +72,7 @@ namespace osu.Game.Rulesets.Objects.Drawables public IReadOnlyList Judgements => judgements; protected List Samples = new List(); + protected virtual IEnumerable GetSamples() => HitObject.Samples; public readonly Bindable State = new Bindable(); @@ -84,13 +85,14 @@ namespace osu.Game.Rulesets.Objects.Drawables [BackgroundDependencyLoader] private void load(AudioManager audio) { - if (Samples.Count > 0) + var samples = GetSamples(); + if (samples.Any()) { if (HitObject.SampleControlPoint == null) throw new ArgumentNullException(nameof(HitObject.SampleControlPoint), $"{nameof(HitObject)}s must always have an attached {nameof(HitObject.SampleControlPoint)}." + $" This is an indication that {nameof(HitObject.ApplyDefaults)} has not been invoked on {this}."); - foreach (SampleInfo s in HitObject.Samples) + foreach (SampleInfo s in samples) { SampleInfo localSampleInfo = new SampleInfo { From 35d7fa8a81ae017f964c1644ddac3db0b7f94135 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 26 Dec 2017 14:18:38 +0900 Subject: [PATCH 34/49] Cleanup things that are now not needed with these changes --- osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs | 2 +- .../Objects/Drawables/DrawableHitStrong.cs | 2 +- .../Objects/Drawables/DrawableSwell.cs | 4 +--- .../Objects/Drawables/DrawableTaikoHitObject.cs | 1 - osu.Game.Rulesets.Taiko/Objects/Swell.cs | 5 ----- osu.Game.Rulesets.Taiko/UI/InputDrum.cs | 3 --- osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 8 +------- 7 files changed, 4 insertions(+), 21 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs index df33aae94e..fd35f0eaec 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs @@ -68,7 +68,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables validKeyPressed = HitActions.Contains(action); // Only count this as handled if the new judgement is a hit - return UpdateJudgement(true) && Judgements.LastOrDefault()?.IsHit == true; + return UpdateJudgement(true); } protected override void Update() diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs index 07f7b83cef..cda82afe0e 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs @@ -83,7 +83,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables return false; // Assume the intention was to hit the strong hit with both keys only if the first key is still being held down - return firstKeyHeld && UpdateJudgement(true) && Judgements.LastOrDefault()?.IsHit == true; + return firstKeyHeld && UpdateJudgement(true); } } } diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs index 3099c6984c..5ca33aaea2 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs @@ -14,8 +14,6 @@ using OpenTK; using OpenTK.Graphics; using osu.Framework.Graphics.Shapes; using osu.Game.Rulesets.Taiko.Judgements; -using osu.Framework.Audio; -using osu.Game.Rulesets.Taiko.Audio; namespace osu.Game.Rulesets.Taiko.Objects.Drawables { @@ -118,7 +116,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables } [BackgroundDependencyLoader] - private void load(OsuColour colours, AudioManager audio) + private void load(OsuColour colours) { MainPiece.AccentColour = colours.YellowDark; expandingRing.Colour = colours.YellowLight; diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs index cf0df260b1..92da3fe09e 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs @@ -6,7 +6,6 @@ using osu.Framework.Input.Bindings; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces; using OpenTK; -using System; using System.Linq; using osu.Game.Audio; using System.Collections.Generic; diff --git a/osu.Game.Rulesets.Taiko/Objects/Swell.cs b/osu.Game.Rulesets.Taiko/Objects/Swell.cs index 95ea9f8aa4..cd2876ea2d 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Swell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Swell.cs @@ -1,12 +1,7 @@ // 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.Beatmaps.ControlPoints; using osu.Game.Rulesets.Objects.Types; -using osu.Game.Rulesets.Taiko.Audio; namespace osu.Game.Rulesets.Taiko.Objects { diff --git a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs index 8c02b21733..bf1274256b 100644 --- a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs +++ b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs @@ -2,8 +2,6 @@ // 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.Audio; @@ -12,7 +10,6 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; using osu.Framework.Input.Bindings; -using osu.Game.Audio; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Graphics; using osu.Game.Rulesets.Taiko.Audio; diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index 14f8de0f48..3fdbd056ce 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -16,11 +16,7 @@ using osu.Framework.Extensions.Color4Extensions; using System.Linq; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Taiko.Objects.Drawables; -using osu.Framework.Input.Bindings; using osu.Game.Beatmaps.ControlPoints; -using osu.Framework.Audio; -using System.Collections.Generic; -using osu.Game.Rulesets.Taiko.Audio; namespace osu.Game.Rulesets.Taiko.UI { @@ -199,10 +195,8 @@ namespace osu.Game.Rulesets.Taiko.UI } [BackgroundDependencyLoader] - private void load(OsuColour colours, AudioManager audio) + private void load(OsuColour colours) { - - overlayBackgroundContainer.BorderColour = colours.Gray0; overlayBackground.Colour = colours.Gray1; From 9ccc49c9b5a2b61c73e30a9cea35118614f5f4fb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 26 Dec 2017 15:32:39 +0900 Subject: [PATCH 35/49] Make selection triggering more liberal --- osu.Game/Screens/Select/BeatmapCarousel.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index e3566f3206..9d7867659d 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -513,7 +513,7 @@ namespace osu.Game.Screens.Select currentY += DrawHeight / 2; scrollableContent.Height = currentY; - if (selectedBeatmapSet != null && (selectedBeatmap == null || selectedBeatmapSet.State.Value != CarouselItemState.Selected)) + if (selectedBeatmapSet == null || selectedBeatmap == null || selectedBeatmapSet.State.Value != CarouselItemState.Selected) { selectedBeatmapSet = null; SelectionChanged?.Invoke(null); From e14ad31a071cacfc10f4ab8668f3d00634776c68 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 26 Dec 2017 15:32:53 +0900 Subject: [PATCH 36/49] Increase wait durations for test stability --- osu.Game.Tests/Visual/TestCasePlaySongSelect.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs b/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs index e27e786a05..69aa371958 100644 --- a/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs @@ -90,7 +90,7 @@ namespace osu.Game.Tests.Visual loadNewSongSelect(true); - AddWaitStep(1); + AddWaitStep(3); AddAssert("dummy selected", () => songSelect.CurrentBeatmap == defaultBeatmap); @@ -100,11 +100,11 @@ namespace osu.Game.Tests.Visual manager.Import(createTestBeatmapSet(i)); }); - AddWaitStep(1); + AddWaitStep(3); AddAssert("random map selected", () => songSelect.CurrentBeatmap != defaultBeatmap); loadNewSongSelect(); - AddWaitStep(1); + AddWaitStep(3); AddAssert("random map selected", () => songSelect.CurrentBeatmap != defaultBeatmap); AddStep(@"Sort by Artist", delegate { songSelect.FilterControl.Sort = SortMode.Artist; }); From 024d9a6850c9071225cba706b77e8f21d9f426e6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 26 Dec 2017 15:33:02 +0900 Subject: [PATCH 37/49] Remove unnecessary null check --- .../Visual/TestCasePlaySongSelect.cs | 25 ++++++++----------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs b/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs index 69aa371958..18e40db064 100644 --- a/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs @@ -59,21 +59,18 @@ namespace osu.Game.Tests.Visual { TestSongSelect songSelect = null; - if (manager == null) + var storage = new TestStorage(@"TestCasePlaySongSelect"); + + // this is by no means clean. should be replacing inside of OsuGameBase somehow. + var context = new OsuDbContext(); + + Func contextFactory = () => context; + + dependencies.Cache(rulesets = new RulesetStore(contextFactory)); + dependencies.Cache(manager = new BeatmapManager(storage, contextFactory, rulesets, null) { - var storage = new TestStorage(@"TestCasePlaySongSelect"); - - // this is by no means clean. should be replacing inside of OsuGameBase somehow. - var context = new OsuDbContext(); - - Func contextFactory = () => context; - - dependencies.Cache(rulesets = new RulesetStore(contextFactory)); - dependencies.Cache(manager = new BeatmapManager(storage, contextFactory, rulesets, null) - { - DefaultBeatmap = defaultBeatmap = baseManager.GetWorkingBeatmap(null) - }); - } + DefaultBeatmap = defaultBeatmap = baseManager.GetWorkingBeatmap(null) + }); void loadNewSongSelect(bool deleteMaps = false) => AddStep("reload song select", () => { From ed1df94f778d983933e72183a386e0f3bbd1b11d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 26 Dec 2017 15:48:01 +0900 Subject: [PATCH 38/49] Fix unread light not turning off --- osu.Game/Overlays/Notifications/Notification.cs | 2 +- osu.Game/Overlays/Notifications/SimpleNotification.cs | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Notifications/Notification.cs b/osu.Game/Overlays/Notifications/Notification.cs index 422051364e..b4720e79c4 100644 --- a/osu.Game/Overlays/Notifications/Notification.cs +++ b/osu.Game/Overlays/Notifications/Notification.cs @@ -261,4 +261,4 @@ namespace osu.Game.Overlays.Notifications } } } -} \ No newline at end of file +} diff --git a/osu.Game/Overlays/Notifications/SimpleNotification.cs b/osu.Game/Overlays/Notifications/SimpleNotification.cs index 0b8b365c48..1e691e2a5a 100644 --- a/osu.Game/Overlays/Notifications/SimpleNotification.cs +++ b/osu.Game/Overlays/Notifications/SimpleNotification.cs @@ -83,8 +83,10 @@ namespace osu.Game.Overlays.Notifications set { + if (value == base.Read) return; + base.Read = value; - Light.FadeTo(value ? 1 : 0, 100); + Light.FadeTo(value ? 0 : 1, 100); } } } From 45b3acdd6f1ad89ade0f0abd8564c0fcaa7fefb7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 26 Dec 2017 15:50:59 +0900 Subject: [PATCH 39/49] Fix progress notifications not closing properly when opening their continuation --- osu.Game/Overlays/Notifications/ProgressNotification.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Notifications/ProgressNotification.cs b/osu.Game/Overlays/Notifications/ProgressNotification.cs index 9211c227f8..c39c630858 100644 --- a/osu.Game/Overlays/Notifications/ProgressNotification.cs +++ b/osu.Game/Overlays/Notifications/ProgressNotification.cs @@ -95,7 +95,7 @@ namespace osu.Game.Overlays.Notifications protected virtual void Completed() { - Expire(); + base.Close(); CompletionTarget?.Invoke(CreateCompletionNotification()); } From 24d8d357d07e762fb233411c5e8860400664f151 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 26 Dec 2017 15:52:36 +0900 Subject: [PATCH 40/49] Only bounce and flash notification count when increasing --- .../Toolbar/ToolbarNotificationButton.cs | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/Toolbar/ToolbarNotificationButton.cs b/osu.Game/Overlays/Toolbar/ToolbarNotificationButton.cs index faf802f5e7..c093767e52 100644 --- a/osu.Game/Overlays/Toolbar/ToolbarNotificationButton.cs +++ b/osu.Game/Overlays/Toolbar/ToolbarNotificationButton.cs @@ -59,16 +59,27 @@ namespace osu.Game.Overlays.Toolbar private class CountCircle : CompositeDrawable { - private readonly OsuSpriteText count; + private readonly OsuSpriteText countText; private readonly Circle circle; + private int count; + public int Count { + get { return count; } set { - count.Text = value.ToString("#,0"); - circle.FlashColour(Color4.White, 600, Easing.OutQuint); - this.ScaleTo(1.1f).Then().ScaleTo(1, 600, Easing.OutElastic); + if (count == value) + return; + + if (value > count) + { + circle.FlashColour(Color4.White, 600, Easing.OutQuint); + this.ScaleTo(1.1f).Then().ScaleTo(1, 600, Easing.OutElastic); + } + + count = value; + countText.Text = value.ToString("#,0"); } } @@ -83,7 +94,7 @@ namespace osu.Game.Overlays.Toolbar RelativeSizeAxes = Axes.Both, Colour = Color4.Red }, - count = new OsuSpriteText + countText = new OsuSpriteText { Anchor = Anchor.Centre, Origin = Anchor.Centre, From 3f1ced618ae6db07f71ad6ba05b81f477c617334 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 26 Dec 2017 16:15:15 +0900 Subject: [PATCH 41/49] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 08f85f9bf9..46d4704b0a 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 08f85f9bf9a7376aec8dfcde8c7c96d267d8c295 +Subproject commit 46d4704b0a3f140fa8ad10ca0b1553b67d8385ab From 44fbe7859a0a703f540f2fa6a70b413665bcb75a Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Tue, 26 Dec 2017 11:34:26 +0100 Subject: [PATCH 42/49] move anchor and origin so metadata doesn't move if it's partially empty --- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 5d4f950a51..4f20b50d35 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -154,9 +154,10 @@ namespace osu.Game.Screens.Select }, new FillFlowContainer { - Name = "Bottom-aligned metadata", - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, + Name = "Centre-aligned metadata", + Anchor = Anchor.CentreLeft, + Origin = Anchor.TopLeft, + Y = -22, Direction = FillDirection.Vertical, Margin = new MarginPadding { Top = 15, Left = 25, Right = 10, Bottom = 20 }, AutoSizeAxes = Axes.Both, From 1c4bcdda96f690123a8eb2ae7a502da9cac11a52 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 26 Dec 2017 20:13:55 +0900 Subject: [PATCH 43/49] Fix test race condition async loads --- osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs b/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs index 61c904aa60..53943edfab 100644 --- a/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs +++ b/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs @@ -110,11 +110,15 @@ namespace osu.Game.Tests.Visual private void selectBeatmap(string name) { + var infoBefore = infoWedge.Info; + AddStep($"select {name} beatmap", () => { beatmap.Value = new TestWorkingBeatmap(beatmaps.First(b => b.BeatmapInfo.Ruleset.ShortName == name)); infoWedge.UpdateBeatmap(beatmap); }); + + AddUntilStep(() => infoWedge.Info != infoBefore, "wait for async load"); } private void selectNullBeatmap() From 7504cd589dc532f67e1a2c42aac5505732c9c6ee Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 26 Dec 2017 20:18:47 +0900 Subject: [PATCH 44/49] Move alpha handling to state --- .../Visual/TestCaseBeatmapInfoWedge.cs | 20 +++++++++---------- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 9 ++++++--- osu.Game/Screens/Select/SongSelect.cs | 1 - 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs b/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs index 53943edfab..3a50e43239 100644 --- a/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs +++ b/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs @@ -41,25 +41,23 @@ namespace osu.Game.Tests.Visual { Size = new Vector2(0.5f, 245), RelativeSizeAxes = Axes.X, - Margin = new MarginPadding - { - Top = 20, - } - }); - - AddStep("hide", () => - { - infoWedge.State = Visibility.Hidden; - Content.FadeOut(100); + Margin = new MarginPadding { Top = 20 } }); AddStep("show", () => { - Content.FadeInFromZero(250); infoWedge.State = Visibility.Visible; infoWedge.UpdateBeatmap(beatmap); }); + AddWaitStep(3); + + AddStep("hide", () => { infoWedge.State = Visibility.Hidden; }); + + AddWaitStep(3); + + AddStep("show", () => { infoWedge.State = Visibility.Visible; }); + foreach (var rulesetInfo in rulesets.AvailableRulesets) { var ruleset = rulesetInfo.CreateInstance(); diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 4f20b50d35..d4f1b90ebf 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -35,6 +35,7 @@ namespace osu.Game.Screens.Select Masking = true; BorderColour = new Color4(221, 255, 255, 255); BorderThickness = 2.5f; + Alpha = 0; EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Glow, @@ -50,12 +51,14 @@ namespace osu.Game.Screens.Select { this.MoveToX(0, 800, Easing.OutQuint); this.RotateTo(0, 800, Easing.OutQuint); + this.FadeIn(250); } protected override void PopOut() { - this.MoveToX(-100, 800, Easing.InQuint); - this.RotateTo(10, 800, Easing.InQuint); + this.MoveToX(-100, 800, Easing.In); + this.RotateTo(10, 800, Easing.In); + this.FadeOut(500, Easing.In); } public void UpdateBeatmap(WorkingBeatmap beatmap) @@ -68,7 +71,7 @@ namespace osu.Game.Screens.Select { // ensure we ourselves are visible if not already. if (!IsPresent) - this.FadeIn(250); + State = Visibility.Visible; Info?.FadeOut(250); Info?.Expire(); diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 68ee08e721..a66cd0b3e3 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -121,7 +121,6 @@ namespace osu.Game.Screens.Select }, beatmapInfoWedge = new BeatmapInfoWedge { - Alpha = 0, Size = wedged_container_size, RelativeSizeAxes = Axes.X, Margin = new MarginPadding From d17f6cb5647c03b4fef7f7464ef7cfbfac43fa43 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 27 Dec 2017 11:20:17 +0900 Subject: [PATCH 45/49] Fix crash when starting play mode with no beatmap Closes #1767 --- osu.Game/Screens/Play/PlayerLoader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index de67bef004..a220dcee0e 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -250,7 +250,7 @@ namespace osu.Game.Screens.Play Origin = Anchor.TopCentre, Anchor = Anchor.TopCentre, }, - new MetadataLine("Mapper", metadata.Author.Username) + new MetadataLine("Mapper", metadata.AuthorString) { Origin = Anchor.TopCentre, Anchor = Anchor.TopCentre, From ae9f08f387dc26ca63eea7e09507e0ed9d4eded0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 27 Dec 2017 11:47:04 +0900 Subject: [PATCH 46/49] Fix crash in editor when trying to seek on a virtual track --- .../Edit/Components/Timelines/Summary/Parts/MarkerPart.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs index 367cf4337d..b2308aca71 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs @@ -47,6 +47,8 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts if (Beatmap.Value == null) return; + if (Beatmap.Value.Track.Length == double.PositiveInfinity) return; + float markerPos = MathHelper.Clamp(ToLocalSpace(screenPosition).X, 0, DrawWidth); seekTo(markerPos / DrawWidth * Beatmap.Value.Track.Length); } From 18d2be75d54a84dfe1d601c1a3cadab354fce7cc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 27 Dec 2017 13:04:24 +0900 Subject: [PATCH 47/49] Fix random selection happening more than once on quick imports --- osu.Game/Screens/Select/SongSelect.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index b4494936f4..9e5a2fa633 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -444,7 +444,7 @@ namespace osu.Game.Screens.Select { if (!Beatmap.IsDefault && Beatmap.Value.BeatmapSetInfo?.DeletePending == false) Carousel.SelectBeatmap(Beatmap.Value.BeatmapInfo); - else + else if (Carousel.SelectedBeatmapSet == null) Carousel.SelectNextRandom(); } From 5b529511ec6727ccded551c9bce9312027ffa7f0 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 27 Dec 2017 13:18:34 +0900 Subject: [PATCH 48/49] Update OpenTK nuget package Fixes the recent AppVeyor errors --- osu.Desktop/osu.Desktop.csproj | 4 ++-- osu.Desktop/packages.config | 2 +- osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj | 4 ++-- osu.Game.Rulesets.Catch/packages.config | 2 +- osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj | 4 ++-- osu.Game.Rulesets.Mania/packages.config | 2 +- osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj | 4 ++-- osu.Game.Rulesets.Osu/packages.config | 2 +- osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj | 4 ++-- osu.Game.Rulesets.Taiko/packages.config | 2 +- osu.Game.Tests/osu.Game.Tests.csproj | 4 ++-- osu.Game.Tests/packages.config | 2 +- osu.Game/osu.Game.csproj | 4 ++-- osu.Game/packages.config | 2 +- 14 files changed, 21 insertions(+), 21 deletions(-) diff --git a/osu.Desktop/osu.Desktop.csproj b/osu.Desktop/osu.Desktop.csproj index e4e9807754..4a1798feb4 100644 --- a/osu.Desktop/osu.Desktop.csproj +++ b/osu.Desktop/osu.Desktop.csproj @@ -135,8 +135,8 @@ $(SolutionDir)\packages\squirrel.windows.1.7.8\lib\Net45\NuGet.Squirrel.dll True - - $(SolutionDir)\packages\OpenTK.3.0.0-git00009\lib\net20\OpenTK.dll + + $(SolutionDir)\packages\OpenTK.3.0.0-git00021\lib\net20\OpenTK.dll True diff --git a/osu.Desktop/packages.config b/osu.Desktop/packages.config index 6b6361b578..e7233a42ac 100644 --- a/osu.Desktop/packages.config +++ b/osu.Desktop/packages.config @@ -6,7 +6,7 @@ Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/maste - + diff --git a/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj index b03c8d2eea..578d8eb34d 100644 --- a/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj +++ b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj @@ -36,8 +36,8 @@ $(SolutionDir)\packages\NUnit.3.8.1\lib\net45\nunit.framework.dll True - - $(SolutionDir)\packages\OpenTK.3.0.0-git00009\lib\net20\OpenTK.dll + + $(SolutionDir)\packages\OpenTK.3.0.0-git00021\lib\net20\OpenTK.dll True diff --git a/osu.Game.Rulesets.Catch/packages.config b/osu.Game.Rulesets.Catch/packages.config index cde428acea..2369f7529b 100644 --- a/osu.Game.Rulesets.Catch/packages.config +++ b/osu.Game.Rulesets.Catch/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj index 26181164f9..bdd6656ed9 100644 --- a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj +++ b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj @@ -36,8 +36,8 @@ $(SolutionDir)\packages\NUnit.3.8.1\lib\net45\nunit.framework.dll True - - $(SolutionDir)\packages\OpenTK.3.0.0-git00009\lib\net20\OpenTK.dll + + $(SolutionDir)\packages\OpenTK.3.0.0-git00021\lib\net20\OpenTK.dll True diff --git a/osu.Game.Rulesets.Mania/packages.config b/osu.Game.Rulesets.Mania/packages.config index cde428acea..2369f7529b 100644 --- a/osu.Game.Rulesets.Mania/packages.config +++ b/osu.Game.Rulesets.Mania/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj b/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj index ec71869adb..6e61d7fb2d 100644 --- a/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj +++ b/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj @@ -37,8 +37,8 @@ $(SolutionDir)\packages\NUnit.3.8.1\lib\net45\nunit.framework.dll True - - $(SolutionDir)\packages\OpenTK.3.0.0-git00009\lib\net20\OpenTK.dll + + $(SolutionDir)\packages\OpenTK.3.0.0-git00021\lib\net20\OpenTK.dll True diff --git a/osu.Game.Rulesets.Osu/packages.config b/osu.Game.Rulesets.Osu/packages.config index cde428acea..2369f7529b 100644 --- a/osu.Game.Rulesets.Osu/packages.config +++ b/osu.Game.Rulesets.Osu/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj b/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj index f1c29c1a34..f73831a952 100644 --- a/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj +++ b/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj @@ -36,8 +36,8 @@ $(SolutionDir)\packages\NUnit.3.8.1\lib\net45\nunit.framework.dll True - - $(SolutionDir)\packages\OpenTK.3.0.0-git00009\lib\net20\OpenTK.dll + + $(SolutionDir)\packages\OpenTK.3.0.0-git00021\lib\net20\OpenTK.dll True diff --git a/osu.Game.Rulesets.Taiko/packages.config b/osu.Game.Rulesets.Taiko/packages.config index cde428acea..2369f7529b 100644 --- a/osu.Game.Rulesets.Taiko/packages.config +++ b/osu.Game.Rulesets.Taiko/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj index e0b9eb4091..df66896d9b 100644 --- a/osu.Game.Tests/osu.Game.Tests.csproj +++ b/osu.Game.Tests/osu.Game.Tests.csproj @@ -37,8 +37,8 @@ $(SolutionDir)\packages\NUnit.3.8.1\lib\net45\nunit.framework.dll True - - $(SolutionDir)\packages\OpenTK.3.0.0-git00009\lib\net20\OpenTK.dll + + $(SolutionDir)\packages\OpenTK.3.0.0-git00021\lib\net20\OpenTK.dll True diff --git a/osu.Game.Tests/packages.config b/osu.Game.Tests/packages.config index e09f2a07ba..c2056e09a8 100644 --- a/osu.Game.Tests/packages.config +++ b/osu.Game.Tests/packages.config @@ -6,6 +6,6 @@ Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/maste - + \ No newline at end of file diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index b5f93123fd..7d146c0a12 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -143,8 +143,8 @@ $(SolutionDir)\packages\NUnit.3.8.1\lib\net45\nunit.framework.dll True - - $(SolutionDir)\packages\OpenTK.3.0.0-git00009\lib\net20\OpenTK.dll + + $(SolutionDir)\packages\OpenTK.3.0.0-git00021\lib\net20\OpenTK.dll True diff --git a/osu.Game/packages.config b/osu.Game/packages.config index 02ace918de..3ba50388e8 100644 --- a/osu.Game/packages.config +++ b/osu.Game/packages.config @@ -66,7 +66,7 @@ Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/maste - + From 5ad86d2b757baefcc57b1ac545e4283be8920e3a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 27 Dec 2017 13:50:54 +0900 Subject: [PATCH 49/49] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 46d4704b0a..b28d4ba82a 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 46d4704b0a3f140fa8ad10ca0b1553b67d8385ab +Subproject commit b28d4ba82af0138d38ff8b3f4f3392d9d9068da9