From a14edc06c840babaaf7fcc4f73f09fedc07c4e9d Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Wed, 19 Oct 2016 10:31:10 -0400 Subject: [PATCH 01/58] Pull beatmap list from db and render simple list --- osu.Game/Beatmaps/Beatmap.cs | 2 +- osu.Game/Database/BeatmapDatabase.cs | 2 +- osu.Game/Database/BeatmapMetadata.cs | 2 +- osu.Game/GameModes/Play/PlaySongSelect.cs | 30 +++++++++++++++++++---- 4 files changed, 28 insertions(+), 8 deletions(-) diff --git a/osu.Game/Beatmaps/Beatmap.cs b/osu.Game/Beatmaps/Beatmap.cs index 438a5a2b89..c2b6b5932f 100644 --- a/osu.Game/Beatmaps/Beatmap.cs +++ b/osu.Game/Beatmaps/Beatmap.cs @@ -17,4 +17,4 @@ namespace osu.Game.Beatmaps public List ControlPoints { get; set; } public List ComboColors { get; set; } } -} \ No newline at end of file +} diff --git a/osu.Game/Database/BeatmapDatabase.cs b/osu.Game/Database/BeatmapDatabase.cs index 73809c6fc2..3ada4888eb 100644 --- a/osu.Game/Database/BeatmapDatabase.cs +++ b/osu.Game/Database/BeatmapDatabase.cs @@ -125,4 +125,4 @@ namespace osu.Game.Database connection.Update(record); } } -} \ No newline at end of file +} diff --git a/osu.Game/Database/BeatmapMetadata.cs b/osu.Game/Database/BeatmapMetadata.cs index 531779922a..0b4d692abc 100644 --- a/osu.Game/Database/BeatmapMetadata.cs +++ b/osu.Game/Database/BeatmapMetadata.cs @@ -8,7 +8,7 @@ namespace osu.Game.Database { public class BeatmapMetadata { - [PrimaryKey] + [PrimaryKey, AutoIncrement] public int ID { get; set; } public int BeatmapSetID { get; set; } diff --git a/osu.Game/GameModes/Play/PlaySongSelect.cs b/osu.Game/GameModes/Play/PlaySongSelect.cs index df120ba8ba..d63ea5b7d5 100644 --- a/osu.Game/GameModes/Play/PlaySongSelect.cs +++ b/osu.Game/GameModes/Play/PlaySongSelect.cs @@ -4,21 +4,33 @@ using System; using System.Collections.Generic; using osu.Framework.Configuration; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; using osu.Game.GameModes.Backgrounds; using osu.Framework; namespace osu.Game.GameModes.Play { - class PlaySongSelect : GameModeWhiteBox + class PlaySongSelect : OsuGameMode { private Bindable playMode; + // TODO: use currently selected track as bg protected override BackgroundMode CreateBackground() => new BackgroundModeCustom(@"Backgrounds/bg4"); - protected override IEnumerable PossibleChildren => new[] { - typeof(ModSelect), - typeof(Player) - }; + private FlowContainer setList; + + private void addBeatmapSets() + { + var sets = (Game as OsuGame).Beatmaps.GetBeatmapSets(); + foreach (var beatmapSet in sets) + { + setList.Add(new SpriteText + { + Text = beatmapSet.Metadata.Title + }); + } + } public override void Load(BaseGame game) { @@ -28,6 +40,14 @@ namespace osu.Game.GameModes.Play playMode = osu.PlayMode; playMode.ValueChanged += PlayMode_ValueChanged; + + Add(setList = new FlowContainer + { + Direction = FlowDirection.VerticalOnly, + Padding = new OpenTK.Vector2(0, osu.Toolbar.Height) + }); + + addBeatmapSets(); } protected override void Dispose(bool isDisposing) From 674f624bfc3e0262faea9e0c0bafeff26940a80d Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Tue, 11 Oct 2016 13:52:16 -0400 Subject: [PATCH 02/58] Improve song selection layout, database loading Also adds event that notifes the song select when a beatmap is added. --- osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs | 3 +- osu.Game/Database/BeatmapDatabase.cs | 2 ++ osu.Game/GameModes/Play/PlaySongSelect.cs | 29 +++++++++++++------ 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs index 9cbddc853f..585dff4226 100644 --- a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs @@ -223,7 +223,6 @@ namespace osu.Game.Beatmaps.Formats line = stream.ReadLine(); if (line == null) break; - line = line.Trim(); if (string.IsNullOrEmpty(line)) continue; if (line.StartsWith(@"osu file format v")) @@ -274,4 +273,4 @@ namespace osu.Game.Beatmaps.Formats return beatmap; } } -} \ No newline at end of file +} diff --git a/osu.Game/Database/BeatmapDatabase.cs b/osu.Game/Database/BeatmapDatabase.cs index 3ada4888eb..082047f56b 100644 --- a/osu.Game/Database/BeatmapDatabase.cs +++ b/osu.Game/Database/BeatmapDatabase.cs @@ -16,6 +16,7 @@ namespace osu.Game.Database { private static SQLiteConnection connection { get; set; } private BasicStorage storage; + public event Action BeatmapSetAdded; public BeatmapDatabase(BasicStorage storage) { @@ -75,6 +76,7 @@ namespace osu.Game.Database connection.Insert(beatmapSet); beatmapSet.BeatmapMetadataID = connection.Insert(metadata); connection.UpdateWithChildren(beatmapSet); + BeatmapSetAdded?.Invoke(beatmapSet); } public ArchiveReader GetReader(BeatmapSetInfo beatmapSet) diff --git a/osu.Game/GameModes/Play/PlaySongSelect.cs b/osu.Game/GameModes/Play/PlaySongSelect.cs index d63ea5b7d5..37a85f7f75 100644 --- a/osu.Game/GameModes/Play/PlaySongSelect.cs +++ b/osu.Game/GameModes/Play/PlaySongSelect.cs @@ -4,8 +4,10 @@ using System; using System.Collections.Generic; using osu.Framework.Configuration; +using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; +using osu.Game.Beatmaps; using osu.Game.GameModes.Backgrounds; using osu.Framework; @@ -20,16 +22,16 @@ namespace osu.Game.GameModes.Play private FlowContainer setList; + private Drawable createSetUI(BeatmapSet bset) + { + return new SpriteText { Text = bset.Metadata.Title }; + } + private void addBeatmapSets() { var sets = (Game as OsuGame).Beatmaps.GetBeatmapSets(); foreach (var beatmapSet in sets) - { - setList.Add(new SpriteText - { - Text = beatmapSet.Metadata.Title - }); - } + setList.Add(createSetUI(beatmapSet)); } public override void Load(BaseGame game) @@ -41,13 +43,22 @@ namespace osu.Game.GameModes.Play playMode = osu.PlayMode; playMode.ValueChanged += PlayMode_ValueChanged; - Add(setList = new FlowContainer + Add(new ScrollContainer { - Direction = FlowDirection.VerticalOnly, - Padding = new OpenTK.Vector2(0, osu.Toolbar.Height) + OriginPosition = new OpenTK.Vector2(0, -osu.Toolbar.Height), + Children = new[] + { + setList = new FlowContainer + { + Direction = FlowDirection.VerticalOnly, + Padding = new OpenTK.Vector2(25, 25) + } + } }); addBeatmapSets(); + + (Game as OsuGame).Beatmaps.BeatmapSetAdded += bset => setList.Add(createSetUI(bset)); } protected override void Dispose(bool isDisposing) From 22fdb3e49a37d031beb77c060a610499880fc7bb Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Tue, 11 Oct 2016 14:15:22 -0400 Subject: [PATCH 03/58] Adjust PlaySongSelect to match UI standards --- osu.Game/GameModes/Play/PlaySongSelect.cs | 32 ++++++++++++++--------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/osu.Game/GameModes/Play/PlaySongSelect.cs b/osu.Game/GameModes/Play/PlaySongSelect.cs index 37a85f7f75..bdabb8d8dd 100644 --- a/osu.Game/GameModes/Play/PlaySongSelect.cs +++ b/osu.Game/GameModes/Play/PlaySongSelect.cs @@ -33,6 +33,25 @@ namespace osu.Game.GameModes.Play foreach (var beatmapSet in sets) setList.Add(createSetUI(beatmapSet)); } + + public PlaySongSelect() + { + Children = new[] + { + new ScrollContainer + { + OriginPosition = new OpenTK.Vector2(0, -(Game as OsuGame).Toolbar.Height), + Children = new[] + { + setList = new FlowContainer + { + Direction = FlowDirection.VerticalOnly, + Padding = new OpenTK.Vector2(25, 25) + } + } + } + }; + } public override void Load(BaseGame game) { @@ -43,19 +62,6 @@ namespace osu.Game.GameModes.Play playMode = osu.PlayMode; playMode.ValueChanged += PlayMode_ValueChanged; - Add(new ScrollContainer - { - OriginPosition = new OpenTK.Vector2(0, -osu.Toolbar.Height), - Children = new[] - { - setList = new FlowContainer - { - Direction = FlowDirection.VerticalOnly, - Padding = new OpenTK.Vector2(25, 25) - } - } - }); - addBeatmapSets(); (Game as OsuGame).Beatmaps.BeatmapSetAdded += bset => setList.Add(createSetUI(bset)); From d21b7f0050f1da0dd087e5a01e836fff4396afd2 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 13 Oct 2016 13:49:44 -0400 Subject: [PATCH 04/58] Fix up song select based on upstream changes --- osu.Game/Beatmaps/Formats/BeatmapDecoder.cs | 2 +- osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs | 1 + osu.Game/GameModes/Play/PlaySongSelect.cs | 16 +++++++++++----- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/BeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/BeatmapDecoder.cs index 92f2452484..f376d831cf 100644 --- a/osu.Game/Beatmaps/Formats/BeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/BeatmapDecoder.cs @@ -23,4 +23,4 @@ namespace osu.Game.Beatmaps.Formats public abstract Beatmap Decode(TextReader stream); } -} \ No newline at end of file +} diff --git a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs index 585dff4226..78f05676b7 100644 --- a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs @@ -21,6 +21,7 @@ namespace osu.Game.Beatmaps.Formats AddDecoder(@"osu file format v12"); AddDecoder(@"osu file format v11"); AddDecoder(@"osu file format v10"); + AddDecoder(@"osu file format v9"); // TODO: Not sure how far back to go, or differences between versions } diff --git a/osu.Game/GameModes/Play/PlaySongSelect.cs b/osu.Game/GameModes/Play/PlaySongSelect.cs index bdabb8d8dd..edf144db6f 100644 --- a/osu.Game/GameModes/Play/PlaySongSelect.cs +++ b/osu.Game/GameModes/Play/PlaySongSelect.cs @@ -10,16 +10,20 @@ using osu.Framework.Graphics.Sprites; using osu.Game.Beatmaps; using osu.Game.GameModes.Backgrounds; using osu.Framework; +using osu.Game.Database; +using osu.Framework.Graphics.Primitives; namespace osu.Game.GameModes.Play { class PlaySongSelect : OsuGameMode { private Bindable playMode; + private BeatmapDatabase beatmaps; // TODO: use currently selected track as bg protected override BackgroundMode CreateBackground() => new BackgroundModeCustom(@"Backgrounds/bg4"); + private ScrollContainer scrollContainer; private FlowContainer setList; private Drawable createSetUI(BeatmapSet bset) @@ -29,7 +33,7 @@ namespace osu.Game.GameModes.Play private void addBeatmapSets() { - var sets = (Game as OsuGame).Beatmaps.GetBeatmapSets(); + var sets = beatmaps.GetBeatmapSets(); foreach (var beatmapSet in sets) setList.Add(createSetUI(beatmapSet)); } @@ -38,15 +42,14 @@ namespace osu.Game.GameModes.Play { Children = new[] { - new ScrollContainer + scrollContainer = new ScrollContainer { - OriginPosition = new OpenTK.Vector2(0, -(Game as OsuGame).Toolbar.Height), Children = new[] { setList = new FlowContainer { Direction = FlowDirection.VerticalOnly, - Padding = new OpenTK.Vector2(25, 25) + Padding = new MarginPadding(25), } } } @@ -61,10 +64,13 @@ namespace osu.Game.GameModes.Play playMode = osu.PlayMode; playMode.ValueChanged += PlayMode_ValueChanged; + beatmaps = osu.Beatmaps; + + scrollContainer.Padding = new MarginPadding { Top = osu.Toolbar.Height }; addBeatmapSets(); - (Game as OsuGame).Beatmaps.BeatmapSetAdded += bset => setList.Add(createSetUI(bset)); + beatmaps.BeatmapSetAdded += bset => setList.Add(createSetUI(bset)); } protected override void Dispose(bool isDisposing) From bc6e705e2b84a5a67fb6ebd3bdd3ae94eb110a7c Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 13 Oct 2016 15:10:00 -0400 Subject: [PATCH 05/58] Add test case for song selection --- osu.Desktop.VisualTests/Program.cs | 2 +- .../Tests/TestCasePlaySongSelect.cs | 31 ++++++++++ osu.Desktop.VisualTests/VisualTestGame.cs | 1 + .../osu.Desktop.VisualTests.csproj | 1 + osu.Game/GameModes/Play/BeatmapButton.cs | 38 ++++++++++++ osu.Game/GameModes/Play/BeatmapGroup.cs | 62 +++++++++++++++++++ osu.Game/GameModes/Play/PlaySongSelect.cs | 26 ++++---- osu.Game/osu.Game.csproj | 4 +- 8 files changed, 148 insertions(+), 17 deletions(-) create mode 100644 osu.Desktop.VisualTests/Tests/TestCasePlaySongSelect.cs create mode 100644 osu.Game/GameModes/Play/BeatmapButton.cs create mode 100644 osu.Game/GameModes/Play/BeatmapGroup.cs diff --git a/osu.Desktop.VisualTests/Program.cs b/osu.Desktop.VisualTests/Program.cs index 4dcfaff987..52aceb1ee8 100644 --- a/osu.Desktop.VisualTests/Program.cs +++ b/osu.Desktop.VisualTests/Program.cs @@ -12,7 +12,7 @@ namespace osu.Framework.VisualTests [STAThread] public static void Main(string[] args) { - BasicGameHost host = Host.GetSuitableHost(@"osu-visual-tests"); + BasicGameHost host = Host.GetSuitableHost(@"osu"); host.Add(new VisualTestGame()); host.Run(); } diff --git a/osu.Desktop.VisualTests/Tests/TestCasePlaySongSelect.cs b/osu.Desktop.VisualTests/Tests/TestCasePlaySongSelect.cs new file mode 100644 index 0000000000..7dcc7026b1 --- /dev/null +++ b/osu.Desktop.VisualTests/Tests/TestCasePlaySongSelect.cs @@ -0,0 +1,31 @@ +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; +using osu.Framework.GameModes.Testing; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Threading; +using osu.Game; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using osu.Framework.Graphics.Sprites; +using osu.Game.Online.Chat.Display; +using osu.Framework; +using osu.Game.GameModes.Play; + +namespace osu.Desktop.Tests +{ + class TestCasePlaySongSelect : TestCase + { + public override string Name => @"Song Select"; + public override string Description => @"Testing song selection UI"; + + public override void Reset() + { + base.Reset(); + Add(new PlaySongSelect()); + } + } +} diff --git a/osu.Desktop.VisualTests/VisualTestGame.cs b/osu.Desktop.VisualTests/VisualTestGame.cs index 323923591d..5a51f28d82 100644 --- a/osu.Desktop.VisualTests/VisualTestGame.cs +++ b/osu.Desktop.VisualTests/VisualTestGame.cs @@ -3,6 +3,7 @@ using osu.Framework.GameModes.Testing; using osu.Framework.Graphics.Cursor; +using osu.Game.Database; using osu.Game; namespace osu.Framework.VisualTests diff --git a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj index 55de7cf39b..3dfe829651 100644 --- a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj +++ b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj @@ -146,6 +146,7 @@ + diff --git a/osu.Game/GameModes/Play/BeatmapButton.cs b/osu.Game/GameModes/Play/BeatmapButton.cs new file mode 100644 index 0000000000..8a1451e853 --- /dev/null +++ b/osu.Game/GameModes/Play/BeatmapButton.cs @@ -0,0 +1,38 @@ +//Copyright (c) 2007-2016 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.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; +using osu.Game.Beatmaps; +using osu.Game.GameModes.Backgrounds; +using osu.Framework; +using osu.Game.Database; +using osu.Framework.Graphics.Primitives; + +namespace osu.Game.GameModes.Play +{ + class BeatmapButton : FlowContainer + { + private BeatmapSet beatmapSet; + private Beatmap beatmap; + + public BeatmapButton(BeatmapSet set, Beatmap beatmap) + { + this.beatmapSet = set; + this.beatmap = beatmap; + Children = new[] + { + new SpriteText { Text = beatmap.Version }, + }; + } + + public override void Load(BaseGame game) + { + base.Load(game); + } + } +} diff --git a/osu.Game/GameModes/Play/BeatmapGroup.cs b/osu.Game/GameModes/Play/BeatmapGroup.cs new file mode 100644 index 0000000000..3fc29d9528 --- /dev/null +++ b/osu.Game/GameModes/Play/BeatmapGroup.cs @@ -0,0 +1,62 @@ +//Copyright (c) 2007-2016 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.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; +using osu.Game.Beatmaps; +using osu.Game.GameModes.Backgrounds; +using osu.Framework; +using osu.Game.Database; +using osu.Framework.Graphics.Primitives; +using OpenTK; +using System.Linq; +using osu.Framework.Graphics.Drawables; + +namespace osu.Game.GameModes.Play +{ + class BeatmapGroup : FlowContainer + { + private BeatmapSet beatmapSet; + private bool collapsed; + public bool Collapsed + { + get { return collapsed; } + set + { + collapsed = value; + if (collapsed) + Alpha = 0.75f; + else + Alpha = 1; + // TODO: whatever + } + } + + public BeatmapGroup(BeatmapSet beatmapSet) + { + this.beatmapSet = beatmapSet; + this.collapsed = true; + Direction = FlowDirection.VerticalOnly; + Children = new[] + { + new SpriteText() { Text = this.beatmapSet.Metadata.Title, TextSize = 25 }, + new FlowContainer + { + Spacing = new Vector2(0, 10), + Padding = new MarginPadding { Left = 50 }, + Direction = FlowDirection.VerticalOnly, + Children = this.beatmapSet.Beatmaps.Select(b => new BeatmapButton(this.beatmapSet, b)) + }, + }; + } + + public override void Load(BaseGame game) + { + base.Load(game); + } + } +} diff --git a/osu.Game/GameModes/Play/PlaySongSelect.cs b/osu.Game/GameModes/Play/PlaySongSelect.cs index edf144db6f..d0fa70643f 100644 --- a/osu.Game/GameModes/Play/PlaySongSelect.cs +++ b/osu.Game/GameModes/Play/PlaySongSelect.cs @@ -15,7 +15,7 @@ using osu.Framework.Graphics.Primitives; namespace osu.Game.GameModes.Play { - class PlaySongSelect : OsuGameMode + public class PlaySongSelect : OsuGameMode { private Bindable playMode; private BeatmapDatabase beatmaps; @@ -26,16 +26,11 @@ namespace osu.Game.GameModes.Play private ScrollContainer scrollContainer; private FlowContainer setList; - private Drawable createSetUI(BeatmapSet bset) - { - return new SpriteText { Text = bset.Metadata.Title }; - } - private void addBeatmapSets() { var sets = beatmaps.GetBeatmapSets(); foreach (var beatmapSet in sets) - setList.Add(createSetUI(beatmapSet)); + setList.Add(new BeatmapGroup(beatmapSet)); } public PlaySongSelect() @@ -61,16 +56,17 @@ namespace osu.Game.GameModes.Play base.Load(game); OsuGame osu = game as OsuGame; - - playMode = osu.PlayMode; - playMode.ValueChanged += PlayMode_ValueChanged; - beatmaps = osu.Beatmaps; + if (osu != null) + { + playMode = osu.PlayMode; + playMode.ValueChanged += PlayMode_ValueChanged; + // Temporary: + scrollContainer.Padding = new MarginPadding { Top = osu.Toolbar.Height }; + } - scrollContainer.Padding = new MarginPadding { Top = osu.Toolbar.Height }; - + beatmaps = (game as OsuGameBase).Beatmaps; + beatmaps.BeatmapSetAdded += bset => Scheduler.Add(() => setList.Add(new BeatmapGroup(bset))); addBeatmapSets(); - - beatmaps.BeatmapSetAdded += bset => setList.Add(createSetUI(bset)); } protected override void Dispose(bool isDisposing) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 545d777098..10e384ec01 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -116,6 +116,8 @@ + + @@ -215,4 +217,4 @@ --> - \ No newline at end of file + From 71f58285fce4bea3d1f0cb7f2eaf6a233cf580ba Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 13 Oct 2016 16:25:41 -0400 Subject: [PATCH 06/58] Add selection interactions --- osu.Game/GameModes/Play/BeatmapButton.cs | 5 --- osu.Game/GameModes/Play/BeatmapGroup.cs | 54 +++++++++++++++-------- osu.Game/GameModes/Play/PlaySongSelect.cs | 20 ++++++++- 3 files changed, 54 insertions(+), 25 deletions(-) diff --git a/osu.Game/GameModes/Play/BeatmapButton.cs b/osu.Game/GameModes/Play/BeatmapButton.cs index 8a1451e853..8025f1bc16 100644 --- a/osu.Game/GameModes/Play/BeatmapButton.cs +++ b/osu.Game/GameModes/Play/BeatmapButton.cs @@ -29,10 +29,5 @@ namespace osu.Game.GameModes.Play new SpriteText { Text = beatmap.Version }, }; } - - public override void Load(BaseGame game) - { - base.Load(game); - } } } diff --git a/osu.Game/GameModes/Play/BeatmapGroup.cs b/osu.Game/GameModes/Play/BeatmapGroup.cs index 3fc29d9528..5a889d82fa 100644 --- a/osu.Game/GameModes/Play/BeatmapGroup.cs +++ b/osu.Game/GameModes/Play/BeatmapGroup.cs @@ -15,48 +15,66 @@ using osu.Framework.Graphics.Primitives; using OpenTK; using System.Linq; using osu.Framework.Graphics.Drawables; +using osu.Framework.Graphics.Transformations; +using osu.Framework.Input; +using OpenTK.Graphics; namespace osu.Game.GameModes.Play { class BeatmapGroup : FlowContainer { - private BeatmapSet beatmapSet; + public event Action SetSelected; + public event Action BeatmapSelected; + public BeatmapSet BeatmapSet; + private FlowContainer difficulties; private bool collapsed; public bool Collapsed { get { return collapsed; } set { + if (collapsed == value) + return; collapsed = value; + this.ClearTransformations(); + const float collapsedAlpha = 0.75f; + const float uncollapsedAlpha = 1; + Transforms.Add(new TransformAlpha(Clock) + { + StartValue = collapsed ? uncollapsedAlpha : collapsedAlpha, + EndValue = collapsed ? collapsedAlpha : uncollapsedAlpha, + StartTime = Time, + EndTime = Time + 250, + }); if (collapsed) - Alpha = 0.75f; + Remove(difficulties); else - Alpha = 1; - // TODO: whatever + Add(difficulties); } } public BeatmapGroup(BeatmapSet beatmapSet) { - this.beatmapSet = beatmapSet; - this.collapsed = true; + BeatmapSet = beatmapSet; Direction = FlowDirection.VerticalOnly; - Children = new[] + Children = new Drawable[] { - new SpriteText() { Text = this.beatmapSet.Metadata.Title, TextSize = 25 }, - new FlowContainer - { - Spacing = new Vector2(0, 10), - Padding = new MarginPadding { Left = 50 }, - Direction = FlowDirection.VerticalOnly, - Children = this.beatmapSet.Beatmaps.Select(b => new BeatmapButton(this.beatmapSet, b)) - }, + new SpriteText { Text = this.BeatmapSet.Metadata.Title, TextSize = 25 }, }; + difficulties = new FlowContainer // Deliberately not added to children + { + Spacing = new Vector2(0, 10), + Padding = new MarginPadding { Left = 50 }, + Direction = FlowDirection.VerticalOnly, + Children = this.BeatmapSet.Beatmaps.Select(b => new BeatmapButton(this.BeatmapSet, b)) + }; + collapsed = true; } - - public override void Load(BaseGame game) + + protected override bool OnClick(InputState state) { - base.Load(game); + SetSelected?.Invoke(BeatmapSet); + return true; } } } diff --git a/osu.Game/GameModes/Play/PlaySongSelect.cs b/osu.Game/GameModes/Play/PlaySongSelect.cs index d0fa70643f..f86d1b5efd 100644 --- a/osu.Game/GameModes/Play/PlaySongSelect.cs +++ b/osu.Game/GameModes/Play/PlaySongSelect.cs @@ -12,6 +12,7 @@ using osu.Game.GameModes.Backgrounds; using osu.Framework; using osu.Game.Database; using osu.Framework.Graphics.Primitives; +using System.Linq; namespace osu.Game.GameModes.Play { @@ -25,12 +26,26 @@ namespace osu.Game.GameModes.Play private ScrollContainer scrollContainer; private FlowContainer setList; + + private void addBeatmapSet(BeatmapSet beatmapSet) + { + var group = new BeatmapGroup(beatmapSet); + group.SetSelected += (selectedSet) => + { + foreach (var child in setList.Children) + { + var childGroup = child as BeatmapGroup; + childGroup.Collapsed = childGroup.BeatmapSet != selectedSet; + } + }; + setList.Add(group); + } private void addBeatmapSets() { var sets = beatmaps.GetBeatmapSets(); foreach (var beatmapSet in sets) - setList.Add(new BeatmapGroup(beatmapSet)); + addBeatmapSet(beatmapSet); } public PlaySongSelect() @@ -65,8 +80,9 @@ namespace osu.Game.GameModes.Play } beatmaps = (game as OsuGameBase).Beatmaps; - beatmaps.BeatmapSetAdded += bset => Scheduler.Add(() => setList.Add(new BeatmapGroup(bset))); + beatmaps.BeatmapSetAdded += bset => Scheduler.Add(() => addBeatmapSet(bset)); addBeatmapSets(); + (setList.Children.First() as BeatmapGroup).Collapsed = false; } protected override void Dispose(bool isDisposing) From 3d53af155f6d854c985ce12611c6bb508d98eaf4 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 13 Oct 2016 16:55:15 -0400 Subject: [PATCH 07/58] Add background to song select --- osu.Game/GameModes/Play/BeatmapGroup.cs | 24 +++++++++--- osu.Game/GameModes/Play/PlaySongSelect.cs | 47 ++++++++++++++++++++++- 2 files changed, 64 insertions(+), 7 deletions(-) diff --git a/osu.Game/GameModes/Play/BeatmapGroup.cs b/osu.Game/GameModes/Play/BeatmapGroup.cs index 5a889d82fa..8d5ec8f274 100644 --- a/osu.Game/GameModes/Play/BeatmapGroup.cs +++ b/osu.Game/GameModes/Play/BeatmapGroup.cs @@ -21,11 +21,14 @@ using OpenTK.Graphics; namespace osu.Game.GameModes.Play { - class BeatmapGroup : FlowContainer + class BeatmapGroup : AutoSizeContainer { + private const float collapsedAlpha = 0.75f; + public event Action SetSelected; public event Action BeatmapSelected; public BeatmapSet BeatmapSet; + private FlowContainer topContainer; private FlowContainer difficulties; private bool collapsed; public bool Collapsed @@ -37,7 +40,6 @@ namespace osu.Game.GameModes.Play return; collapsed = value; this.ClearTransformations(); - const float collapsedAlpha = 0.75f; const float uncollapsedAlpha = 1; Transforms.Add(new TransformAlpha(Clock) { @@ -47,19 +49,29 @@ namespace osu.Game.GameModes.Play EndTime = Time + 250, }); if (collapsed) - Remove(difficulties); + topContainer.Remove(difficulties); else - Add(difficulties); + topContainer.Add(difficulties); } } public BeatmapGroup(BeatmapSet beatmapSet) { BeatmapSet = beatmapSet; - Direction = FlowDirection.VerticalOnly; + Alpha = collapsedAlpha; Children = new Drawable[] { - new SpriteText { Text = this.BeatmapSet.Metadata.Title, TextSize = 25 }, + new Box + { + Colour = new Color4(0, 0, 0, 0.75f), + RelativeSizeAxes = Axes.Both, + Size = new Vector2(1), + }, + topContainer = new FlowContainer + { + Direction = FlowDirection.VerticalOnly, + Children = new[] { new SpriteText { Text = this.BeatmapSet.Metadata.Title, TextSize = 25 } } + } }; difficulties = new FlowContainer // Deliberately not added to children { diff --git a/osu.Game/GameModes/Play/PlaySongSelect.cs b/osu.Game/GameModes/Play/PlaySongSelect.cs index f86d1b5efd..86dd38f711 100644 --- a/osu.Game/GameModes/Play/PlaySongSelect.cs +++ b/osu.Game/GameModes/Play/PlaySongSelect.cs @@ -12,7 +12,10 @@ using osu.Game.GameModes.Backgrounds; using osu.Framework; using osu.Game.Database; using osu.Framework.Graphics.Primitives; +using osu.Framework.Graphics.Drawables; using System.Linq; +using OpenTK; +using OpenTK.Graphics; namespace osu.Game.GameModes.Play { @@ -50,10 +53,30 @@ namespace osu.Game.GameModes.Play public PlaySongSelect() { - Children = new[] + const float backgroundWidth = 0.6f; + const float backgroundSlant = 25; + Children = new Drawable[] { + new BackgroundBox(backgroundSlant) + { + RelativeSizeAxes = Axes.Both, + Size = new Vector2(backgroundWidth, 0.5f), + Colour = new Color4(0, 0, 0, 0.5f), + }, + new BackgroundBox(-backgroundSlant) + { + RelativeSizeAxes = Axes.Both, + RelativePositionAxes = Axes.Y, + Size = new Vector2(backgroundWidth, 0.5f), + Position = new Vector2(0, 0.5f), + Colour = new Color4(0, 0, 0, 0.5f), + }, scrollContainer = new ScrollContainer { + RelativeSizeAxes = Axes.Both, + RelativePositionAxes = Axes.Both, + Size = new Vector2(0.5f, 1), + Position = new Vector2(0.5f, 0), Children = new[] { setList = new FlowContainer @@ -95,5 +118,27 @@ namespace osu.Game.GameModes.Play private void PlayMode_ValueChanged(object sender, EventArgs e) { } + + class BackgroundBox : Box + { + private float wedgeWidth; + + public BackgroundBox(float wedgeWidth) + { + this.wedgeWidth = wedgeWidth; + } + + protected override Quad DrawQuad + { + get + { + Quad q = base.DrawQuad; + q.TopRight.X += wedgeWidth; + q.BottomRight.X -= wedgeWidth; + return q; + } + } + + } } } From e13374ed238321ce495b0a8c2ca8a52646e88cae Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 13 Oct 2016 17:27:08 -0400 Subject: [PATCH 08/58] Tweak layout of beatmap groups --- osu.Game/GameModes/Play/BeatmapGroup.cs | 28 +++++++++++++++-------- osu.Game/GameModes/Play/PlaySongSelect.cs | 1 + 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/osu.Game/GameModes/Play/BeatmapGroup.cs b/osu.Game/GameModes/Play/BeatmapGroup.cs index 8d5ec8f274..8f0b6c6181 100644 --- a/osu.Game/GameModes/Play/BeatmapGroup.cs +++ b/osu.Game/GameModes/Play/BeatmapGroup.cs @@ -59,24 +59,34 @@ namespace osu.Game.GameModes.Play { BeatmapSet = beatmapSet; Alpha = collapsedAlpha; - Children = new Drawable[] + Children = new[] { - new Box - { - Colour = new Color4(0, 0, 0, 0.75f), - RelativeSizeAxes = Axes.Both, - Size = new Vector2(1), - }, topContainer = new FlowContainer { Direction = FlowDirection.VerticalOnly, - Children = new[] { new SpriteText { Text = this.BeatmapSet.Metadata.Title, TextSize = 25 } } + Children = new[] + { + new AutoSizeContainer + { + Children = new Drawable[] + { + new Box + { + Colour = new Color4(0, 0, 0, 0.75f), + RelativeSizeAxes = Axes.Both, + Size = new Vector2(1), + }, + new SpriteText { Text = this.BeatmapSet.Metadata.Title, TextSize = 25 } + } + } + } } }; difficulties = new FlowContainer // Deliberately not added to children { - Spacing = new Vector2(0, 10), + Margin = new MarginPadding { Top = 10 }, Padding = new MarginPadding { Left = 50 }, + Spacing = new Vector2(0, 10), Direction = FlowDirection.VerticalOnly, Children = this.BeatmapSet.Beatmaps.Select(b => new BeatmapButton(this.BeatmapSet, b)) }; diff --git a/osu.Game/GameModes/Play/PlaySongSelect.cs b/osu.Game/GameModes/Play/PlaySongSelect.cs index 86dd38f711..3889c5c0f1 100644 --- a/osu.Game/GameModes/Play/PlaySongSelect.cs +++ b/osu.Game/GameModes/Play/PlaySongSelect.cs @@ -83,6 +83,7 @@ namespace osu.Game.GameModes.Play { Direction = FlowDirection.VerticalOnly, Padding = new MarginPadding(25), + Spacing = new Vector2(0, 25), } } } From 7a22c60c7c0861b69c0dc81131e3c95872bdef4b Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 13 Oct 2016 18:15:43 -0400 Subject: [PATCH 09/58] Get some more of the design's layout in place --- osu.Game/GameModes/Play/BeatmapButton.cs | 42 +++++++++- osu.Game/GameModes/Play/BeatmapGroup.cs | 98 +++++++++++++++++------ osu.Game/GameModes/Play/PlaySongSelect.cs | 24 +++--- 3 files changed, 127 insertions(+), 37 deletions(-) diff --git a/osu.Game/GameModes/Play/BeatmapButton.cs b/osu.Game/GameModes/Play/BeatmapButton.cs index 8025f1bc16..f09a890e30 100644 --- a/osu.Game/GameModes/Play/BeatmapButton.cs +++ b/osu.Game/GameModes/Play/BeatmapButton.cs @@ -12,10 +12,14 @@ using osu.Game.GameModes.Backgrounds; using osu.Framework; using osu.Game.Database; using osu.Framework.Graphics.Primitives; +using osu.Framework.Graphics.Drawables; +using OpenTK.Graphics; +using OpenTK; +using osu.Game.Graphics; namespace osu.Game.GameModes.Play { - class BeatmapButton : FlowContainer + class BeatmapButton : AutoSizeContainer { private BeatmapSet beatmapSet; private Beatmap beatmap; @@ -24,9 +28,41 @@ namespace osu.Game.GameModes.Play { this.beatmapSet = set; this.beatmap = beatmap; - Children = new[] + Children = new Drawable[] { - new SpriteText { Text = beatmap.Version }, + new Box + { + Colour = new Color4(40, 86, 102, 255), // TODO: texture + RelativeSizeAxes = Axes.Both, + Size = new Vector2(1), + }, + new FlowContainer + { + Padding = new MarginPadding(5), + Direction = FlowDirection.HorizontalOnly, + Children = new Drawable[] + { + new DifficultyIcon(FontAwesome.dot_circle_o, new Color4(159, 198, 0, 255)), + new FlowContainer + { + Padding = new MarginPadding { Left = 10 }, + Direction = FlowDirection.HorizontalOnly, + Children = new[] + { + new SpriteText + { + Text = beatmap.Version, + TextSize = 20, + }, + new SpriteText + { + Text = string.Format(" mapped by {0}", beatmap.Version), + TextSize = 16, + }, + } + } + } + } }; } } diff --git a/osu.Game/GameModes/Play/BeatmapGroup.cs b/osu.Game/GameModes/Play/BeatmapGroup.cs index 8f0b6c6181..17952c7e42 100644 --- a/osu.Game/GameModes/Play/BeatmapGroup.cs +++ b/osu.Game/GameModes/Play/BeatmapGroup.cs @@ -2,15 +2,11 @@ //Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; -using System.Collections.Generic; -using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; +using osu.Game.Graphics; using osu.Game.Beatmaps; -using osu.Game.GameModes.Backgrounds; -using osu.Framework; -using osu.Game.Database; using osu.Framework.Graphics.Primitives; using OpenTK; using System.Linq; @@ -23,7 +19,7 @@ namespace osu.Game.GameModes.Play { class BeatmapGroup : AutoSizeContainer { - private const float collapsedAlpha = 0.75f; + private const float collapsedAlpha = 0.3f; public event Action SetSelected; public event Action BeatmapSelected; @@ -64,29 +60,14 @@ namespace osu.Game.GameModes.Play topContainer = new FlowContainer { Direction = FlowDirection.VerticalOnly, - Children = new[] - { - new AutoSizeContainer - { - Children = new Drawable[] - { - new Box - { - Colour = new Color4(0, 0, 0, 0.75f), - RelativeSizeAxes = Axes.Both, - Size = new Vector2(1), - }, - new SpriteText { Text = this.BeatmapSet.Metadata.Title, TextSize = 25 } - } - } - } + Children = new[] { new BeatmapSetBox(beatmapSet) } } }; difficulties = new FlowContainer // Deliberately not added to children { - Margin = new MarginPadding { Top = 10 }, - Padding = new MarginPadding { Left = 50 }, - Spacing = new Vector2(0, 10), + Margin = new MarginPadding { Top = 5 }, + Padding = new MarginPadding { Left = 25 }, + Spacing = new Vector2(0, 5), Direction = FlowDirection.VerticalOnly, Children = this.BeatmapSet.Beatmaps.Select(b => new BeatmapButton(this.BeatmapSet, b)) }; @@ -99,4 +80,71 @@ namespace osu.Game.GameModes.Play return true; } } + + class BeatmapSetBox : AutoSizeContainer + { + private BeatmapSet beatmapSet; + + public BeatmapSetBox(BeatmapSet beatmapSet) + { + this.beatmapSet = beatmapSet; + Children = new Drawable[] + { + new Box + { + Colour = new Color4(85, 85, 85, 255), // TODO: Gradient, and beatmap texture + RelativeSizeAxes = Axes.Both, + Size = new Vector2(1), + }, + new FlowContainer + { + Direction = FlowDirection.VerticalOnly, + Spacing = new Vector2(0, 2), + Padding = new MarginPadding { Top = 3, Left = 20, Right = 20, Bottom = 3 }, + Children = new[] + { + // TODO: Make these italic + new SpriteText + { + Text = this.beatmapSet.Metadata.TitleUnicode ?? this.beatmapSet.Metadata.Title, + TextSize = 20 + }, + new SpriteText + { + Text = this.beatmapSet.Metadata.ArtistUnicode ?? this.beatmapSet.Metadata.Artist, + TextSize = 16 + }, + new FlowContainer + { + Children = new[] + { + new DifficultyIcon(FontAwesome.dot_circle_o, new Color4(159, 198, 0, 255)), + new DifficultyIcon(FontAwesome.dot_circle_o, new Color4(246, 101, 166, 255)), + } + } + } + } + }; + } + } + + class DifficultyIcon : Container + { + public DifficultyIcon(FontAwesome icon, Color4 color) + { + const float size = 20; + Size = new Vector2(size); + Children = new[] + { + new TextAwesome + { + Anchor = Anchor.Centre, + TextSize = size, + Size = new Vector2(size), + Colour = color, + Icon = icon + } + }; + } + } } diff --git a/osu.Game/GameModes/Play/PlaySongSelect.cs b/osu.Game/GameModes/Play/PlaySongSelect.cs index 3889c5c0f1..d371689e7f 100644 --- a/osu.Game/GameModes/Play/PlaySongSelect.cs +++ b/osu.Game/GameModes/Play/PlaySongSelect.cs @@ -23,6 +23,7 @@ namespace osu.Game.GameModes.Play { private Bindable playMode; private BeatmapDatabase beatmaps; + private BeatmapSet selectedBeatmapSet; // TODO: use currently selected track as bg protected override BackgroundMode CreateBackground() => new BackgroundModeCustom(@"Backgrounds/bg4"); @@ -30,17 +31,20 @@ namespace osu.Game.GameModes.Play private ScrollContainer scrollContainer; private FlowContainer setList; + private void selectBeatmapSet(BeatmapSet beatmapSet) + { + selectedBeatmapSet = beatmapSet; + foreach (var child in setList.Children) + { + var childGroup = child as BeatmapGroup; + childGroup.Collapsed = childGroup.BeatmapSet != beatmapSet; + } + } + private void addBeatmapSet(BeatmapSet beatmapSet) { var group = new BeatmapGroup(beatmapSet); - group.SetSelected += (selectedSet) => - { - foreach (var child in setList.Children) - { - var childGroup = child as BeatmapGroup; - childGroup.Collapsed = childGroup.BeatmapSet != selectedSet; - } - }; + group.SetSelected += (selectedSet) => selectBeatmapSet(selectedSet); setList.Add(group); } @@ -106,7 +110,9 @@ namespace osu.Game.GameModes.Play beatmaps = (game as OsuGameBase).Beatmaps; beatmaps.BeatmapSetAdded += bset => Scheduler.Add(() => addBeatmapSet(bset)); addBeatmapSets(); - (setList.Children.First() as BeatmapGroup).Collapsed = false; + var first = setList.Children.First() as BeatmapGroup; + first.Collapsed = false; + selectedBeatmapSet = first.BeatmapSet; } protected override void Dispose(bool isDisposing) From 07e44560be5aec26086b7f73efafc9a513032d3b Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 13 Oct 2016 18:20:08 -0400 Subject: [PATCH 10/58] Use beatmap author in listing --- osu.Game/GameModes/Play/BeatmapButton.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/GameModes/Play/BeatmapButton.cs b/osu.Game/GameModes/Play/BeatmapButton.cs index f09a890e30..377ec9099f 100644 --- a/osu.Game/GameModes/Play/BeatmapButton.cs +++ b/osu.Game/GameModes/Play/BeatmapButton.cs @@ -56,7 +56,7 @@ namespace osu.Game.GameModes.Play }, new SpriteText { - Text = string.Format(" mapped by {0}", beatmap.Version), + Text = string.Format(" mapped by {0}", (beatmap.Metadata ?? set.Metadata).Author), TextSize = 16, }, } From 05d803483f4382b0ffe98480eecac4fd226d0da9 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 13 Oct 2016 20:48:36 -0400 Subject: [PATCH 11/58] Fix width of beatmaps --- osu.Game/GameModes/Play/BeatmapButton.cs | 2 ++ osu.Game/GameModes/Play/BeatmapGroup.cs | 8 ++++++++ osu.Game/GameModes/Play/PlaySongSelect.cs | 5 +++-- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/osu.Game/GameModes/Play/BeatmapButton.cs b/osu.Game/GameModes/Play/BeatmapButton.cs index 377ec9099f..5182fe71cb 100644 --- a/osu.Game/GameModes/Play/BeatmapButton.cs +++ b/osu.Game/GameModes/Play/BeatmapButton.cs @@ -28,6 +28,8 @@ namespace osu.Game.GameModes.Play { this.beatmapSet = set; this.beatmap = beatmap; + RelativeSizeAxes = Axes.X; + Size = new Vector2(1, 0); Children = new Drawable[] { new Box diff --git a/osu.Game/GameModes/Play/BeatmapGroup.cs b/osu.Game/GameModes/Play/BeatmapGroup.cs index 17952c7e42..752e6fe940 100644 --- a/osu.Game/GameModes/Play/BeatmapGroup.cs +++ b/osu.Game/GameModes/Play/BeatmapGroup.cs @@ -55,16 +55,22 @@ namespace osu.Game.GameModes.Play { BeatmapSet = beatmapSet; Alpha = collapsedAlpha; + RelativeSizeAxes = Axes.X; + Size = new Vector2(1, 0); Children = new[] { topContainer = new FlowContainer { + RelativeSizeAxes = Axes.X, + Size = new Vector2(1, 0), Direction = FlowDirection.VerticalOnly, Children = new[] { new BeatmapSetBox(beatmapSet) } } }; difficulties = new FlowContainer // Deliberately not added to children { + RelativeSizeAxes = Axes.X, + Size = new Vector2(1, 0), Margin = new MarginPadding { Top = 5 }, Padding = new MarginPadding { Left = 25 }, Spacing = new Vector2(0, 5), @@ -88,6 +94,8 @@ namespace osu.Game.GameModes.Play public BeatmapSetBox(BeatmapSet beatmapSet) { this.beatmapSet = beatmapSet; + RelativeSizeAxes = Axes.X; + Size = new Vector2(1, 0); Children = new Drawable[] { new Box diff --git a/osu.Game/GameModes/Play/PlaySongSelect.cs b/osu.Game/GameModes/Play/PlaySongSelect.cs index d371689e7f..3f943c07a9 100644 --- a/osu.Game/GameModes/Play/PlaySongSelect.cs +++ b/osu.Game/GameModes/Play/PlaySongSelect.cs @@ -81,12 +81,13 @@ namespace osu.Game.GameModes.Play RelativePositionAxes = Axes.Both, Size = new Vector2(0.5f, 1), Position = new Vector2(0.5f, 0), - Children = new[] + Children = new Drawable[] { setList = new FlowContainer { + RelativeSizeAxes = Axes.X, + Size = new Vector2(1, 0), Direction = FlowDirection.VerticalOnly, - Padding = new MarginPadding(25), Spacing = new Vector2(0, 25), } } From 9b887982742f92e7e24d468065a441985b687fc4 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 13 Oct 2016 21:40:44 -0400 Subject: [PATCH 12/58] Fix up padding on song select @peppy btw scrolling beyond the ends of the ScrollContainer behaves weirdly for this container --- osu.Game/GameModes/Play/PlaySongSelect.cs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/osu.Game/GameModes/Play/PlaySongSelect.cs b/osu.Game/GameModes/Play/PlaySongSelect.cs index 3f943c07a9..9788debc9f 100644 --- a/osu.Game/GameModes/Play/PlaySongSelect.cs +++ b/osu.Game/GameModes/Play/PlaySongSelect.cs @@ -30,7 +30,7 @@ namespace osu.Game.GameModes.Play private ScrollContainer scrollContainer; private FlowContainer setList; - + private void selectBeatmapSet(BeatmapSet beatmapSet) { selectedBeatmapSet = beatmapSet; @@ -40,7 +40,7 @@ namespace osu.Game.GameModes.Play childGroup.Collapsed = childGroup.BeatmapSet != beatmapSet; } } - + private void addBeatmapSet(BeatmapSet beatmapSet) { var group = new BeatmapGroup(beatmapSet); @@ -54,7 +54,7 @@ namespace osu.Game.GameModes.Play foreach (var beatmapSet in sets) addBeatmapSet(beatmapSet); } - + public PlaySongSelect() { const float backgroundWidth = 0.6f; @@ -85,6 +85,7 @@ namespace osu.Game.GameModes.Play { setList = new FlowContainer { + Padding = new MarginPadding { Top = 25, Bottom = 25 }, RelativeSizeAxes = Axes.X, Size = new Vector2(1, 0), Direction = FlowDirection.VerticalOnly, @@ -107,7 +108,7 @@ namespace osu.Game.GameModes.Play // Temporary: scrollContainer.Padding = new MarginPadding { Top = osu.Toolbar.Height }; } - + beatmaps = (game as OsuGameBase).Beatmaps; beatmaps.BeatmapSetAdded += bset => Scheduler.Add(() => addBeatmapSet(bset)); addBeatmapSets(); @@ -126,7 +127,7 @@ namespace osu.Game.GameModes.Play private void PlayMode_ValueChanged(object sender, EventArgs e) { } - + class BackgroundBox : Box { private float wedgeWidth; @@ -146,7 +147,7 @@ namespace osu.Game.GameModes.Play return q; } } - + } } } From 9a66d766e995474f95a5d68773cc8d6430aaaf4a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 14 Oct 2016 13:32:08 +0900 Subject: [PATCH 13/58] Don't bail on no beatmaps in database. --- osu.Game/GameModes/Play/PlaySongSelect.cs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/osu.Game/GameModes/Play/PlaySongSelect.cs b/osu.Game/GameModes/Play/PlaySongSelect.cs index 9788debc9f..6353848607 100644 --- a/osu.Game/GameModes/Play/PlaySongSelect.cs +++ b/osu.Game/GameModes/Play/PlaySongSelect.cs @@ -51,6 +51,9 @@ namespace osu.Game.GameModes.Play private void addBeatmapSets() { var sets = beatmaps.GetBeatmapSets(); + + if (sets.Length == 0) return; + foreach (var beatmapSet in sets) addBeatmapSet(beatmapSet); } @@ -112,9 +115,12 @@ namespace osu.Game.GameModes.Play beatmaps = (game as OsuGameBase).Beatmaps; beatmaps.BeatmapSetAdded += bset => Scheduler.Add(() => addBeatmapSet(bset)); addBeatmapSets(); - var first = setList.Children.First() as BeatmapGroup; - first.Collapsed = false; - selectedBeatmapSet = first.BeatmapSet; + var first = setList.Children.FirstOrDefault() as BeatmapGroup; + if (first != null) + { + first.Collapsed = false; + selectedBeatmapSet = first.BeatmapSet; + } } protected override void Dispose(bool isDisposing) From 942662985306d719fbe2876a03a2ac6f492382d2 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Fri, 14 Oct 2016 10:47:44 -0400 Subject: [PATCH 14/58] Don't crash if you leave and return to song select During visual tests --- osu.Game/GameModes/Play/PlaySongSelect.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/GameModes/Play/PlaySongSelect.cs b/osu.Game/GameModes/Play/PlaySongSelect.cs index 6353848607..e7f2c141bf 100644 --- a/osu.Game/GameModes/Play/PlaySongSelect.cs +++ b/osu.Game/GameModes/Play/PlaySongSelect.cs @@ -126,8 +126,8 @@ namespace osu.Game.GameModes.Play protected override void Dispose(bool isDisposing) { base.Dispose(isDisposing); - - playMode.ValueChanged -= PlayMode_ValueChanged; + if (playMode != null) + playMode.ValueChanged -= PlayMode_ValueChanged; } private void PlayMode_ValueChanged(object sender, EventArgs e) From 8e31965fb44b6c4895fa080408a62cd6049c54d8 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Fri, 14 Oct 2016 14:10:01 -0400 Subject: [PATCH 15/58] Refactor beatmap import secondary process Doesn't launch a new game window and now supports several files at once. --- osu.Desktop/Program.cs | 18 ++++++++++++++++-- osu.Game/OsuGame.cs | 16 ++-------------- osu.Game/OsuGameBase.cs | 7 +++++-- 3 files changed, 23 insertions(+), 18 deletions(-) diff --git a/osu.Desktop/Program.cs b/osu.Desktop/Program.cs index a1a29b918f..c78ea962ff 100644 --- a/osu.Desktop/Program.cs +++ b/osu.Desktop/Program.cs @@ -2,6 +2,9 @@ //Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using System.IO; +using System.Linq; +using osu.Framework; using osu.Framework.Desktop; using osu.Framework.Platform; using osu.Game; @@ -11,11 +14,22 @@ namespace osu.Desktop public static class Program { [STAThread] - public static void Main(string[] args) + public static int Main(string[] args) { BasicGameHost host = Host.GetSuitableHost(@"osu"); - host.Add(new OsuGame(args)); + BaseGame osuGame = new OsuGame(); + if (args.Length != 0 && args.All(File.Exists)) + { + host.Load(osuGame); + var beatmapIPC = new IpcChannel(host); + foreach (var file in args) + beatmapIPC.SendMessage(new OsuGame.ImportBeatmap { Path = file }).Wait(); + Console.WriteLine(@"Sent file to running instance"); + return 0; + } + host.Add(osuGame); host.Run(); + return 0; } } } diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index b0a4ec94e8..11fc3fd33c 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -28,7 +28,7 @@ namespace osu.Game { public class OsuGame : OsuGameBase { - private class ImportBeatmap + public class ImportBeatmap { public string Path; } @@ -37,16 +37,10 @@ namespace osu.Game public ChatConsole Chat; public MainMenu MainMenu => intro?.ChildGameMode as MainMenu; private Intro intro; - private string[] args; private IpcChannel BeatmapIPC; public Bindable PlayMode; - public OsuGame(string[] args) - { - this.args = args; - } - public override void SetHost(BasicGameHost host) { base.SetHost(host); @@ -60,13 +54,7 @@ namespace osu.Game if (!Host.IsPrimaryInstance) { - if (args.Length == 1 && File.Exists(args[0])) - { - BeatmapIPC.SendMessage(new ImportBeatmap { Path = args[0] }).Wait(); - Logger.Log(@"Sent file to running instance"); - } - else - Logger.Log(@"osu! does not support multiple running instances.", LoggingTarget.Runtime, LogLevel.Error); + Logger.Log(@"osu! does not support multiple running instances.", LoggingTarget.Runtime, LogLevel.Error); Environment.Exit(0); } diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 2d20faeeb1..ba6dd19506 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -72,8 +72,11 @@ namespace osu.Game protected override void Dispose(bool isDisposing) { //refresh token may have changed. - Config.Set(OsuConfig.Token, API.Token); - Config.Save(); + if (Config != null && API != null) + { + Config.Set(OsuConfig.Token, API.Token); + Config.Save(); + } base.Dispose(isDisposing); } From c41b3d92c69800e6cb9fd66a6ceff4219c62b73a Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Wed, 19 Oct 2016 10:47:23 -0400 Subject: [PATCH 16/58] Fix up wrt upstream development --- osu.Game/Database/BeatmapInfo.cs | 2 +- osu.Game/Database/BeatmapSetInfo.cs | 5 ++- osu.Game/GameModes/Play/BeatmapButton.cs | 7 ++-- osu.Game/GameModes/Play/BeatmapGroup.cs | 14 ++++---- osu.Game/GameModes/Play/PlaySongSelect.cs | 39 ++++------------------- 5 files changed, 21 insertions(+), 46 deletions(-) diff --git a/osu.Game/Database/BeatmapInfo.cs b/osu.Game/Database/BeatmapInfo.cs index 540450d19e..3dd45a0c2b 100644 --- a/osu.Game/Database/BeatmapInfo.cs +++ b/osu.Game/Database/BeatmapInfo.cs @@ -17,7 +17,7 @@ namespace osu.Game.Database [PrimaryKey] public int BeatmapID { get; set; } - [NotNull, Indexed] + [ForeignKey(typeof(BeatmapSetInfo)), NotNull] public int BeatmapSetID { get; set; } [ForeignKey(typeof(BeatmapMetadata))] public int BeatmapMetadataID { get; set; } diff --git a/osu.Game/Database/BeatmapSetInfo.cs b/osu.Game/Database/BeatmapSetInfo.cs index 97b3359510..414b6b09f8 100644 --- a/osu.Game/Database/BeatmapSetInfo.cs +++ b/osu.Game/Database/BeatmapSetInfo.cs @@ -1,5 +1,6 @@ using System; -using SQLite.Net.Attributes; +using System.Collections.Generic; +using SQLite.Net.Attributes; using SQLiteNetExtensions.Attributes; namespace osu.Game.Database @@ -12,6 +13,8 @@ namespace osu.Game.Database public BeatmapMetadata Metadata { get; set; } [NotNull, ForeignKey(typeof(BeatmapMetadata))] public int BeatmapMetadataID { get; set; } + [OneToMany] + public List Beatmaps { get; set; } public string Hash { get; set; } public string Path { get; set; } } diff --git a/osu.Game/GameModes/Play/BeatmapButton.cs b/osu.Game/GameModes/Play/BeatmapButton.cs index 5182fe71cb..9700ed5bf7 100644 --- a/osu.Game/GameModes/Play/BeatmapButton.cs +++ b/osu.Game/GameModes/Play/BeatmapButton.cs @@ -12,7 +12,6 @@ using osu.Game.GameModes.Backgrounds; using osu.Framework; using osu.Game.Database; using osu.Framework.Graphics.Primitives; -using osu.Framework.Graphics.Drawables; using OpenTK.Graphics; using OpenTK; using osu.Game.Graphics; @@ -21,10 +20,10 @@ namespace osu.Game.GameModes.Play { class BeatmapButton : AutoSizeContainer { - private BeatmapSet beatmapSet; - private Beatmap beatmap; + private BeatmapSetInfo beatmapSet; + private BeatmapInfo beatmap; - public BeatmapButton(BeatmapSet set, Beatmap beatmap) + public BeatmapButton(BeatmapSetInfo set, BeatmapInfo beatmap) { this.beatmapSet = set; this.beatmap = beatmap; diff --git a/osu.Game/GameModes/Play/BeatmapGroup.cs b/osu.Game/GameModes/Play/BeatmapGroup.cs index 752e6fe940..280952e58b 100644 --- a/osu.Game/GameModes/Play/BeatmapGroup.cs +++ b/osu.Game/GameModes/Play/BeatmapGroup.cs @@ -7,10 +7,10 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Game.Graphics; using osu.Game.Beatmaps; +using osu.Game.Database; using osu.Framework.Graphics.Primitives; using OpenTK; using System.Linq; -using osu.Framework.Graphics.Drawables; using osu.Framework.Graphics.Transformations; using osu.Framework.Input; using OpenTK.Graphics; @@ -21,9 +21,9 @@ namespace osu.Game.GameModes.Play { private const float collapsedAlpha = 0.3f; - public event Action SetSelected; - public event Action BeatmapSelected; - public BeatmapSet BeatmapSet; + public event Action SetSelected; + public event Action BeatmapSelected; + public BeatmapSetInfo BeatmapSet; private FlowContainer topContainer; private FlowContainer difficulties; private bool collapsed; @@ -51,7 +51,7 @@ namespace osu.Game.GameModes.Play } } - public BeatmapGroup(BeatmapSet beatmapSet) + public BeatmapGroup(BeatmapSetInfo beatmapSet) { BeatmapSet = beatmapSet; Alpha = collapsedAlpha; @@ -89,9 +89,9 @@ namespace osu.Game.GameModes.Play class BeatmapSetBox : AutoSizeContainer { - private BeatmapSet beatmapSet; + private BeatmapSetInfo beatmapSet; - public BeatmapSetBox(BeatmapSet beatmapSet) + public BeatmapSetBox(BeatmapSetInfo beatmapSet) { this.beatmapSet = beatmapSet; RelativeSizeAxes = Axes.X; diff --git a/osu.Game/GameModes/Play/PlaySongSelect.cs b/osu.Game/GameModes/Play/PlaySongSelect.cs index e7f2c141bf..d6726840c7 100644 --- a/osu.Game/GameModes/Play/PlaySongSelect.cs +++ b/osu.Game/GameModes/Play/PlaySongSelect.cs @@ -12,7 +12,6 @@ using osu.Game.GameModes.Backgrounds; using osu.Framework; using osu.Game.Database; using osu.Framework.Graphics.Primitives; -using osu.Framework.Graphics.Drawables; using System.Linq; using OpenTK; using OpenTK.Graphics; @@ -23,7 +22,7 @@ namespace osu.Game.GameModes.Play { private Bindable playMode; private BeatmapDatabase beatmaps; - private BeatmapSet selectedBeatmapSet; + private BeatmapSetInfo selectedBeatmapSet; // TODO: use currently selected track as bg protected override BackgroundMode CreateBackground() => new BackgroundModeCustom(@"Backgrounds/bg4"); @@ -31,7 +30,7 @@ namespace osu.Game.GameModes.Play private ScrollContainer scrollContainer; private FlowContainer setList; - private void selectBeatmapSet(BeatmapSet beatmapSet) + private void selectBeatmapSet(BeatmapSetInfo beatmapSet) { selectedBeatmapSet = beatmapSet; foreach (var child in setList.Children) @@ -41,7 +40,7 @@ namespace osu.Game.GameModes.Play } } - private void addBeatmapSet(BeatmapSet beatmapSet) + private void addBeatmapSet(BeatmapSetInfo beatmapSet) { var group = new BeatmapGroup(beatmapSet); group.SetSelected += (selectedSet) => selectBeatmapSet(selectedSet); @@ -50,11 +49,7 @@ namespace osu.Game.GameModes.Play private void addBeatmapSets() { - var sets = beatmaps.GetBeatmapSets(); - - if (sets.Length == 0) return; - - foreach (var beatmapSet in sets) + foreach (var beatmapSet in beatmaps.Query()) addBeatmapSet(beatmapSet); } @@ -64,13 +59,13 @@ namespace osu.Game.GameModes.Play const float backgroundSlant = 25; Children = new Drawable[] { - new BackgroundBox(backgroundSlant) + new Box { RelativeSizeAxes = Axes.Both, Size = new Vector2(backgroundWidth, 0.5f), Colour = new Color4(0, 0, 0, 0.5f), }, - new BackgroundBox(-backgroundSlant) + new Box { RelativeSizeAxes = Axes.Both, RelativePositionAxes = Axes.Y, @@ -133,27 +128,5 @@ namespace osu.Game.GameModes.Play private void PlayMode_ValueChanged(object sender, EventArgs e) { } - - class BackgroundBox : Box - { - private float wedgeWidth; - - public BackgroundBox(float wedgeWidth) - { - this.wedgeWidth = wedgeWidth; - } - - protected override Quad DrawQuad - { - get - { - Quad q = base.DrawQuad; - q.TopRight.X += wedgeWidth; - q.BottomRight.X -= wedgeWidth; - return q; - } - } - - } } } From 641855c79082f9848360a1d6fa2e362cd3bc3dee Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Wed, 19 Oct 2016 11:00:11 -0400 Subject: [PATCH 17/58] Fix issues with beatmap import file contention --- osu.Game/Beatmaps/IO/OszArchiveReader.cs | 11 +++++--- osu.Game/Database/BeatmapDatabase.cs | 36 ++++++++++++------------ 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/osu.Game/Beatmaps/IO/OszArchiveReader.cs b/osu.Game/Beatmaps/IO/OszArchiveReader.cs index 8b677d0145..edfaca7708 100644 --- a/osu.Game/Beatmaps/IO/OszArchiveReader.cs +++ b/osu.Game/Beatmaps/IO/OszArchiveReader.cs @@ -19,13 +19,15 @@ namespace osu.Game.Beatmaps.IO }); OsuLegacyDecoder.Register(); } - - private ZipFile archive { get; set; } - private string[] beatmaps { get; set; } - private Beatmap firstMap { get; set; } + + private Stream archiveStream; + private ZipFile archive; + private string[] beatmaps; + private Beatmap firstMap; public OszArchiveReader(Stream archiveStream) { + this.archiveStream = archiveStream; archive = ZipFile.Read(archiveStream); beatmaps = archive.Entries.Where(e => e.FileName.EndsWith(@".osu")) .Select(e => e.FileName).ToArray(); @@ -59,6 +61,7 @@ namespace osu.Game.Beatmaps.IO public override void Dispose() { archive.Dispose(); + archiveStream.Dispose(); } } } \ No newline at end of file diff --git a/osu.Game/Database/BeatmapDatabase.cs b/osu.Game/Database/BeatmapDatabase.cs index 082047f56b..e09e84def1 100644 --- a/osu.Game/Database/BeatmapDatabase.cs +++ b/osu.Game/Database/BeatmapDatabase.cs @@ -34,8 +34,9 @@ namespace osu.Game.Database public void ImportBeatmap(string path) { string hash = null; - var reader = ArchiveReader.GetReader(storage, path); - var metadata = reader.ReadMetadata(); + BeatmapMetadata metadata; + using (var reader = ArchiveReader.GetReader(storage, path)) + metadata = reader.ReadMetadata(); if (connection.Table().Count(b => b.BeatmapSetID == metadata.BeatmapSetID) != 0) return; // TODO: Update this beatmap instead if (File.Exists(path)) // Not always the case, i.e. for LegacyFilesystemReader @@ -50,32 +51,31 @@ namespace osu.Game.Database input.CopyTo(output); } } - string[] mapNames = reader.ReadBeatmaps(); var beatmapSet = new BeatmapSetInfo { BeatmapSetID = metadata.BeatmapSetID, Path = path, Hash = hash, }; + beatmapSet.Metadata = metadata; var maps = new List(); - foreach (var name in mapNames) + using (var reader = ArchiveReader.GetReader(storage, path)) { - using (var stream = new StreamReader(reader.ReadFile(name))) + string[] mapNames = reader.ReadBeatmaps(); + foreach (var name in mapNames) { - var decoder = BeatmapDecoder.GetDecoder(stream); - Beatmap beatmap = decoder.Decode(stream); - beatmap.BeatmapInfo.Path = name; - // TODO: Diff beatmap metadata with set metadata and insert if necessary - beatmap.BeatmapInfo.Metadata = null; - maps.Add(beatmap.BeatmapInfo); - connection.Insert(beatmap.BeatmapInfo.BaseDifficulty); - connection.Insert(beatmap.BeatmapInfo); - connection.UpdateWithChildren(beatmap.BeatmapInfo); + using (var stream = new StreamReader(reader.ReadFile(name))) + { + var decoder = BeatmapDecoder.GetDecoder(stream); + Beatmap beatmap = decoder.Decode(stream); + beatmap.BeatmapInfo.Path = name; + // TODO: Diff beatmap metadata with set metadata and leave it here if necessary + beatmap.BeatmapInfo.Metadata = null; + maps.Add(beatmap.BeatmapInfo); + } } } - connection.Insert(beatmapSet); - beatmapSet.BeatmapMetadataID = connection.Insert(metadata); - connection.UpdateWithChildren(beatmapSet); + connection.InsertWithChildren(beatmapSet); BeatmapSetAdded?.Invoke(beatmapSet); } @@ -127,4 +127,4 @@ namespace osu.Game.Database connection.Update(record); } } -} +} From 3ee0bf2b805f0071375648a820404c23014166fd Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Wed, 19 Oct 2016 12:51:18 -0400 Subject: [PATCH 18/58] Fix cascade insert --- osu.Game/Database/BeatmapDatabase.cs | 17 ++++++++++++++++- osu.Game/GameModes/Play/PlaySongSelect.cs | 1 + 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/osu.Game/Database/BeatmapDatabase.cs b/osu.Game/Database/BeatmapDatabase.cs index e09e84def1..0378421411 100644 --- a/osu.Game/Database/BeatmapDatabase.cs +++ b/osu.Game/Database/BeatmapDatabase.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Linq.Expressions; using System.Security.Cryptography; using osu.Framework.Platform; using osu.Game.Beatmaps; @@ -58,6 +59,8 @@ namespace osu.Game.Database Hash = hash, }; beatmapSet.Metadata = metadata; + connection.Insert(beatmapSet); + connection.Insert(metadata); var maps = new List(); using (var reader = ArchiveReader.GetReader(storage, path)) { @@ -72,10 +75,11 @@ namespace osu.Game.Database // TODO: Diff beatmap metadata with set metadata and leave it here if necessary beatmap.BeatmapInfo.Metadata = null; maps.Add(beatmap.BeatmapInfo); + connection.Insert(beatmap.BeatmapInfo); } } } - connection.InsertWithChildren(beatmapSet); + connection.UpdateWithChildren(beatmapSet); BeatmapSetAdded?.Invoke(beatmapSet); } @@ -108,6 +112,17 @@ namespace osu.Game.Database { return connection.Table(); } + + public T GetWithChildren(object id) where T : class + { + return connection.GetWithChildren(id); + } + + public List GetAllWithChildren(Expression> filter = null, + bool recursive = true) where T : class + { + return connection.GetAllWithChildren(filter, recursive); + } readonly Type[] validTypes = new[] { diff --git a/osu.Game/GameModes/Play/PlaySongSelect.cs b/osu.Game/GameModes/Play/PlaySongSelect.cs index d6726840c7..78bd4408b6 100644 --- a/osu.Game/GameModes/Play/PlaySongSelect.cs +++ b/osu.Game/GameModes/Play/PlaySongSelect.cs @@ -42,6 +42,7 @@ namespace osu.Game.GameModes.Play private void addBeatmapSet(BeatmapSetInfo beatmapSet) { + beatmapSet = beatmaps.GetWithChildren(beatmapSet.BeatmapSetID); var group = new BeatmapGroup(beatmapSet); group.SetSelected += (selectedSet) => selectBeatmapSet(selectedSet); setList.Add(group); From 8d4a211419856475b2c777928544940051e50120 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Wed, 19 Oct 2016 13:13:14 -0400 Subject: [PATCH 19/58] Fix initialization of BeatmapInfo --- osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs | 6 +++++- osu.Game/Database/BeatmapDatabase.cs | 1 + osu.Game/Database/BeatmapInfo.cs | 8 ++------ 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs index 78f05676b7..7d3b918961 100644 --- a/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/OsuLegacyDecoder.cs @@ -214,7 +214,11 @@ namespace osu.Game.Beatmaps.Formats HitObjects = new List(), ControlPoints = new List(), ComboColors = new List(), - BeatmapInfo = new BeatmapInfo(), + BeatmapInfo = new BeatmapInfo + { + Metadata = new BeatmapMetadata(), + BaseDifficulty = new BaseDifficulty(), + }, }; var section = Section.None; diff --git a/osu.Game/Database/BeatmapDatabase.cs b/osu.Game/Database/BeatmapDatabase.cs index 0378421411..4d980283f6 100644 --- a/osu.Game/Database/BeatmapDatabase.cs +++ b/osu.Game/Database/BeatmapDatabase.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; diff --git a/osu.Game/Database/BeatmapInfo.cs b/osu.Game/Database/BeatmapInfo.cs index 3dd45a0c2b..996a887e77 100644 --- a/osu.Game/Database/BeatmapInfo.cs +++ b/osu.Game/Database/BeatmapInfo.cs @@ -9,16 +9,12 @@ namespace osu.Game.Database { public class BeatmapInfo { - public BeatmapInfo() - { - BaseDifficulty = new BaseDifficulty(); - Metadata = new BeatmapMetadata(); - } - [PrimaryKey] public int BeatmapID { get; set; } [ForeignKey(typeof(BeatmapSetInfo)), NotNull] public int BeatmapSetID { get; set; } + [ManyToOne] + public BeatmapSetInfo BeatmapSet { get; set; } [ForeignKey(typeof(BeatmapMetadata))] public int BeatmapMetadataID { get; set; } [ForeignKey(typeof(BaseDifficulty)), NotNull] From 6da092ab30215db25a9e322e53879aad8348820c Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Wed, 19 Oct 2016 14:02:03 -0400 Subject: [PATCH 20/58] Fix additional bugs, tweak L+F --- osu.Game/Database/BeatmapDatabase.cs | 9 +++-- osu.Game/Database/BeatmapInfo.cs | 2 +- osu.Game/GameModes/Play/BeatmapGroup.cs | 12 +++++- osu.Game/GameModes/Play/PlaySongSelect.cs | 45 ++++++++++++++--------- 4 files changed, 45 insertions(+), 23 deletions(-) diff --git a/osu.Game/Database/BeatmapDatabase.cs b/osu.Game/Database/BeatmapDatabase.cs index 4d980283f6..553bba6cb8 100644 --- a/osu.Game/Database/BeatmapDatabase.cs +++ b/osu.Game/Database/BeatmapDatabase.cs @@ -56,13 +56,13 @@ namespace osu.Game.Database var beatmapSet = new BeatmapSetInfo { BeatmapSetID = metadata.BeatmapSetID, + Beatmaps = new List(), Path = path, Hash = hash, }; - beatmapSet.Metadata = metadata; - connection.Insert(beatmapSet); connection.Insert(metadata); - var maps = new List(); + beatmapSet.Metadata = metadata; + connection.Insert(beatmapSet); using (var reader = ArchiveReader.GetReader(storage, path)) { string[] mapNames = reader.ReadBeatmaps(); @@ -73,9 +73,10 @@ namespace osu.Game.Database var decoder = BeatmapDecoder.GetDecoder(stream); Beatmap beatmap = decoder.Decode(stream); beatmap.BeatmapInfo.Path = name; + beatmap.BeatmapInfo.BeatmapSetID = beatmapSet.BeatmapSetID; // TODO: Diff beatmap metadata with set metadata and leave it here if necessary beatmap.BeatmapInfo.Metadata = null; - maps.Add(beatmap.BeatmapInfo); + beatmapSet.Beatmaps.Add(beatmap.BeatmapInfo); connection.Insert(beatmap.BeatmapInfo); } } diff --git a/osu.Game/Database/BeatmapInfo.cs b/osu.Game/Database/BeatmapInfo.cs index 996a887e77..874b6e3f8a 100644 --- a/osu.Game/Database/BeatmapInfo.cs +++ b/osu.Game/Database/BeatmapInfo.cs @@ -11,7 +11,7 @@ namespace osu.Game.Database { [PrimaryKey] public int BeatmapID { get; set; } - [ForeignKey(typeof(BeatmapSetInfo)), NotNull] + [ForeignKey(typeof(BeatmapSetInfo))] public int BeatmapSetID { get; set; } [ManyToOne] public BeatmapSetInfo BeatmapSet { get; set; } diff --git a/osu.Game/GameModes/Play/BeatmapGroup.cs b/osu.Game/GameModes/Play/BeatmapGroup.cs index 280952e58b..955fa656ac 100644 --- a/osu.Game/GameModes/Play/BeatmapGroup.cs +++ b/osu.Game/GameModes/Play/BeatmapGroup.cs @@ -24,6 +24,7 @@ namespace osu.Game.GameModes.Play public event Action SetSelected; public event Action BeatmapSelected; public BeatmapSetInfo BeatmapSet; + private BeatmapSetBox setBox; private FlowContainer topContainer; private FlowContainer difficulties; private bool collapsed; @@ -48,6 +49,11 @@ namespace osu.Game.GameModes.Play topContainer.Remove(difficulties); else topContainer.Add(difficulties); + setBox.BorderColour = new Color4( + setBox.BorderColour.R, + setBox.BorderColour.G, + setBox.BorderColour.B, + collapsed ? 0 : 255); } } @@ -64,7 +70,7 @@ namespace osu.Game.GameModes.Play RelativeSizeAxes = Axes.X, Size = new Vector2(1, 0), Direction = FlowDirection.VerticalOnly, - Children = new[] { new BeatmapSetBox(beatmapSet) } + Children = new[] { setBox = new BeatmapSetBox(beatmapSet) } } }; difficulties = new FlowContainer // Deliberately not added to children @@ -96,6 +102,10 @@ namespace osu.Game.GameModes.Play this.beatmapSet = beatmapSet; RelativeSizeAxes = Axes.X; Size = new Vector2(1, 0); + Masking = true; + CornerRadius = 5; + BorderThickness = 2; + BorderColour = new Color4(221, 255, 255, 0); Children = new Drawable[] { new Box diff --git a/osu.Game/GameModes/Play/PlaySongSelect.cs b/osu.Game/GameModes/Play/PlaySongSelect.cs index 78bd4408b6..8b8dbcab77 100644 --- a/osu.Game/GameModes/Play/PlaySongSelect.cs +++ b/osu.Game/GameModes/Play/PlaySongSelect.cs @@ -56,30 +56,41 @@ namespace osu.Game.GameModes.Play public PlaySongSelect() { - const float backgroundWidth = 0.6f; - const float backgroundSlant = 25; + const float scrollWidth = 500; Children = new Drawable[] { - new Box + new Container { RelativeSizeAxes = Axes.Both, - Size = new Vector2(backgroundWidth, 0.5f), - Colour = new Color4(0, 0, 0, 0.5f), - }, - new Box - { - RelativeSizeAxes = Axes.Both, - RelativePositionAxes = Axes.Y, - Size = new Vector2(backgroundWidth, 0.5f), - Position = new Vector2(0, 0.5f), - Colour = new Color4(0, 0, 0, 0.5f), + Size = new Vector2(1), + Padding = new MarginPadding { Right = scrollWidth - 100 }, + Children = new[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Size = new Vector2(1, 0.5f), + Colour = new Color4(0, 0, 0, 0.5f), + Shear = new Vector2(0.15f, 0), + }, + new Box + { + RelativeSizeAxes = Axes.Both, + RelativePositionAxes = Axes.Both, + Size = new Vector2(1, 0.5f), + Position = new Vector2(0, 0.5f), + Colour = new Color4(0, 0, 0, 0.5f), + // TODO: Figure out the inverse shear problem + //Shear = new Vector2(-0.15f, 0), + }, + } }, scrollContainer = new ScrollContainer { - RelativeSizeAxes = Axes.Both, - RelativePositionAxes = Axes.Both, - Size = new Vector2(0.5f, 1), - Position = new Vector2(0.5f, 0), + RelativeSizeAxes = Axes.Y, + Size = new Vector2(scrollWidth, 1), + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, Children = new Drawable[] { setList = new FlowContainer From bc959f74a56fc54cdf7ece90664e860181a120ed Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Wed, 19 Oct 2016 16:04:02 -0400 Subject: [PATCH 21/58] Add background textures to beatmap sets Needs osu-framework#189 --- osu.Game/Beatmaps/IO/BeatmapResourceStore.cs | 49 ++++++++++++++++++++ osu.Game/GameModes/Play/BeatmapGroup.cs | 40 +++++++++++++--- osu.Game/GameModes/Play/PlaySongSelect.cs | 19 +++++--- osu.Game/osu.Game.csproj | 1 + 4 files changed, 96 insertions(+), 13 deletions(-) create mode 100644 osu.Game/Beatmaps/IO/BeatmapResourceStore.cs diff --git a/osu.Game/Beatmaps/IO/BeatmapResourceStore.cs b/osu.Game/Beatmaps/IO/BeatmapResourceStore.cs new file mode 100644 index 0000000000..005f751aea --- /dev/null +++ b/osu.Game/Beatmaps/IO/BeatmapResourceStore.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.IO; +using osu.Framework.IO.Stores; +using osu.Game.Database; + +namespace osu.Game.Beatmaps.IO +{ + public class BeatmapResourceStore : IResourceStore, IDisposable + { + private Dictionary beatmaps = new Dictionary(); + private BeatmapDatabase database; + + public BeatmapResourceStore(BeatmapDatabase database) + { + this.database = database; + } + + public void AddBeatmap(BeatmapSetInfo setInfo) + { + beatmaps.Add(setInfo.BeatmapSetID, database.GetReader(setInfo)); + } + + public void RemoveBeatmap(BeatmapSetInfo setInfo) + { + beatmaps[setInfo.BeatmapSetID].Dispose(); + beatmaps.Remove(setInfo.BeatmapSetID); + } + + public void Dispose() + { + foreach (var b in beatmaps.Values) + b.Dispose(); + } + + public byte[] Get(string name) + { + throw new NotImplementedException(); + } + + public Stream GetStream(string name) + { + string id = name.Remove(name.IndexOf(':')); + string path = name.Substring(name.IndexOf(':') + 1); + var reader = beatmaps[int.Parse(id)]; + return reader.ReadFile(path); + } + } +} \ No newline at end of file diff --git a/osu.Game/GameModes/Play/BeatmapGroup.cs b/osu.Game/GameModes/Play/BeatmapGroup.cs index 955fa656ac..df0332e0a1 100644 --- a/osu.Game/GameModes/Play/BeatmapGroup.cs +++ b/osu.Game/GameModes/Play/BeatmapGroup.cs @@ -14,6 +14,8 @@ using System.Linq; using osu.Framework.Graphics.Transformations; using osu.Framework.Input; using OpenTK.Graphics; +using osu.Game.Beatmaps.IO; +using osu.Framework.Graphics.Textures; namespace osu.Game.GameModes.Play { @@ -57,7 +59,7 @@ namespace osu.Game.GameModes.Play } } - public BeatmapGroup(BeatmapSetInfo beatmapSet) + public BeatmapGroup(BeatmapSetInfo beatmapSet, BeatmapResourceStore beatmapStore, TextureStore resources) { BeatmapSet = beatmapSet; Alpha = collapsedAlpha; @@ -70,7 +72,7 @@ namespace osu.Game.GameModes.Play RelativeSizeAxes = Axes.X, Size = new Vector2(1, 0), Direction = FlowDirection.VerticalOnly, - Children = new[] { setBox = new BeatmapSetBox(beatmapSet) } + Children = new[] { setBox = new BeatmapSetBox(beatmapSet, beatmapStore, resources) } } }; difficulties = new FlowContainer // Deliberately not added to children @@ -97,11 +99,11 @@ namespace osu.Game.GameModes.Play { private BeatmapSetInfo beatmapSet; - public BeatmapSetBox(BeatmapSetInfo beatmapSet) + public BeatmapSetBox(BeatmapSetInfo beatmapSet, BeatmapResourceStore beatmapStore, TextureStore resources) { this.beatmapSet = beatmapSet; RelativeSizeAxes = Axes.X; - Size = new Vector2(1, 0); + Size = new Vector2(1, -1); Masking = true; CornerRadius = 5; BorderThickness = 2; @@ -110,9 +112,35 @@ namespace osu.Game.GameModes.Play { new Box { - Colour = new Color4(85, 85, 85, 255), // TODO: Gradient, and beatmap texture + Colour = new Color4(85, 85, 85, 255), RelativeSizeAxes = Axes.Both, - Size = new Vector2(1), + Size = Vector2.One, + }, + new Container + { + RelativeSizeAxes = Axes.Both, + Size = Vector2.One, + Children = new Drawable[] + { + new DeferredSprite + { + RelativeSizeAxes = Axes.X, + Size = new Vector2(1, 0), + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + ResolveTexture = () => + { + beatmapStore.AddBeatmap(beatmapSet); + return resources.Get($@"{beatmapSet.BeatmapSetID}:{beatmapSet.Metadata.BackgroundFile}"); + }, + }, + new Box // TODO: Gradient + { + Colour = new Color4(0, 0, 0, 100), + RelativeSizeAxes = Axes.Both, + Size = Vector2.One, + } + } }, new FlowContainer { diff --git a/osu.Game/GameModes/Play/PlaySongSelect.cs b/osu.Game/GameModes/Play/PlaySongSelect.cs index 8b8dbcab77..eda6a75b71 100644 --- a/osu.Game/GameModes/Play/PlaySongSelect.cs +++ b/osu.Game/GameModes/Play/PlaySongSelect.cs @@ -8,6 +8,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Game.Beatmaps; +using osu.Game.Beatmaps.IO; using osu.Game.GameModes.Backgrounds; using osu.Framework; using osu.Game.Database; @@ -15,6 +16,7 @@ using osu.Framework.Graphics.Primitives; using System.Linq; using OpenTK; using OpenTK.Graphics; +using osu.Framework.Graphics.Textures; namespace osu.Game.GameModes.Play { @@ -23,6 +25,8 @@ namespace osu.Game.GameModes.Play private Bindable playMode; private BeatmapDatabase beatmaps; private BeatmapSetInfo selectedBeatmapSet; + private BeatmapResourceStore beatmapResources; + private TextureStore beatmapTextureResources; // TODO: use currently selected track as bg protected override BackgroundMode CreateBackground() => new BackgroundModeCustom(@"Backgrounds/bg4"); @@ -43,7 +47,7 @@ namespace osu.Game.GameModes.Play private void addBeatmapSet(BeatmapSetInfo beatmapSet) { beatmapSet = beatmaps.GetWithChildren(beatmapSet.BeatmapSetID); - var group = new BeatmapGroup(beatmapSet); + var group = new BeatmapGroup(beatmapSet, beatmapResources, beatmapTextureResources); group.SetSelected += (selectedSet) => selectBeatmapSet(selectedSet); setList.Add(group); } @@ -76,12 +80,11 @@ namespace osu.Game.GameModes.Play new Box { RelativeSizeAxes = Axes.Both, - RelativePositionAxes = Axes.Both, - Size = new Vector2(1, 0.5f), - Position = new Vector2(0, 0.5f), + RelativePositionAxes = Axes.Y, + Size = new Vector2(1, -0.5f), + Position = new Vector2(0, 1), Colour = new Color4(0, 0, 0, 0.5f), - // TODO: Figure out the inverse shear problem - //Shear = new Vector2(-0.15f, 0), + Shear = new Vector2(-0.15f, 0), }, } }, @@ -118,8 +121,10 @@ namespace osu.Game.GameModes.Play // Temporary: scrollContainer.Padding = new MarginPadding { Top = osu.Toolbar.Height }; } - + beatmaps = (game as OsuGameBase).Beatmaps; + beatmapTextureResources = new TextureStore( + new RawTextureLoaderStore(beatmapResources = new BeatmapResourceStore(beatmaps))); beatmaps.BeatmapSetAdded += bset => Scheduler.Add(() => addBeatmapSet(bset)); addBeatmapSets(); var first = setList.Children.FirstOrDefault() as BeatmapGroup; diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 10e384ec01..0ee86c5237 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -190,6 +190,7 @@ + From 941687e091f90a1f139b6727430eb9b1c76521be Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Wed, 19 Oct 2016 16:23:07 -0400 Subject: [PATCH 22/58] Add glow to beatmap groups --- osu.Game/GameModes/Play/BeatmapGroup.cs | 6 ++++-- osu.Game/GameModes/Play/PlaySongSelect.cs | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game/GameModes/Play/BeatmapGroup.cs b/osu.Game/GameModes/Play/BeatmapGroup.cs index df0332e0a1..05c4dab2da 100644 --- a/osu.Game/GameModes/Play/BeatmapGroup.cs +++ b/osu.Game/GameModes/Play/BeatmapGroup.cs @@ -21,7 +21,7 @@ namespace osu.Game.GameModes.Play { class BeatmapGroup : AutoSizeContainer { - private const float collapsedAlpha = 0.3f; + private const float collapsedAlpha = 0.5f; public event Action SetSelected; public event Action BeatmapSelected; @@ -48,7 +48,7 @@ namespace osu.Game.GameModes.Play EndTime = Time + 250, }); if (collapsed) - topContainer.Remove(difficulties); + topContainer.Remove(difficulties, false); else topContainer.Add(difficulties); setBox.BorderColour = new Color4( @@ -56,6 +56,7 @@ namespace osu.Game.GameModes.Play setBox.BorderColour.G, setBox.BorderColour.B, collapsed ? 0 : 255); + setBox.GlowRadius = collapsed ? 0 : 5; } } @@ -108,6 +109,7 @@ namespace osu.Game.GameModes.Play CornerRadius = 5; BorderThickness = 2; BorderColour = new Color4(221, 255, 255, 0); + GlowColour = new Color4(166, 221, 251, 0.5f); // TODO: Get actual color for this Children = new Drawable[] { new Box diff --git a/osu.Game/GameModes/Play/PlaySongSelect.cs b/osu.Game/GameModes/Play/PlaySongSelect.cs index eda6a75b71..b1ad927f7a 100644 --- a/osu.Game/GameModes/Play/PlaySongSelect.cs +++ b/osu.Game/GameModes/Play/PlaySongSelect.cs @@ -98,7 +98,7 @@ namespace osu.Game.GameModes.Play { setList = new FlowContainer { - Padding = new MarginPadding { Top = 25, Bottom = 25 }, + Padding = new MarginPadding { Left = 25, Top = 25, Bottom = 25 }, RelativeSizeAxes = Axes.X, Size = new Vector2(1, 0), Direction = FlowDirection.VerticalOnly, From 4dcdc8638efc2653ba2b6470811cefe7c289ca26 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Wed, 19 Oct 2016 16:37:42 -0400 Subject: [PATCH 23/58] Add beatmap difficulty selection logic --- osu.Game/GameModes/Play/BeatmapButton.cs | 11 ++++++++- osu.Game/GameModes/Play/BeatmapGroup.cs | 13 ++++++++++- osu.Game/GameModes/Play/PlaySongSelect.cs | 28 +++++++++++++++++++++-- 3 files changed, 48 insertions(+), 4 deletions(-) diff --git a/osu.Game/GameModes/Play/BeatmapButton.cs b/osu.Game/GameModes/Play/BeatmapButton.cs index 9700ed5bf7..465b41706b 100644 --- a/osu.Game/GameModes/Play/BeatmapButton.cs +++ b/osu.Game/GameModes/Play/BeatmapButton.cs @@ -7,6 +7,7 @@ using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; +using osu.Framework.Input; using osu.Game.Beatmaps; using osu.Game.GameModes.Backgrounds; using osu.Framework; @@ -23,6 +24,8 @@ namespace osu.Game.GameModes.Play private BeatmapSetInfo beatmapSet; private BeatmapInfo beatmap; + public Action Selected; + public BeatmapButton(BeatmapSetInfo set, BeatmapInfo beatmap) { this.beatmapSet = set; @@ -33,7 +36,7 @@ namespace osu.Game.GameModes.Play { new Box { - Colour = new Color4(40, 86, 102, 255), // TODO: texture + Colour = new Color4(40, 86, 102, 255), // TODO: gradient RelativeSizeAxes = Axes.Both, Size = new Vector2(1), }, @@ -66,5 +69,11 @@ namespace osu.Game.GameModes.Play } }; } + + protected override bool OnClick(InputState state) + { + Selected?.Invoke(beatmap); + return true; + } } } diff --git a/osu.Game/GameModes/Play/BeatmapGroup.cs b/osu.Game/GameModes/Play/BeatmapGroup.cs index 05c4dab2da..c7d3119072 100644 --- a/osu.Game/GameModes/Play/BeatmapGroup.cs +++ b/osu.Game/GameModes/Play/BeatmapGroup.cs @@ -22,6 +22,16 @@ namespace osu.Game.GameModes.Play class BeatmapGroup : AutoSizeContainer { private const float collapsedAlpha = 0.5f; + + private BeatmapInfo selectedBeatmap; + public BeatmapInfo SelectedBeatmap + { + get { return selectedBeatmap; } + set + { + selectedBeatmap = value; + } + } public event Action SetSelected; public event Action BeatmapSelected; @@ -84,7 +94,8 @@ namespace osu.Game.GameModes.Play Padding = new MarginPadding { Left = 25 }, Spacing = new Vector2(0, 5), Direction = FlowDirection.VerticalOnly, - Children = this.BeatmapSet.Beatmaps.Select(b => new BeatmapButton(this.BeatmapSet, b)) + Children = this.BeatmapSet.Beatmaps.Select( + b => new BeatmapButton(this.BeatmapSet, b) { Selected = beatmap => BeatmapSelected?.Invoke(beatmapSet, beatmap) }) }; collapsed = true; } diff --git a/osu.Game/GameModes/Play/PlaySongSelect.cs b/osu.Game/GameModes/Play/PlaySongSelect.cs index b1ad927f7a..c37a18751c 100644 --- a/osu.Game/GameModes/Play/PlaySongSelect.cs +++ b/osu.Game/GameModes/Play/PlaySongSelect.cs @@ -17,6 +17,7 @@ using System.Linq; using OpenTK; using OpenTK.Graphics; using osu.Framework.Graphics.Textures; +using osu.Framework.Graphics.UserInterface; namespace osu.Game.GameModes.Play { @@ -25,6 +26,7 @@ namespace osu.Game.GameModes.Play private Bindable playMode; private BeatmapDatabase beatmaps; private BeatmapSetInfo selectedBeatmapSet; + private BeatmapInfo selectedBeatmap; private BeatmapResourceStore beatmapResources; private TextureStore beatmapTextureResources; @@ -40,15 +42,28 @@ namespace osu.Game.GameModes.Play foreach (var child in setList.Children) { var childGroup = child as BeatmapGroup; - childGroup.Collapsed = childGroup.BeatmapSet != beatmapSet; + if (childGroup.BeatmapSet == beatmapSet) + { + childGroup.Collapsed = false; + selectedBeatmap = childGroup.SelectedBeatmap; + } + else + childGroup.Collapsed = true; } } + + private void selectBeatmap(BeatmapSetInfo set, BeatmapInfo beatmap) + { + selectBeatmapSet(set); + selectedBeatmap = beatmap; + } private void addBeatmapSet(BeatmapSetInfo beatmapSet) { beatmapSet = beatmaps.GetWithChildren(beatmapSet.BeatmapSetID); var group = new BeatmapGroup(beatmapSet, beatmapResources, beatmapTextureResources); - group.SetSelected += (selectedSet) => selectBeatmapSet(selectedSet); + group.SetSelected += selectBeatmapSet; + group.BeatmapSelected += selectBeatmap; setList.Add(group); } @@ -105,6 +120,15 @@ namespace osu.Game.GameModes.Play Spacing = new Vector2(0, 25), } } + }, + new Button + { + Text = "Play", + Anchor = Anchor.BottomRight, + Origin = Anchor.BottomRight, + Action = () => + { + }, } }; } From 51791bba7f7e2deed73ba776e24d94d1c8a66073 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Wed, 19 Oct 2016 16:41:34 -0400 Subject: [PATCH 24/58] Tweak play button --- osu.Game/GameModes/Play/PlaySongSelect.cs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/osu.Game/GameModes/Play/PlaySongSelect.cs b/osu.Game/GameModes/Play/PlaySongSelect.cs index c37a18751c..055dfd39f9 100644 --- a/osu.Game/GameModes/Play/PlaySongSelect.cs +++ b/osu.Game/GameModes/Play/PlaySongSelect.cs @@ -124,11 +124,12 @@ namespace osu.Game.GameModes.Play new Button { Text = "Play", - Anchor = Anchor.BottomRight, - Origin = Anchor.BottomRight, - Action = () => - { - }, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativePositionAxes = Axes.Both, + Position = Vector2.Zero, + Colour = new Color4(238, 51, 153, 255), + Action = () => Console.WriteLine("Clicked!"), } }; } From cfa637b76311379769573d4f00a793c603cb65b2 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Wed, 19 Oct 2016 16:42:52 -0400 Subject: [PATCH 25/58] Select first difficulty by default --- osu.Game/GameModes/Play/BeatmapGroup.cs | 1 + osu.Game/GameModes/Play/PlaySongSelect.cs | 1 + 2 files changed, 2 insertions(+) diff --git a/osu.Game/GameModes/Play/BeatmapGroup.cs b/osu.Game/GameModes/Play/BeatmapGroup.cs index c7d3119072..29c01c4d18 100644 --- a/osu.Game/GameModes/Play/BeatmapGroup.cs +++ b/osu.Game/GameModes/Play/BeatmapGroup.cs @@ -73,6 +73,7 @@ namespace osu.Game.GameModes.Play public BeatmapGroup(BeatmapSetInfo beatmapSet, BeatmapResourceStore beatmapStore, TextureStore resources) { BeatmapSet = beatmapSet; + selectedBeatmap = beatmapSet.Beatmaps[0]; Alpha = collapsedAlpha; RelativeSizeAxes = Axes.X; Size = new Vector2(1, 0); diff --git a/osu.Game/GameModes/Play/PlaySongSelect.cs b/osu.Game/GameModes/Play/PlaySongSelect.cs index 055dfd39f9..3cbaa5d178 100644 --- a/osu.Game/GameModes/Play/PlaySongSelect.cs +++ b/osu.Game/GameModes/Play/PlaySongSelect.cs @@ -157,6 +157,7 @@ namespace osu.Game.GameModes.Play { first.Collapsed = false; selectedBeatmapSet = first.BeatmapSet; + selectedBeatmap = first.SelectedBeatmap; } } From 33fc60716d69eee839e4f69ce1633260f9e70c04 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 20 Oct 2016 11:17:37 -0400 Subject: [PATCH 26/58] Fix assertion failures --- osu.Game/GameModes/Play/BeatmapButton.cs | 2 +- osu.Game/GameModes/Play/BeatmapGroup.cs | 7 +++---- osu.Game/GameModes/Play/PlaySongSelect.cs | 16 ++-------------- 3 files changed, 6 insertions(+), 19 deletions(-) diff --git a/osu.Game/GameModes/Play/BeatmapButton.cs b/osu.Game/GameModes/Play/BeatmapButton.cs index 465b41706b..e80de14380 100644 --- a/osu.Game/GameModes/Play/BeatmapButton.cs +++ b/osu.Game/GameModes/Play/BeatmapButton.cs @@ -31,7 +31,7 @@ namespace osu.Game.GameModes.Play this.beatmapSet = set; this.beatmap = beatmap; RelativeSizeAxes = Axes.X; - Size = new Vector2(1, 0); + Size = new Vector2(1, -1); Children = new Drawable[] { new Box diff --git a/osu.Game/GameModes/Play/BeatmapGroup.cs b/osu.Game/GameModes/Play/BeatmapGroup.cs index 29c01c4d18..648977dc1c 100644 --- a/osu.Game/GameModes/Play/BeatmapGroup.cs +++ b/osu.Game/GameModes/Play/BeatmapGroup.cs @@ -76,13 +76,13 @@ namespace osu.Game.GameModes.Play selectedBeatmap = beatmapSet.Beatmaps[0]; Alpha = collapsedAlpha; RelativeSizeAxes = Axes.X; - Size = new Vector2(1, 0); + Size = new Vector2(1, -1); Children = new[] { topContainer = new FlowContainer { RelativeSizeAxes = Axes.X, - Size = new Vector2(1, 0), + Size = new Vector2(1, -1), Direction = FlowDirection.VerticalOnly, Children = new[] { setBox = new BeatmapSetBox(beatmapSet, beatmapStore, resources) } } @@ -90,7 +90,7 @@ namespace osu.Game.GameModes.Play difficulties = new FlowContainer // Deliberately not added to children { RelativeSizeAxes = Axes.X, - Size = new Vector2(1, 0), + Size = new Vector2(1, -1), Margin = new MarginPadding { Top = 5 }, Padding = new MarginPadding { Left = 25 }, Spacing = new Vector2(0, 5), @@ -200,7 +200,6 @@ namespace osu.Game.GameModes.Play { Anchor = Anchor.Centre, TextSize = size, - Size = new Vector2(size), Colour = color, Icon = icon } diff --git a/osu.Game/GameModes/Play/PlaySongSelect.cs b/osu.Game/GameModes/Play/PlaySongSelect.cs index 3cbaa5d178..20c17c3bbe 100644 --- a/osu.Game/GameModes/Play/PlaySongSelect.cs +++ b/osu.Game/GameModes/Play/PlaySongSelect.cs @@ -29,10 +29,8 @@ namespace osu.Game.GameModes.Play private BeatmapInfo selectedBeatmap; private BeatmapResourceStore beatmapResources; private TextureStore beatmapTextureResources; - // TODO: use currently selected track as bg protected override BackgroundMode CreateBackground() => new BackgroundModeCustom(@"Backgrounds/bg4"); - private ScrollContainer scrollContainer; private FlowContainer setList; @@ -75,7 +73,7 @@ namespace osu.Game.GameModes.Play public PlaySongSelect() { - const float scrollWidth = 500; + const float scrollWidth = 640; Children = new Drawable[] { new Container @@ -115,21 +113,11 @@ namespace osu.Game.GameModes.Play { Padding = new MarginPadding { Left = 25, Top = 25, Bottom = 25 }, RelativeSizeAxes = Axes.X, - Size = new Vector2(1, 0), + Size = new Vector2(1, -1), Direction = FlowDirection.VerticalOnly, Spacing = new Vector2(0, 25), } } - }, - new Button - { - Text = "Play", - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativePositionAxes = Axes.Both, - Position = Vector2.Zero, - Colour = new Color4(238, 51, 153, 255), - Action = () => Console.WriteLine("Clicked!"), } }; } From 61a7ccaece26176fdcc45fc3be3d89f1793029a4 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 20 Oct 2016 13:55:04 -0400 Subject: [PATCH 27/58] Remove dependency on DeferredSprite --- osu.Game/GameModes/Play/BeatmapGroup.cs | 51 ++++++++++++++++++----- osu.Game/GameModes/Play/PlaySongSelect.cs | 2 + 2 files changed, 42 insertions(+), 11 deletions(-) diff --git a/osu.Game/GameModes/Play/BeatmapGroup.cs b/osu.Game/GameModes/Play/BeatmapGroup.cs index 648977dc1c..2a6c9a382f 100644 --- a/osu.Game/GameModes/Play/BeatmapGroup.cs +++ b/osu.Game/GameModes/Play/BeatmapGroup.cs @@ -16,12 +16,14 @@ using osu.Framework.Input; using OpenTK.Graphics; using osu.Game.Beatmaps.IO; using osu.Framework.Graphics.Textures; - +using System.Threading.Tasks; + namespace osu.Game.GameModes.Play { class BeatmapGroup : AutoSizeContainer { private const float collapsedAlpha = 0.5f; + private const float collapsedWidth = 0.8f; private BeatmapInfo selectedBeatmap; public BeatmapInfo SelectedBeatmap @@ -58,9 +60,15 @@ namespace osu.Game.GameModes.Play EndTime = Time + 250, }); if (collapsed) - topContainer.Remove(difficulties, false); + { + topContainer.Remove(difficulties); + setBox.Size = new Vector2(collapsedWidth, -1); + } else + { topContainer.Add(difficulties); + setBox.Size = new Vector2(1, -1); + } setBox.BorderColour = new Color4( setBox.BorderColour.R, setBox.BorderColour.G, @@ -84,7 +92,16 @@ namespace osu.Game.GameModes.Play RelativeSizeAxes = Axes.X, Size = new Vector2(1, -1), Direction = FlowDirection.VerticalOnly, - Children = new[] { setBox = new BeatmapSetBox(beatmapSet, beatmapStore, resources) } + Children = new[] + { + setBox = new BeatmapSetBox(beatmapSet, beatmapStore, resources) + { + RelativeSizeAxes = Axes.X, + Size = new Vector2(collapsedWidth, -1), + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + } + } } }; difficulties = new FlowContainer // Deliberately not added to children @@ -111,12 +128,15 @@ namespace osu.Game.GameModes.Play class BeatmapSetBox : AutoSizeContainer { private BeatmapSetInfo beatmapSet; + private BeatmapResourceStore beatmapStore; + private TextureStore resources; + private Sprite backgroundImage; public BeatmapSetBox(BeatmapSetInfo beatmapSet, BeatmapResourceStore beatmapStore, TextureStore resources) { this.beatmapSet = beatmapSet; - RelativeSizeAxes = Axes.X; - Size = new Vector2(1, -1); + this.beatmapStore = beatmapStore; + this.resources = resources; Masking = true; CornerRadius = 5; BorderThickness = 2; @@ -136,17 +156,12 @@ namespace osu.Game.GameModes.Play Size = Vector2.One, Children = new Drawable[] { - new DeferredSprite + backgroundImage = new Sprite { RelativeSizeAxes = Axes.X, Size = new Vector2(1, 0), Anchor = Anchor.Centre, Origin = Anchor.Centre, - ResolveTexture = () => - { - beatmapStore.AddBeatmap(beatmapSet); - return resources.Get($@"{beatmapSet.BeatmapSetID}:{beatmapSet.Metadata.BackgroundFile}"); - }, }, new Box // TODO: Gradient { @@ -186,6 +201,20 @@ namespace osu.Game.GameModes.Play } }; } + + public override void Load(Framework.BaseGame game) + { + base.Load(game); + if (beatmapSet.Metadata.BackgroundFile != null) + { + Task.Factory.StartNew(() => + { + beatmapStore.AddBeatmap(beatmapSet); + var texture = resources.Get($@"{beatmapSet.BeatmapSetID}:{beatmapSet.Metadata.BackgroundFile}"); + Scheduler.Add(() => backgroundImage.Texture = texture); + }); + } + } } class DifficultyIcon : Container diff --git a/osu.Game/GameModes/Play/PlaySongSelect.cs b/osu.Game/GameModes/Play/PlaySongSelect.cs index 20c17c3bbe..ce29496d40 100644 --- a/osu.Game/GameModes/Play/PlaySongSelect.cs +++ b/osu.Game/GameModes/Play/PlaySongSelect.cs @@ -154,6 +154,8 @@ namespace osu.Game.GameModes.Play base.Dispose(isDisposing); if (playMode != null) playMode.ValueChanged -= PlayMode_ValueChanged; + if (beatmapResources != null) + beatmapResources.Dispose(); } private void PlayMode_ValueChanged(object sender, EventArgs e) From 4b6a1486a6934ec3f82c8f83862bfffe886eebc8 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 20 Oct 2016 14:21:33 -0400 Subject: [PATCH 28/58] Increase spacing to match mockups --- osu.Game/GameModes/Play/PlaySongSelect.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/GameModes/Play/PlaySongSelect.cs b/osu.Game/GameModes/Play/PlaySongSelect.cs index ce29496d40..bf6a9474b4 100644 --- a/osu.Game/GameModes/Play/PlaySongSelect.cs +++ b/osu.Game/GameModes/Play/PlaySongSelect.cs @@ -115,7 +115,7 @@ namespace osu.Game.GameModes.Play RelativeSizeAxes = Axes.X, Size = new Vector2(1, -1), Direction = FlowDirection.VerticalOnly, - Spacing = new Vector2(0, 25), + Spacing = new Vector2(0, 5), } } } From 910a079bdac390543000e9d7e6a09edd88cb3193 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 20 Oct 2016 15:16:06 -0400 Subject: [PATCH 29/58] Add animation, selection indicator to difficulties --- osu.Game/GameModes/Play/BeatmapButton.cs | 31 ++++++++-- osu.Game/GameModes/Play/BeatmapGroup.cs | 74 +++++++++++++++++------ osu.Game/GameModes/Play/PlaySongSelect.cs | 2 +- 3 files changed, 83 insertions(+), 24 deletions(-) diff --git a/osu.Game/GameModes/Play/BeatmapButton.cs b/osu.Game/GameModes/Play/BeatmapButton.cs index e80de14380..a172565a55 100644 --- a/osu.Game/GameModes/Play/BeatmapButton.cs +++ b/osu.Game/GameModes/Play/BeatmapButton.cs @@ -16,6 +16,7 @@ using osu.Framework.Graphics.Primitives; using OpenTK.Graphics; using OpenTK; using osu.Game.Graphics; +using osu.Framework.Graphics.Transformations; namespace osu.Game.GameModes.Play { @@ -24,14 +25,36 @@ namespace osu.Game.GameModes.Play private BeatmapSetInfo beatmapSet; private BeatmapInfo beatmap; - public Action Selected; + public Action MapSelected; + + private bool selected; + + public bool Selected + { + get { return selected; } + set + { + if (selected == value) + return; + selected = value; + BorderColour = new Color4( + BorderColour.R, + BorderColour.G, + BorderColour.B, + selected ? 255 : 0); + GlowRadius = selected ? 3 : 0; + } + } public BeatmapButton(BeatmapSetInfo set, BeatmapInfo beatmap) { this.beatmapSet = set; this.beatmap = beatmap; - RelativeSizeAxes = Axes.X; - Size = new Vector2(1, -1); + Masking = true; + CornerRadius = 5; + BorderThickness = 2; + BorderColour = new Color4(221, 255, 255, 0); + GlowColour = new Color4(166, 221, 251, 0.75f); // TODO: Get actual color for this Children = new Drawable[] { new Box @@ -72,7 +95,7 @@ namespace osu.Game.GameModes.Play protected override bool OnClick(InputState state) { - Selected?.Invoke(beatmap); + MapSelected?.Invoke(beatmap); return true; } } diff --git a/osu.Game/GameModes/Play/BeatmapGroup.cs b/osu.Game/GameModes/Play/BeatmapGroup.cs index 2a6c9a382f..617c19acb1 100644 --- a/osu.Game/GameModes/Play/BeatmapGroup.cs +++ b/osu.Game/GameModes/Play/BeatmapGroup.cs @@ -16,8 +16,8 @@ using osu.Framework.Input; using OpenTK.Graphics; using osu.Game.Beatmaps.IO; using osu.Framework.Graphics.Textures; -using System.Threading.Tasks; - +using System.Threading.Tasks; + namespace osu.Game.GameModes.Play { class BeatmapGroup : AutoSizeContainer @@ -60,15 +60,17 @@ namespace osu.Game.GameModes.Play EndTime = Time + 250, }); if (collapsed) - { topContainer.Remove(difficulties); - setBox.Size = new Vector2(collapsedWidth, -1); - } else - { topContainer.Add(difficulties); - setBox.Size = new Vector2(1, -1); - } + setBox.ClearTransformations(); + setBox.Transforms.Add(new TransformSize(Clock) + { + StartValue = new Vector2(collapsed ? 1 : collapsedWidth, -1), + EndValue = new Vector2(collapsed ? collapsedWidth : 1, -1), + StartTime = Time, + EndTime = Time + 200, + }); setBox.BorderColour = new Color4( setBox.BorderColour.R, setBox.BorderColour.G, @@ -77,6 +79,27 @@ namespace osu.Game.GameModes.Play setBox.GlowRadius = collapsed ? 0 : 5; } } + + private void updateSelected(BeatmapInfo map) + { + int selected = BeatmapSet.Beatmaps.IndexOf(map); + var buttons = difficulties.Children.ToList(); + for (int i = 0; i < buttons.Count; i++) + { + var button = buttons[i] as BeatmapButton; + float targetWidth = 1 - Math.Abs((selected - i) * 0.025f); + targetWidth = MathHelper.Clamp(targetWidth, 0.8f, 1); + button.Transforms.Add(new TransformSize(Clock) + { + StartValue = new Vector2(button.Size.X, -1), + EndValue = new Vector2(targetWidth, -1), + StartTime = Time, + EndTime = Time + 100, + }); + button.Selected = selected == i; + } + BeatmapSelected?.Invoke(BeatmapSet, map); + } public BeatmapGroup(BeatmapSetInfo beatmapSet, BeatmapResourceStore beatmapStore, TextureStore resources) { @@ -85,6 +108,7 @@ namespace osu.Game.GameModes.Play Alpha = collapsedAlpha; RelativeSizeAxes = Axes.X; Size = new Vector2(1, -1); + float difficultyWidth = 1; Children = new[] { topContainer = new FlowContainer @@ -109,11 +133,23 @@ namespace osu.Game.GameModes.Play RelativeSizeAxes = Axes.X, Size = new Vector2(1, -1), Margin = new MarginPadding { Top = 5 }, - Padding = new MarginPadding { Left = 25 }, + Padding = new MarginPadding { Left = 75 }, Spacing = new Vector2(0, 5), Direction = FlowDirection.VerticalOnly, Children = this.BeatmapSet.Beatmaps.Select( - b => new BeatmapButton(this.BeatmapSet, b) { Selected = beatmap => BeatmapSelected?.Invoke(beatmapSet, beatmap) }) + b => { + float width = difficultyWidth; + if (difficultyWidth > 0.8f) difficultyWidth -= 0.025f; + return new BeatmapButton(this.BeatmapSet, b) + { + MapSelected = beatmap => updateSelected(beatmap), + Selected = width == 1, + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + RelativeSizeAxes = Axes.X, + Size = new Vector2(width, -1), + }; + }) }; collapsed = true; } @@ -202,18 +238,18 @@ namespace osu.Game.GameModes.Play }; } - public override void Load(Framework.BaseGame game) - { + public override void Load(Framework.BaseGame game) + { base.Load(game); if (beatmapSet.Metadata.BackgroundFile != null) - { - Task.Factory.StartNew(() => - { - beatmapStore.AddBeatmap(beatmapSet); - var texture = resources.Get($@"{beatmapSet.BeatmapSetID}:{beatmapSet.Metadata.BackgroundFile}"); - Scheduler.Add(() => backgroundImage.Texture = texture); + { + Task.Factory.StartNew(() => + { + beatmapStore.AddBeatmap(beatmapSet); + var texture = resources.Get($@"{beatmapSet.BeatmapSetID}:{beatmapSet.Metadata.BackgroundFile}"); + Scheduler.Add(() => backgroundImage.Texture = texture); }); - } + } } } diff --git a/osu.Game/GameModes/Play/PlaySongSelect.cs b/osu.Game/GameModes/Play/PlaySongSelect.cs index bf6a9474b4..91cd851ef4 100644 --- a/osu.Game/GameModes/Play/PlaySongSelect.cs +++ b/osu.Game/GameModes/Play/PlaySongSelect.cs @@ -80,7 +80,7 @@ namespace osu.Game.GameModes.Play { RelativeSizeAxes = Axes.Both, Size = new Vector2(1), - Padding = new MarginPadding { Right = scrollWidth - 100 }, + Padding = new MarginPadding { Right = scrollWidth - 200 }, Children = new[] { new Box From 8d6431b35e2422a813fb89609813ac95397131c0 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 20 Oct 2016 15:33:46 -0400 Subject: [PATCH 30/58] Add star counter to difficulty select --- osu.Game/Database/BeatmapDatabase.cs | 2 ++ osu.Game/GameModes/Play/BeatmapButton.cs | 30 ++++++++++++++++-------- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/osu.Game/Database/BeatmapDatabase.cs b/osu.Game/Database/BeatmapDatabase.cs index 553bba6cb8..8aa92fb23d 100644 --- a/osu.Game/Database/BeatmapDatabase.cs +++ b/osu.Game/Database/BeatmapDatabase.cs @@ -77,6 +77,8 @@ namespace osu.Game.Database // TODO: Diff beatmap metadata with set metadata and leave it here if necessary beatmap.BeatmapInfo.Metadata = null; beatmapSet.Beatmaps.Add(beatmap.BeatmapInfo); + connection.Insert(beatmap.BeatmapInfo.BaseDifficulty); + beatmap.BeatmapInfo.BaseDifficultyID = beatmap.BeatmapInfo.BaseDifficulty.ID; connection.Insert(beatmap.BeatmapInfo); } } diff --git a/osu.Game/GameModes/Play/BeatmapButton.cs b/osu.Game/GameModes/Play/BeatmapButton.cs index a172565a55..2d99fda0f9 100644 --- a/osu.Game/GameModes/Play/BeatmapButton.cs +++ b/osu.Game/GameModes/Play/BeatmapButton.cs @@ -17,6 +17,7 @@ using OpenTK.Graphics; using OpenTK; using osu.Game.Graphics; using osu.Framework.Graphics.Transformations; +using osu.Game.Graphics.UserInterface; namespace osu.Game.GameModes.Play { @@ -73,19 +74,28 @@ namespace osu.Game.GameModes.Play new FlowContainer { Padding = new MarginPadding { Left = 10 }, - Direction = FlowDirection.HorizontalOnly, - Children = new[] + Direction = FlowDirection.VerticalOnly, + Children = new Drawable[] { - new SpriteText + new FlowContainer { - Text = beatmap.Version, - TextSize = 20, - }, - new SpriteText - { - Text = string.Format(" mapped by {0}", (beatmap.Metadata ?? set.Metadata).Author), - TextSize = 16, + Direction = FlowDirection.HorizontalOnly, + Children = new[] + { + new SpriteText + { + Text = beatmap.Version, + TextSize = 20, + }, + new SpriteText + { + Text = string.Format(" mapped by {0}", + (beatmap.Metadata ?? set.Metadata).Author), + TextSize = 16, + }, + } }, + new StarCounter { Count = beatmap.BaseDifficulty?.OverallDifficulty ?? 5, StarSize = 8 } } } } From 42f8d19c739da4dd3b5e2763b6ec1cb84e4a45c5 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Thu, 20 Oct 2016 15:42:09 -0400 Subject: [PATCH 31/58] Sort by difficulty and fix relationship --- osu.Game/Database/BeatmapDatabase.cs | 5 +++++ osu.Game/GameModes/Play/BeatmapGroup.cs | 4 ++-- osu.Game/GameModes/Play/PlaySongSelect.cs | 3 +++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/osu.Game/Database/BeatmapDatabase.cs b/osu.Game/Database/BeatmapDatabase.cs index 8aa92fb23d..b84de3b129 100644 --- a/osu.Game/Database/BeatmapDatabase.cs +++ b/osu.Game/Database/BeatmapDatabase.cs @@ -127,6 +127,11 @@ namespace osu.Game.Database { return connection.GetAllWithChildren(filter, recursive); } + + public void GetChildren(T item, bool recursive = true) + { + connection.GetChildren(item, recursive); + } readonly Type[] validTypes = new[] { diff --git a/osu.Game/GameModes/Play/BeatmapGroup.cs b/osu.Game/GameModes/Play/BeatmapGroup.cs index 617c19acb1..ef0c78a62e 100644 --- a/osu.Game/GameModes/Play/BeatmapGroup.cs +++ b/osu.Game/GameModes/Play/BeatmapGroup.cs @@ -217,12 +217,12 @@ namespace osu.Game.GameModes.Play // TODO: Make these italic new SpriteText { - Text = this.beatmapSet.Metadata.TitleUnicode ?? this.beatmapSet.Metadata.Title, + Text = this.beatmapSet.Metadata.Title ?? this.beatmapSet.Metadata.TitleUnicode, TextSize = 20 }, new SpriteText { - Text = this.beatmapSet.Metadata.ArtistUnicode ?? this.beatmapSet.Metadata.Artist, + Text = this.beatmapSet.Metadata.Artist ?? this.beatmapSet.Metadata.ArtistUnicode, TextSize = 16 }, new FlowContainer diff --git a/osu.Game/GameModes/Play/PlaySongSelect.cs b/osu.Game/GameModes/Play/PlaySongSelect.cs index 91cd851ef4..1815925c94 100644 --- a/osu.Game/GameModes/Play/PlaySongSelect.cs +++ b/osu.Game/GameModes/Play/PlaySongSelect.cs @@ -59,6 +59,9 @@ namespace osu.Game.GameModes.Play private void addBeatmapSet(BeatmapSetInfo beatmapSet) { beatmapSet = beatmaps.GetWithChildren(beatmapSet.BeatmapSetID); + beatmapSet.Beatmaps.ForEach(b => beatmaps.GetChildren(b)); + beatmapSet.Beatmaps = beatmapSet.Beatmaps.OrderBy(b => b.BaseDifficulty.OverallDifficulty) + .ToList(); var group = new BeatmapGroup(beatmapSet, beatmapResources, beatmapTextureResources); group.SetSelected += selectBeatmapSet; group.BeatmapSelected += selectBeatmap; From ee6c810df57dc3a58622ab9e0c04cfd1bcc2b880 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Oct 2016 17:01:12 +0900 Subject: [PATCH 32/58] Fix cascading inserts. --- osu.Game/Database/BeatmapInfo.cs | 14 ++++++++++---- osu.Game/Database/BeatmapSetInfo.cs | 19 ++++++++++++------- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/osu.Game/Database/BeatmapInfo.cs b/osu.Game/Database/BeatmapInfo.cs index 874b6e3f8a..5b1d0c323c 100644 --- a/osu.Game/Database/BeatmapInfo.cs +++ b/osu.Game/Database/BeatmapInfo.cs @@ -10,18 +10,24 @@ namespace osu.Game.Database public class BeatmapInfo { [PrimaryKey] - public int BeatmapID { get; set; } + public int BeatmapID { get; set; } + [ForeignKey(typeof(BeatmapSetInfo))] public int BeatmapSetID { get; set; } + [ManyToOne] public BeatmapSetInfo BeatmapSet { get; set; } + [ForeignKey(typeof(BeatmapMetadata))] public int BeatmapMetadataID { get; set; } + + [OneToOne(CascadeOperations = CascadeOperation.All)] + public BeatmapMetadata Metadata { get; set; } + [ForeignKey(typeof(BaseDifficulty)), NotNull] public int BaseDifficultyID { get; set; } - [OneToOne] - public BeatmapMetadata Metadata { get; set; } - [OneToOne] + + [OneToOne(CascadeOperations = CascadeOperation.All)] public BaseDifficulty BaseDifficulty { get; set; } public string Path { get; set; } diff --git a/osu.Game/Database/BeatmapSetInfo.cs b/osu.Game/Database/BeatmapSetInfo.cs index 414b6b09f8..6dc0adfa01 100644 --- a/osu.Game/Database/BeatmapSetInfo.cs +++ b/osu.Game/Database/BeatmapSetInfo.cs @@ -8,14 +8,19 @@ namespace osu.Game.Database public class BeatmapSetInfo { [PrimaryKey] - public int BeatmapSetID { get; set; } - [OneToOne] - public BeatmapMetadata Metadata { get; set; } - [NotNull, ForeignKey(typeof(BeatmapMetadata))] + public int BeatmapSetID { get; set; } + + [OneToOne(CascadeOperations = CascadeOperation.All)] + public BeatmapMetadata Metadata { get; set; } + + [NotNull, ForeignKey(typeof(BeatmapMetadata))] public int BeatmapMetadataID { get; set; } - [OneToMany] - public List Beatmaps { get; set; } - public string Hash { get; set; } + + [OneToMany(CascadeOperations = CascadeOperation.All)] + public List Beatmaps { get; set; } + + public string Hash { get; set; } + public string Path { get; set; } } } From 7650bb17074a6fac171a94d19b393c319049534c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Oct 2016 17:01:34 +0900 Subject: [PATCH 33/58] Don't insert to database until we're completely finished importing a beatmap. --- osu.Game/Database/BeatmapDatabase.cs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/osu.Game/Database/BeatmapDatabase.cs b/osu.Game/Database/BeatmapDatabase.cs index b84de3b129..c23db37f08 100644 --- a/osu.Game/Database/BeatmapDatabase.cs +++ b/osu.Game/Database/BeatmapDatabase.cs @@ -37,10 +37,13 @@ namespace osu.Game.Database { string hash = null; BeatmapMetadata metadata; + using (var reader = ArchiveReader.GetReader(storage, path)) metadata = reader.ReadMetadata(); + if (connection.Table().Count(b => b.BeatmapSetID == metadata.BeatmapSetID) != 0) return; // TODO: Update this beatmap instead + if (File.Exists(path)) // Not always the case, i.e. for LegacyFilesystemReader { using (var md5 = MD5.Create()) @@ -48,8 +51,8 @@ namespace osu.Game.Database { hash = BitConverter.ToString(md5.ComputeHash(input)).Replace("-", "").ToLowerInvariant(); input.Seek(0, SeekOrigin.Begin); - var outputPath = Path.Combine(@"beatmaps", hash.Remove(1), hash.Remove(2), hash); - using (var output = storage.GetStream(outputPath, FileAccess.Write)) + path = Path.Combine(@"beatmaps", hash.Remove(1), hash.Remove(2), hash); + using (var output = storage.GetStream(path, FileAccess.Write)) input.CopyTo(output); } } @@ -59,10 +62,9 @@ namespace osu.Game.Database Beatmaps = new List(), Path = path, Hash = hash, + Metadata = metadata }; - connection.Insert(metadata); - beatmapSet.Metadata = metadata; - connection.Insert(beatmapSet); + using (var reader = ArchiveReader.GetReader(storage, path)) { string[] mapNames = reader.ReadBeatmaps(); @@ -73,17 +75,15 @@ namespace osu.Game.Database var decoder = BeatmapDecoder.GetDecoder(stream); Beatmap beatmap = decoder.Decode(stream); beatmap.BeatmapInfo.Path = name; - beatmap.BeatmapInfo.BeatmapSetID = beatmapSet.BeatmapSetID; + // TODO: Diff beatmap metadata with set metadata and leave it here if necessary beatmap.BeatmapInfo.Metadata = null; + beatmapSet.Beatmaps.Add(beatmap.BeatmapInfo); - connection.Insert(beatmap.BeatmapInfo.BaseDifficulty); - beatmap.BeatmapInfo.BaseDifficultyID = beatmap.BeatmapInfo.BaseDifficulty.ID; - connection.Insert(beatmap.BeatmapInfo); } } } - connection.UpdateWithChildren(beatmapSet); + connection.InsertWithChildren(beatmapSet, true); BeatmapSetAdded?.Invoke(beatmapSet); } From 6f80efdb2975d93673ebea84e9073f178f9ae0d7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Oct 2016 17:01:46 +0900 Subject: [PATCH 34/58] Add a database reset method. --- osu.Game/Database/BeatmapDatabase.cs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/osu.Game/Database/BeatmapDatabase.cs b/osu.Game/Database/BeatmapDatabase.cs index c23db37f08..e659d654f3 100644 --- a/osu.Game/Database/BeatmapDatabase.cs +++ b/osu.Game/Database/BeatmapDatabase.cs @@ -33,7 +33,18 @@ namespace osu.Game.Database } } - public void ImportBeatmap(string path) + public void Reset() + { + foreach (var setInfo in Query()) + storage.Delete(setInfo.Path); + + connection.DeleteAll(); + connection.DeleteAll(); + connection.DeleteAll(); + connection.DeleteAll(); + } + + public void Import(string path) { string hash = null; BeatmapMetadata metadata; From 0c9e26e54627fdb9e8c763fe25542c0b3c12bf54 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Oct 2016 17:02:00 +0900 Subject: [PATCH 35/58] Return the populated item when calling GetChildren to write more elegant code. --- osu.Game/Database/BeatmapDatabase.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/osu.Game/Database/BeatmapDatabase.cs b/osu.Game/Database/BeatmapDatabase.cs index e659d654f3..5e5db103ac 100644 --- a/osu.Game/Database/BeatmapDatabase.cs +++ b/osu.Game/Database/BeatmapDatabase.cs @@ -139,9 +139,12 @@ namespace osu.Game.Database return connection.GetAllWithChildren(filter, recursive); } - public void GetChildren(T item, bool recursive = true) + public T GetChildren(T item, bool recursive = true) { - connection.GetChildren(item, recursive); + if (item == null) return default(T); + + connection.GetChildren(item, recursive); + return item; } readonly Type[] validTypes = new[] From d3a857edb981d5da9370cd5cb6d8280b47ff09fa Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 21 Oct 2016 18:25:22 +0900 Subject: [PATCH 36/58] Make importing work properly. Moves import code to BeatmapDatabase. --- osu.Desktop/Program.cs | 27 +++-- .../Beatmaps/IO/ImportBeatmapTest.cs | 109 ++++++++++++++++++ osu.Game.Tests/app.config | 11 ++ osu.Game.Tests/osu.Game.Tests.csproj | 34 ++++-- osu.Game.Tests/packages.config | 3 +- osu.Game/Database/BeatmapDatabase.cs | 109 ++++++++++-------- osu.Game/IPC/BeatmapImporter.cs | 46 ++++++++ osu.Game/OsuGame.cs | 38 ++---- osu.Game/OsuGameBase.cs | 5 +- osu.Game/osu.Game.csproj | 1 + 10 files changed, 286 insertions(+), 97 deletions(-) create mode 100644 osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs create mode 100644 osu.Game.Tests/app.config create mode 100644 osu.Game/IPC/BeatmapImporter.cs diff --git a/osu.Desktop/Program.cs b/osu.Desktop/Program.cs index c78ea962ff..36837044a1 100644 --- a/osu.Desktop/Program.cs +++ b/osu.Desktop/Program.cs @@ -6,8 +6,10 @@ using System.IO; using System.Linq; using osu.Framework; using osu.Framework.Desktop; +using osu.Framework.Desktop.Platform; using osu.Framework.Platform; using osu.Game; +using osu.Game.IPC; namespace osu.Desktop { @@ -16,19 +18,24 @@ namespace osu.Desktop [STAThread] public static int Main(string[] args) { - BasicGameHost host = Host.GetSuitableHost(@"osu"); - BaseGame osuGame = new OsuGame(); - if (args.Length != 0 && args.All(File.Exists)) + DesktopGameHost host = Host.GetSuitableHost(@"osu", true); + + if (!host.IsPrimaryInstance) { - host.Load(osuGame); - var beatmapIPC = new IpcChannel(host); + var importer = new BeatmapImporter(host); + foreach (var file in args) - beatmapIPC.SendMessage(new OsuGame.ImportBeatmap { Path = file }).Wait(); - Console.WriteLine(@"Sent file to running instance"); - return 0; + if (importer.Import(file).Wait(1000)) + throw new TimeoutException(@"IPC took too long to send"); + Console.WriteLine(@"Sent import requests to running instance"); } - host.Add(osuGame); - host.Run(); + else + { + BaseGame osu = new OsuGame(args); + host.Add(osu); + host.Run(); + } + return 0; } } diff --git a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs new file mode 100644 index 0000000000..e57fc71666 --- /dev/null +++ b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs @@ -0,0 +1,109 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading; +using NUnit.Framework; +using osu.Framework.Desktop.Platform; +using osu.Framework.Platform; +using osu.Game.Database; +using osu.Game.IPC; + +namespace osu.Game.Tests.Beatmaps.IO +{ + [TestFixture] + public class ImportBeatmapTest + { + const string osz_path = @"../../../osu-resources/osu.Game.Resources/Beatmaps/241526 Soleily - Renatus.osz"; + + [TestFixtureSetUp] + public void SetUp() + { + } + + [Test] + public void TestImportWhenClosed() + { + //unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here. + HeadlessGameHost host = new HeadlessGameHost(); + + var osu = loadOsu(host); + osu.Beatmaps.Import(osz_path); + ensureLoaded(osu); + } + + [Test] + public void TestImportOverIPC() + { + HeadlessGameHost host = new HeadlessGameHost(true); + HeadlessGameHost client = new HeadlessGameHost(true); + + Assert.IsTrue(host.IsPrimaryInstance); + Assert.IsTrue(!client.IsPrimaryInstance); + + var osu = loadOsu(host); + + var importer = new BeatmapImporter(client); + if (!importer.Import(osz_path).Wait(1000)) + Assert.Fail(@"IPC took too long to send"); + + ensureLoaded(osu, 10000); + } + + private OsuGameBase loadOsu(BasicGameHost host) + { + var osu = new OsuGameBase(); + host.Add(osu); + + //reset beatmap database (sqlite and storage backing) + osu.Beatmaps.Reset(); + + return osu; + } + + private void ensureLoaded(OsuGameBase osu, int timeout = 100) + { + IEnumerable resultSets = null; + + Action waitAction = () => + { + while ((resultSets = osu.Beatmaps.Query().Where(s => s.BeatmapSetID == 241526)).Count() != 1) + Thread.Sleep(1); + }; + + Assert.IsTrue(waitAction.BeginInvoke(null, null).AsyncWaitHandle.WaitOne(timeout), + @"BeatmapSet did not import to the database"); + + //ensure we were stored to beatmap database backing... + + Assert.IsTrue(resultSets.Count() == 1); + + IEnumerable resultBeatmaps = null; + + //if we don't re-check here, the set will be inserted but the beatmaps won't be present yet. + waitAction = () => + { + while ((resultBeatmaps = osu.Beatmaps.Query().Where(s => s.BeatmapSetID == 241526 && s.BaseDifficultyID > 0)).Count() != 12) + Thread.Sleep(1); + }; + + Assert.IsTrue(waitAction.BeginInvoke(null, null).AsyncWaitHandle.WaitOne(timeout), + @"Beatmaps did not import to the database"); + + //fetch children and check we can load from the post-storage path... + var set = osu.Beatmaps.GetChildren(resultSets.First()); + + Assert.IsTrue(set.Beatmaps.Count == resultBeatmaps.Count()); + + foreach (BeatmapInfo b in resultBeatmaps) + Assert.IsTrue(set.Beatmaps.Any(c => c.BeatmapID == b.BeatmapID)); + + Assert.IsTrue(set.Beatmaps.Count > 0); + + var beatmap = osu.Beatmaps.GetBeatmap(set.Beatmaps[0]); + + Assert.IsTrue(beatmap.HitObjects.Count > 0); + } + } +} + diff --git a/osu.Game.Tests/app.config b/osu.Game.Tests/app.config new file mode 100644 index 0000000000..44ccc4b77a --- /dev/null +++ b/osu.Game.Tests/app.config @@ -0,0 +1,11 @@ + + + + + + + + + + + \ 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 264eabd85c..0718c61942 100644 --- a/osu.Game.Tests/osu.Game.Tests.csproj +++ b/osu.Game.Tests/osu.Game.Tests.csproj @@ -1,4 +1,4 @@ - + Debug @@ -30,6 +30,21 @@ ..\packages\NUnit.3.5.0\lib\net45\nunit.framework.dll True + + ..\packages\SQLite.Net-PCL.3.0.5\lib\net40\SQLite.Net.dll + True + + + ..\packages\SQLite.Net-PCL.3.0.5\lib\net40\SQLite.Net.Platform.Generic.dll + True + + + ..\packages\SQLite.Net-PCL.3.0.5\lib\net4\SQLite.Net.Platform.Win32.dll + True + + + + $(SolutionDir)\packages\NUnit.2.6.4\lib\nunit.framework.dll ..\packages\ppy.OpenTK.2.0.50727.1337\lib\net20\OpenTK.dll @@ -40,10 +55,19 @@ + + + {65DC628F-A640-4111-AB35-3A5652BC1E17} + osu.Framework.Desktop + + + {c76bf5b3-985e-4d39-95fe-97c9c879b83a} + osu.Framework + {0D3FBF8A-7464-4CF7-8C90-3E7886DF2D4D} osu.Game @@ -53,14 +77,10 @@ osu.Game.Resources - - - - - - + + diff --git a/osu.Game.Tests/packages.config b/osu.Game.Tests/packages.config index 00f92c3cb8..ca50867221 100644 --- a/osu.Game.Tests/packages.config +++ b/osu.Game.Tests/packages.config @@ -2,4 +2,5 @@ - \ No newline at end of file + + diff --git a/osu.Game/Database/BeatmapDatabase.cs b/osu.Game/Database/BeatmapDatabase.cs index 5e5db103ac..a39caac2fe 100644 --- a/osu.Game/Database/BeatmapDatabase.cs +++ b/osu.Game/Database/BeatmapDatabase.cs @@ -9,6 +9,7 @@ using osu.Framework.Platform; using osu.Game.Beatmaps; using osu.Game.Beatmaps.Formats; using osu.Game.Beatmaps.IO; +using osu.Game.IPC; using SQLite.Net; using SQLiteNetExtensions.Extensions; @@ -19,10 +20,15 @@ namespace osu.Game.Database private static SQLiteConnection connection { get; set; } private BasicStorage storage; public event Action BeatmapSetAdded; - - public BeatmapDatabase(BasicStorage storage) + + private BeatmapImporter ipc; + + public BeatmapDatabase(BasicGameHost host) { - this.storage = storage; + this.storage = host.Storage; + + ipc = new BeatmapImporter(host, this); + if (connection == null) { connection = storage.GetDatabase(@"beatmaps"); @@ -44,58 +50,63 @@ namespace osu.Game.Database connection.DeleteAll(); } - public void Import(string path) + public void Import(params string[] paths) { - string hash = null; - BeatmapMetadata metadata; - - using (var reader = ArchiveReader.GetReader(storage, path)) - metadata = reader.ReadMetadata(); - - if (connection.Table().Count(b => b.BeatmapSetID == metadata.BeatmapSetID) != 0) - return; // TODO: Update this beatmap instead - - if (File.Exists(path)) // Not always the case, i.e. for LegacyFilesystemReader + foreach (string p in paths) { - using (var md5 = MD5.Create()) - using (var input = storage.GetStream(path)) + var path = p; + string hash = null; + + BeatmapMetadata metadata; + + using (var reader = ArchiveReader.GetReader(storage, path)) + metadata = reader.ReadMetadata(); + + if (connection.Table().Count(b => b.BeatmapSetID == metadata.BeatmapSetID) != 0) + return; // TODO: Update this beatmap instead + + if (File.Exists(path)) // Not always the case, i.e. for LegacyFilesystemReader { - hash = BitConverter.ToString(md5.ComputeHash(input)).Replace("-", "").ToLowerInvariant(); - input.Seek(0, SeekOrigin.Begin); - path = Path.Combine(@"beatmaps", hash.Remove(1), hash.Remove(2), hash); - using (var output = storage.GetStream(path, FileAccess.Write)) - input.CopyTo(output); - } - } - var beatmapSet = new BeatmapSetInfo - { - BeatmapSetID = metadata.BeatmapSetID, - Beatmaps = new List(), - Path = path, - Hash = hash, - Metadata = metadata - }; - - using (var reader = ArchiveReader.GetReader(storage, path)) - { - string[] mapNames = reader.ReadBeatmaps(); - foreach (var name in mapNames) - { - using (var stream = new StreamReader(reader.ReadFile(name))) + using (var md5 = MD5.Create()) + using (var input = storage.GetStream(path)) { - var decoder = BeatmapDecoder.GetDecoder(stream); - Beatmap beatmap = decoder.Decode(stream); - beatmap.BeatmapInfo.Path = name; - - // TODO: Diff beatmap metadata with set metadata and leave it here if necessary - beatmap.BeatmapInfo.Metadata = null; - - beatmapSet.Beatmaps.Add(beatmap.BeatmapInfo); + hash = BitConverter.ToString(md5.ComputeHash(input)).Replace("-", "").ToLowerInvariant(); + input.Seek(0, SeekOrigin.Begin); + path = Path.Combine(@"beatmaps", hash.Remove(1), hash.Remove(2), hash); + using (var output = storage.GetStream(path, FileAccess.Write)) + input.CopyTo(output); } } + var beatmapSet = new BeatmapSetInfo + { + BeatmapSetID = metadata.BeatmapSetID, + Beatmaps = new List(), + Path = path, + Hash = hash, + Metadata = metadata + }; + + using (var reader = ArchiveReader.GetReader(storage, path)) + { + string[] mapNames = reader.ReadBeatmaps(); + foreach (var name in mapNames) + { + using (var stream = new StreamReader(reader.ReadFile(name))) + { + var decoder = BeatmapDecoder.GetDecoder(stream); + Beatmap beatmap = decoder.Decode(stream); + beatmap.BeatmapInfo.Path = name; + + // TODO: Diff beatmap metadata with set metadata and leave it here if necessary + beatmap.BeatmapInfo.Metadata = null; + + beatmapSet.Beatmaps.Add(beatmap.BeatmapInfo); + } + } + } + connection.InsertWithChildren(beatmapSet, true); + BeatmapSetAdded?.Invoke(beatmapSet); } - connection.InsertWithChildren(beatmapSet, true); - BeatmapSetAdded?.Invoke(beatmapSet); } public ArchiveReader GetReader(BeatmapSetInfo beatmapSet) @@ -154,7 +165,7 @@ namespace osu.Game.Database typeof(BeatmapMetadata), typeof(BaseDifficulty), }; - + public void Update(T record, bool cascade = true) where T : class { if (!validTypes.Any(t => t == typeof(T))) diff --git a/osu.Game/IPC/BeatmapImporter.cs b/osu.Game/IPC/BeatmapImporter.cs new file mode 100644 index 0000000000..1c011ebf5b --- /dev/null +++ b/osu.Game/IPC/BeatmapImporter.cs @@ -0,0 +1,46 @@ +//Copyright (c) 2007-2016 ppy Pty Ltd . +//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Diagnostics; +using System.Threading.Tasks; +using osu.Framework.Platform; +using osu.Game.Database; + +namespace osu.Game.IPC +{ + public class BeatmapImporter + { + private IpcChannel channel; + private BeatmapDatabase beatmaps; + + public BeatmapImporter(BasicGameHost host, BeatmapDatabase beatmaps = null) + { + this.beatmaps = beatmaps; + + channel = new IpcChannel(host); + channel.MessageReceived += messageReceived; + } + + public async Task Import(string path) + { + if (beatmaps != null) + beatmaps.Import(path); + else + { + await channel.SendMessage(new BeatmapImportMessage { Path = path }); + } + } + + private void messageReceived(BeatmapImportMessage msg) + { + Debug.Assert(beatmaps != null); + + Import(msg.Path); + } + } + + public class BeatmapImportMessage + { + public string Path; + } +} diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 11fc3fd33c..db74e2f020 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -9,38 +9,33 @@ using osu.Game.GameModes.Menu; using OpenTK; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Sprites; using osu.Framework.Platform; -using osu.Game.GameModes; -using osu.Game.Graphics.Background; using osu.Game.GameModes.Play; -using osu.Game.Graphics.Containers; using osu.Game.Overlays; using osu.Framework; using osu.Framework.Input; using osu.Game.Input; using OpenTK.Input; -using System.IO; -using osu.Game.Beatmaps.IO; using osu.Framework.Logging; namespace osu.Game { public class OsuGame : OsuGameBase { - public class ImportBeatmap - { - public string Path; - } - public Toolbar Toolbar; public ChatConsole Chat; public MainMenu MainMenu => intro?.ChildGameMode as MainMenu; private Intro intro; - private IpcChannel BeatmapIPC; public Bindable PlayMode; + string[] args; + + public OsuGame(string[] args = null) + { + this.args = args; + } + public override void SetHost(BasicGameHost host) { base.SetHost(host); @@ -50,30 +45,17 @@ namespace osu.Game public override void Load(BaseGame game) { - BeatmapIPC = new IpcChannel(Host); - if (!Host.IsPrimaryInstance) { Logger.Log(@"osu! does not support multiple running instances.", LoggingTarget.Runtime, LogLevel.Error); Environment.Exit(0); } - BeatmapIPC.MessageReceived += message => - { - try - { - Beatmaps.ImportBeatmap(message.Path); - // TODO: Switch to beatmap list and select the new song - } - catch (Exception ex) - { - // TODO: Show the user some info? - Logger.Log($@"Failed to import beatmap: {ex}", LoggingTarget.Runtime, LogLevel.Error); - } - }; - base.Load(game); + if (args?.Length > 0) + Schedule(delegate { Beatmaps.Import(args); }); + //attach our bindables to the audio subsystem. Audio.Volume.Weld(Config.GetBindable(OsuConfig.VolumeGlobal)); Audio.VolumeSample.Weld(Config.GetBindable(OsuConfig.VolumeEffect)); diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index ba6dd19506..96b56f1d1b 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -10,6 +10,7 @@ using osu.Game.Configuration; using osu.Game.Database; using osu.Game.Graphics.Cursor; using osu.Game.Graphics.Processing; +using osu.Game.IPC; using osu.Game.Online.API; using osu.Game.Overlays; @@ -18,7 +19,7 @@ namespace osu.Game public class OsuGameBase : BaseGame { internal OsuConfigManager Config = new OsuConfigManager(); - internal BeatmapDatabase Beatmaps { get; private set; } + public BeatmapDatabase Beatmaps { get; private set; } protected override string MainResourceFile => @"osu.Game.Resources.dll"; @@ -47,7 +48,7 @@ namespace osu.Game base.Load(game); OszArchiveReader.Register(); - Beatmaps = new BeatmapDatabase(Host.Storage); + Beatmaps = new BeatmapDatabase(Host); //this completely overrides the framework default. will need to change once we make a proper FontStore. Fonts = new TextureStore() { ScaleAdjust = 0.01f }; diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 0ee86c5237..4041045343 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -156,6 +156,7 @@ + From cfc920c9c18e4244356f3df30cc3730b21e471b7 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Fri, 21 Oct 2016 10:52:52 -0400 Subject: [PATCH 37/58] Implement Play button, drop textures --- osu.Game/GameModes/Play/BeatmapGroup.cs | 24 ++-------------- osu.Game/GameModes/Play/PlaySongSelect.cs | 34 ++++++++++++++++++----- 2 files changed, 30 insertions(+), 28 deletions(-) diff --git a/osu.Game/GameModes/Play/BeatmapGroup.cs b/osu.Game/GameModes/Play/BeatmapGroup.cs index ef0c78a62e..f59a15f24f 100644 --- a/osu.Game/GameModes/Play/BeatmapGroup.cs +++ b/osu.Game/GameModes/Play/BeatmapGroup.cs @@ -101,7 +101,7 @@ namespace osu.Game.GameModes.Play BeatmapSelected?.Invoke(BeatmapSet, map); } - public BeatmapGroup(BeatmapSetInfo beatmapSet, BeatmapResourceStore beatmapStore, TextureStore resources) + public BeatmapGroup(BeatmapSetInfo beatmapSet) { BeatmapSet = beatmapSet; selectedBeatmap = beatmapSet.Beatmaps[0]; @@ -118,7 +118,7 @@ namespace osu.Game.GameModes.Play Direction = FlowDirection.VerticalOnly, Children = new[] { - setBox = new BeatmapSetBox(beatmapSet, beatmapStore, resources) + setBox = new BeatmapSetBox(beatmapSet) { RelativeSizeAxes = Axes.X, Size = new Vector2(collapsedWidth, -1), @@ -164,15 +164,11 @@ namespace osu.Game.GameModes.Play class BeatmapSetBox : AutoSizeContainer { private BeatmapSetInfo beatmapSet; - private BeatmapResourceStore beatmapStore; - private TextureStore resources; private Sprite backgroundImage; - public BeatmapSetBox(BeatmapSetInfo beatmapSet, BeatmapResourceStore beatmapStore, TextureStore resources) + public BeatmapSetBox(BeatmapSetInfo beatmapSet) { this.beatmapSet = beatmapSet; - this.beatmapStore = beatmapStore; - this.resources = resources; Masking = true; CornerRadius = 5; BorderThickness = 2; @@ -237,20 +233,6 @@ namespace osu.Game.GameModes.Play } }; } - - public override void Load(Framework.BaseGame game) - { - base.Load(game); - if (beatmapSet.Metadata.BackgroundFile != null) - { - Task.Factory.StartNew(() => - { - beatmapStore.AddBeatmap(beatmapSet); - var texture = resources.Get($@"{beatmapSet.BeatmapSetID}:{beatmapSet.Metadata.BackgroundFile}"); - Scheduler.Add(() => backgroundImage.Texture = texture); - }); - } - } } class DifficultyIcon : Container diff --git a/osu.Game/GameModes/Play/PlaySongSelect.cs b/osu.Game/GameModes/Play/PlaySongSelect.cs index 1815925c94..b2e749e5fc 100644 --- a/osu.Game/GameModes/Play/PlaySongSelect.cs +++ b/osu.Game/GameModes/Play/PlaySongSelect.cs @@ -27,8 +27,6 @@ namespace osu.Game.GameModes.Play private BeatmapDatabase beatmaps; private BeatmapSetInfo selectedBeatmapSet; private BeatmapInfo selectedBeatmap; - private BeatmapResourceStore beatmapResources; - private TextureStore beatmapTextureResources; // TODO: use currently selected track as bg protected override BackgroundMode CreateBackground() => new BackgroundModeCustom(@"Backgrounds/bg4"); private ScrollContainer scrollContainer; @@ -62,7 +60,7 @@ namespace osu.Game.GameModes.Play beatmapSet.Beatmaps.ForEach(b => beatmaps.GetChildren(b)); beatmapSet.Beatmaps = beatmapSet.Beatmaps.OrderBy(b => b.BaseDifficulty.OverallDifficulty) .ToList(); - var group = new BeatmapGroup(beatmapSet, beatmapResources, beatmapTextureResources); + var group = new BeatmapGroup(beatmapSet); group.SetSelected += selectBeatmapSet; group.BeatmapSelected += selectBeatmap; setList.Add(group); @@ -121,6 +119,32 @@ namespace osu.Game.GameModes.Play Spacing = new Vector2(0, 5), } } + }, + new Container + { + RelativeSizeAxes = Axes.X, + Size = new Vector2(1, 50), + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Size = Vector2.One, + Colour = new Color4(0, 0, 0, 0.5f), + }, + new Button + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + RelativeSizeAxes = Axes.Y, + Size = new Vector2(100, 1), + Text = "Play", + Colour = new Color4(238, 51, 153, 255), + Action = () => Push(new Player { /*Beatmap = selectedBeatmap*/ }), + }, + } } }; } @@ -139,8 +163,6 @@ namespace osu.Game.GameModes.Play } beatmaps = (game as OsuGameBase).Beatmaps; - beatmapTextureResources = new TextureStore( - new RawTextureLoaderStore(beatmapResources = new BeatmapResourceStore(beatmaps))); beatmaps.BeatmapSetAdded += bset => Scheduler.Add(() => addBeatmapSet(bset)); addBeatmapSets(); var first = setList.Children.FirstOrDefault() as BeatmapGroup; @@ -157,8 +179,6 @@ namespace osu.Game.GameModes.Play base.Dispose(isDisposing); if (playMode != null) playMode.ValueChanged -= PlayMode_ValueChanged; - if (beatmapResources != null) - beatmapResources.Dispose(); } private void PlayMode_ValueChanged(object sender, EventArgs e) From e5168f8da8443fed25cc51100626eddbcf6d9375 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Fri, 21 Oct 2016 11:10:15 -0400 Subject: [PATCH 38/58] Implement handoff to Player --- osu.Game/GameModes/Play/Osu/OsuHitRenderer.cs | 3 ++- osu.Game/GameModes/Play/PlaySongSelect.cs | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game/GameModes/Play/Osu/OsuHitRenderer.cs b/osu.Game/GameModes/Play/Osu/OsuHitRenderer.cs index 865f567a86..9e12d69d2b 100644 --- a/osu.Game/GameModes/Play/Osu/OsuHitRenderer.cs +++ b/osu.Game/GameModes/Play/Osu/OsuHitRenderer.cs @@ -14,6 +14,7 @@ namespace osu.Game.GameModes.Play.Osu protected override Playfield CreatePlayfield() => new OsuPlayfield(); - protected override DrawableHitObject GetVisualRepresentation(OsuBaseHit h) => new DrawableCircle(h as Circle); + protected override DrawableHitObject GetVisualRepresentation(OsuBaseHit h) + => h is Circle ? new DrawableCircle(h as Circle) : null; } } diff --git a/osu.Game/GameModes/Play/PlaySongSelect.cs b/osu.Game/GameModes/Play/PlaySongSelect.cs index b2e749e5fc..4f86f46fb4 100644 --- a/osu.Game/GameModes/Play/PlaySongSelect.cs +++ b/osu.Game/GameModes/Play/PlaySongSelect.cs @@ -142,7 +142,7 @@ namespace osu.Game.GameModes.Play Size = new Vector2(100, 1), Text = "Play", Colour = new Color4(238, 51, 153, 255), - Action = () => Push(new Player { /*Beatmap = selectedBeatmap*/ }), + Action = () => Push(new Player { Beatmap = beatmaps.GetBeatmap(selectedBeatmap) }), }, } } From ff1a5187cd62524f86aa06090b9a8a6ae297b4fa Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Mon, 24 Oct 2016 09:58:51 -0400 Subject: [PATCH 39/58] Implement fixes related to auto size changes --- osu-resources | 2 +- osu.Game/GameModes/Play/BeatmapButton.cs | 8 +++-- osu.Game/GameModes/Play/BeatmapGroup.cs | 37 ++++++++++-------------- 3 files changed, 22 insertions(+), 25 deletions(-) diff --git a/osu-resources b/osu-resources index ca807cf81a..0505cf0d3b 160000 --- a/osu-resources +++ b/osu-resources @@ -1 +1 @@ -Subproject commit ca807cf81ae3706972937d4e1009376cfaa0b266 +Subproject commit 0505cf0d3b317667dbc95346f57b67fdbcdb4dee diff --git a/osu.Game/GameModes/Play/BeatmapButton.cs b/osu.Game/GameModes/Play/BeatmapButton.cs index 2d99fda0f9..d31f1b3a54 100644 --- a/osu.Game/GameModes/Play/BeatmapButton.cs +++ b/osu.Game/GameModes/Play/BeatmapButton.cs @@ -21,7 +21,7 @@ using osu.Game.Graphics.UserInterface; namespace osu.Game.GameModes.Play { - class BeatmapButton : AutoSizeContainer + class BeatmapButton : Container { private BeatmapSetInfo beatmapSet; private BeatmapInfo beatmap; @@ -51,6 +51,7 @@ namespace osu.Game.GameModes.Play { this.beatmapSet = set; this.beatmap = beatmap; + AutoSizeAxes = Axes.Y; Masking = true; CornerRadius = 5; BorderThickness = 2; @@ -62,12 +63,13 @@ namespace osu.Game.GameModes.Play { Colour = new Color4(40, 86, 102, 255), // TODO: gradient RelativeSizeAxes = Axes.Both, - Size = new Vector2(1), + Size = Vector2.One, }, new FlowContainer { Padding = new MarginPadding(5), Direction = FlowDirection.HorizontalOnly, + AutoSizeAxes = Axes.Both, Children = new Drawable[] { new DifficultyIcon(FontAwesome.dot_circle_o, new Color4(159, 198, 0, 255)), @@ -75,11 +77,13 @@ namespace osu.Game.GameModes.Play { Padding = new MarginPadding { Left = 10 }, Direction = FlowDirection.VerticalOnly, + AutoSizeAxes = Axes.Both, Children = new Drawable[] { new FlowContainer { Direction = FlowDirection.HorizontalOnly, + AutoSizeAxes = Axes.Both, Children = new[] { new SpriteText diff --git a/osu.Game/GameModes/Play/BeatmapGroup.cs b/osu.Game/GameModes/Play/BeatmapGroup.cs index f59a15f24f..6b86df329a 100644 --- a/osu.Game/GameModes/Play/BeatmapGroup.cs +++ b/osu.Game/GameModes/Play/BeatmapGroup.cs @@ -20,7 +20,7 @@ using System.Threading.Tasks; namespace osu.Game.GameModes.Play { - class BeatmapGroup : AutoSizeContainer + class BeatmapGroup : Container { private const float collapsedAlpha = 0.5f; private const float collapsedWidth = 0.8f; @@ -64,13 +64,7 @@ namespace osu.Game.GameModes.Play else topContainer.Add(difficulties); setBox.ClearTransformations(); - setBox.Transforms.Add(new TransformSize(Clock) - { - StartValue = new Vector2(collapsed ? 1 : collapsedWidth, -1), - EndValue = new Vector2(collapsed ? collapsedWidth : 1, -1), - StartTime = Time, - EndTime = Time + 200, - }); + setBox.Width = collapsed ? collapsedWidth : 1; // TODO: Transform setBox.BorderColour = new Color4( setBox.BorderColour.R, setBox.BorderColour.G, @@ -89,13 +83,7 @@ namespace osu.Game.GameModes.Play var button = buttons[i] as BeatmapButton; float targetWidth = 1 - Math.Abs((selected - i) * 0.025f); targetWidth = MathHelper.Clamp(targetWidth, 0.8f, 1); - button.Transforms.Add(new TransformSize(Clock) - { - StartValue = new Vector2(button.Size.X, -1), - EndValue = new Vector2(targetWidth, -1), - StartTime = Time, - EndTime = Time + 100, - }); + button.Width = targetWidth; // TODO: Transform button.Selected = selected == i; } BeatmapSelected?.Invoke(BeatmapSet, map); @@ -106,22 +94,24 @@ namespace osu.Game.GameModes.Play BeatmapSet = beatmapSet; selectedBeatmap = beatmapSet.Beatmaps[0]; Alpha = collapsedAlpha; + AutoSizeAxes = Axes.Y; RelativeSizeAxes = Axes.X; - Size = new Vector2(1, -1); + Width = 1; float difficultyWidth = 1; Children = new[] { topContainer = new FlowContainer { RelativeSizeAxes = Axes.X, - Size = new Vector2(1, -1), + AutoSizeAxes = Axes.Y, + Width = 1, Direction = FlowDirection.VerticalOnly, Children = new[] { setBox = new BeatmapSetBox(beatmapSet) { RelativeSizeAxes = Axes.X, - Size = new Vector2(collapsedWidth, -1), + Width = collapsedWidth, Anchor = Anchor.TopRight, Origin = Anchor.TopRight, } @@ -131,7 +121,8 @@ namespace osu.Game.GameModes.Play difficulties = new FlowContainer // Deliberately not added to children { RelativeSizeAxes = Axes.X, - Size = new Vector2(1, -1), + AutoSizeAxes = Axes.Y, + Width = 1, Margin = new MarginPadding { Top = 5 }, Padding = new MarginPadding { Left = 75 }, Spacing = new Vector2(0, 5), @@ -147,7 +138,7 @@ namespace osu.Game.GameModes.Play Anchor = Anchor.TopRight, Origin = Anchor.TopRight, RelativeSizeAxes = Axes.X, - Size = new Vector2(width, -1), + Width = width, }; }) }; @@ -161,7 +152,7 @@ namespace osu.Game.GameModes.Play } } - class BeatmapSetBox : AutoSizeContainer + class BeatmapSetBox : Container { private BeatmapSetInfo beatmapSet; private Sprite backgroundImage; @@ -169,6 +160,7 @@ namespace osu.Game.GameModes.Play public BeatmapSetBox(BeatmapSetInfo beatmapSet) { this.beatmapSet = beatmapSet; + AutoSizeAxes = Axes.Y; Masking = true; CornerRadius = 5; BorderThickness = 2; @@ -191,7 +183,7 @@ namespace osu.Game.GameModes.Play backgroundImage = new Sprite { RelativeSizeAxes = Axes.X, - Size = new Vector2(1, 0), + Width = 1, Anchor = Anchor.Centre, Origin = Anchor.Centre, }, @@ -208,6 +200,7 @@ namespace osu.Game.GameModes.Play Direction = FlowDirection.VerticalOnly, Spacing = new Vector2(0, 2), Padding = new MarginPadding { Top = 3, Left = 20, Right = 20, Bottom = 3 }, + AutoSizeAxes = Axes.Both, Children = new[] { // TODO: Make these italic From 86bbe8688b695a81770c928602c24086d8468ca9 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Mon, 24 Oct 2016 11:01:53 -0400 Subject: [PATCH 40/58] Fix issues with invisible beatmaps --- osu.Game/GameModes/Play/BeatmapGroup.cs | 4 ---- osu.Game/GameModes/Play/PlaySongSelect.cs | 4 ++-- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/osu.Game/GameModes/Play/BeatmapGroup.cs b/osu.Game/GameModes/Play/BeatmapGroup.cs index 6b86df329a..e46d42df91 100644 --- a/osu.Game/GameModes/Play/BeatmapGroup.cs +++ b/osu.Game/GameModes/Play/BeatmapGroup.cs @@ -96,7 +96,6 @@ namespace osu.Game.GameModes.Play Alpha = collapsedAlpha; AutoSizeAxes = Axes.Y; RelativeSizeAxes = Axes.X; - Width = 1; float difficultyWidth = 1; Children = new[] { @@ -104,7 +103,6 @@ namespace osu.Game.GameModes.Play { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Width = 1, Direction = FlowDirection.VerticalOnly, Children = new[] { @@ -122,7 +120,6 @@ namespace osu.Game.GameModes.Play { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Width = 1, Margin = new MarginPadding { Top = 5 }, Padding = new MarginPadding { Left = 75 }, Spacing = new Vector2(0, 5), @@ -183,7 +180,6 @@ namespace osu.Game.GameModes.Play backgroundImage = new Sprite { RelativeSizeAxes = Axes.X, - Width = 1, Anchor = Anchor.Centre, Origin = Anchor.Centre, }, diff --git a/osu.Game/GameModes/Play/PlaySongSelect.cs b/osu.Game/GameModes/Play/PlaySongSelect.cs index 4f86f46fb4..125364e5e0 100644 --- a/osu.Game/GameModes/Play/PlaySongSelect.cs +++ b/osu.Game/GameModes/Play/PlaySongSelect.cs @@ -80,7 +80,7 @@ namespace osu.Game.GameModes.Play new Container { RelativeSizeAxes = Axes.Both, - Size = new Vector2(1), + Size = Vector2.One, Padding = new MarginPadding { Right = scrollWidth - 200 }, Children = new[] { @@ -114,7 +114,7 @@ namespace osu.Game.GameModes.Play { Padding = new MarginPadding { Left = 25, Top = 25, Bottom = 25 }, RelativeSizeAxes = Axes.X, - Size = new Vector2(1, -1), + AutoSizeAxes = Axes.X, Direction = FlowDirection.VerticalOnly, Spacing = new Vector2(0, 5), } From b0898a3ce060c9905212bfe52a6d3432c35a6367 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Mon, 24 Oct 2016 11:08:48 -0400 Subject: [PATCH 41/58] Fix sizing of setList flow container --- osu.Game/GameModes/Play/PlaySongSelect.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/osu.Game/GameModes/Play/PlaySongSelect.cs b/osu.Game/GameModes/Play/PlaySongSelect.cs index 125364e5e0..ce6c11a610 100644 --- a/osu.Game/GameModes/Play/PlaySongSelect.cs +++ b/osu.Game/GameModes/Play/PlaySongSelect.cs @@ -75,6 +75,7 @@ namespace osu.Game.GameModes.Play public PlaySongSelect() { const float scrollWidth = 640; + const float bottomToolHeight = 50; Children = new Drawable[] { new Container @@ -112,9 +113,9 @@ namespace osu.Game.GameModes.Play { setList = new FlowContainer { - Padding = new MarginPadding { Left = 25, Top = 25, Bottom = 25 }, + Padding = new MarginPadding { Left = 25, Top = 25, Bottom = 25 + bottomToolHeight }, RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, Direction = FlowDirection.VerticalOnly, Spacing = new Vector2(0, 5), } @@ -123,7 +124,7 @@ namespace osu.Game.GameModes.Play new Container { RelativeSizeAxes = Axes.X, - Size = new Vector2(1, 50), + Height = bottomToolHeight, Anchor = Anchor.BottomCentre, Origin = Anchor.BottomCentre, Children = new Drawable[] @@ -139,7 +140,7 @@ namespace osu.Game.GameModes.Play Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, RelativeSizeAxes = Axes.Y, - Size = new Vector2(100, 1), + Width = 100, Text = "Play", Colour = new Color4(238, 51, 153, 255), Action = () => Push(new Player { Beatmap = beatmaps.GetBeatmap(selectedBeatmap) }), From a1019f91bae54a79c0eaf87b6b88ac7b40a67fd0 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Mon, 24 Oct 2016 11:15:50 -0400 Subject: [PATCH 42/58] Fix auto size on BeatmapSetBox difficulties --- osu.Game/GameModes/Play/BeatmapGroup.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/GameModes/Play/BeatmapGroup.cs b/osu.Game/GameModes/Play/BeatmapGroup.cs index e46d42df91..3b0dfe1bd5 100644 --- a/osu.Game/GameModes/Play/BeatmapGroup.cs +++ b/osu.Game/GameModes/Play/BeatmapGroup.cs @@ -212,6 +212,7 @@ namespace osu.Game.GameModes.Play }, new FlowContainer { + AutoSizeAxes = Axes.Both, Children = new[] { new DifficultyIcon(FontAwesome.dot_circle_o, new Color4(159, 198, 0, 255)), From d559903ebc40898e08c22237e79801c6a619065b Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Mon, 24 Oct 2016 11:41:14 -0400 Subject: [PATCH 43/58] Fix busted test project --- osu.Game.Tests/osu.Game.Tests.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj index 0718c61942..5b7cb3e80b 100644 --- a/osu.Game.Tests/osu.Game.Tests.csproj +++ b/osu.Game.Tests/osu.Game.Tests.csproj @@ -30,6 +30,7 @@ ..\packages\NUnit.3.5.0\lib\net45\nunit.framework.dll True + ..\packages\SQLite.Net-PCL.3.0.5\lib\net40\SQLite.Net.dll True From 063fdd9a2d64f11b34a5a2c933081faf561a7f1f Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Mon, 24 Oct 2016 14:57:00 -0400 Subject: [PATCH 44/58] Add test data to db for VisualTests Also fixes the broken IPC condition --- osu.Desktop.VisualTests/Program.cs | 1 + osu.Desktop.VisualTests/VisualTestGame.cs | 64 ++++++++++++++++++- .../osu.Desktop.VisualTests.csproj | 11 +++- osu.Desktop.VisualTests/packages.config | 7 ++ osu.Desktop/Program.cs | 2 +- osu.Game/Database/BeatmapDatabase.cs | 38 +++++------ 6 files changed, 100 insertions(+), 23 deletions(-) create mode 100644 osu.Desktop.VisualTests/packages.config diff --git a/osu.Desktop.VisualTests/Program.cs b/osu.Desktop.VisualTests/Program.cs index 52aceb1ee8..4732930b0b 100644 --- a/osu.Desktop.VisualTests/Program.cs +++ b/osu.Desktop.VisualTests/Program.cs @@ -3,6 +3,7 @@ using System; using osu.Framework.Desktop; +using osu.Framework.Desktop.Platform; using osu.Framework.Platform; namespace osu.Framework.VisualTests diff --git a/osu.Desktop.VisualTests/VisualTestGame.cs b/osu.Desktop.VisualTests/VisualTestGame.cs index 5a51f28d82..38ac3b45f9 100644 --- a/osu.Desktop.VisualTests/VisualTestGame.cs +++ b/osu.Desktop.VisualTests/VisualTestGame.cs @@ -5,15 +5,77 @@ using osu.Framework.GameModes.Testing; using osu.Framework.Graphics.Cursor; using osu.Game.Database; using osu.Game; +using osu.Framework.Desktop.Platform; +using System.Reflection; +using System.IO; +using System.Collections.Generic; +using osu.Game.GameModes.Play; +using SQLiteNetExtensions.Extensions; namespace osu.Framework.VisualTests { class VisualTestGame : OsuGameBase { + private void InsertTestMap(int i) + { + var beatmapSet = new BeatmapSetInfo + { + BeatmapSetID = 1234 + i, + Hash = "d8e8fca2dc0f896fd7cb4cb0031ba249", + Path = "/foo/bar/baz", + Metadata = new BeatmapMetadata + { + BeatmapSetID = 1234 + i, + Artist = "MONACA", + Title = "Black Song", + Author = "Some Guy", + }, + Beatmaps = new List(new[] + { + new BeatmapInfo + { + BeatmapID = 1234 + i, + Mode = PlayMode.Osu, + Path = "normal.osu", + Version = "Normal", + BaseDifficulty = new BaseDifficulty + { + OverallDifficulty = 3.5f, + } + }, + new BeatmapInfo + { + BeatmapID = 1235 + i, + Mode = PlayMode.Osu, + Path = "hard.osu", + Version = "Hard", + BaseDifficulty = new BaseDifficulty + { + OverallDifficulty = 5, + } + }, + new BeatmapInfo + { + BeatmapID = 1236 + i, + Mode = PlayMode.Osu, + Path = "insane.osu", + Version = "Insane", + BaseDifficulty = new BaseDifficulty + { + OverallDifficulty = 7, + } + }, + }), + }; + BeatmapDatabase.Connection.InsertWithChildren(beatmapSet, true); + } + public override void Load(BaseGame game) { + (Host.Storage as DesktopStorage).InMemorySQL = true; base.Load(game); - + for (int i = 0; i < 100; i += 10) + InsertTestMap(i); Add(new TestBrowser()); } } diff --git a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj index 3dfe829651..2f97d991a6 100644 --- a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj +++ b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj @@ -81,15 +81,22 @@ - ..\packages\ppy.OpenTK.2.0.50727.1337\lib\net20\OpenTK.dll + $(SolutionDir)\packages\ppy.OpenTK.2.0.50727.1337\lib\net20\OpenTK.dll True + + $(SolutionDir)\packages\SQLite.Net.Core-PCL.3.1.1\lib\portable-win8+net45+wp8+wpa81+MonoAndroid1+MonoTouch1\SQLite.Net.dll + + + $(SolutionDir)\packages\SQLiteNetExtensions.1.3.0\lib\portable-net45+netcore45+wpa81+wp8+MonoAndroid1+MonoTouch1\SQLiteNetExtensions.dll + osu.licenseheader + @@ -170,4 +177,4 @@ - \ No newline at end of file + diff --git a/osu.Desktop.VisualTests/packages.config b/osu.Desktop.VisualTests/packages.config new file mode 100644 index 0000000000..62a2a41a2a --- /dev/null +++ b/osu.Desktop.VisualTests/packages.config @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/osu.Desktop/Program.cs b/osu.Desktop/Program.cs index 36837044a1..8586e3a2a9 100644 --- a/osu.Desktop/Program.cs +++ b/osu.Desktop/Program.cs @@ -25,7 +25,7 @@ namespace osu.Desktop var importer = new BeatmapImporter(host); foreach (var file in args) - if (importer.Import(file).Wait(1000)) + if (!importer.Import(file).Wait(1000)) throw new TimeoutException(@"IPC took too long to send"); Console.WriteLine(@"Sent import requests to running instance"); } diff --git a/osu.Game/Database/BeatmapDatabase.cs b/osu.Game/Database/BeatmapDatabase.cs index a39caac2fe..512ca32a75 100644 --- a/osu.Game/Database/BeatmapDatabase.cs +++ b/osu.Game/Database/BeatmapDatabase.cs @@ -17,7 +17,7 @@ namespace osu.Game.Database { public class BeatmapDatabase { - private static SQLiteConnection connection { get; set; } + public static SQLiteConnection Connection { get; set; } private BasicStorage storage; public event Action BeatmapSetAdded; @@ -29,13 +29,13 @@ namespace osu.Game.Database ipc = new BeatmapImporter(host, this); - if (connection == null) + if (Connection == null) { - connection = storage.GetDatabase(@"beatmaps"); - connection.CreateTable(); - connection.CreateTable(); - connection.CreateTable(); - connection.CreateTable(); + Connection = storage.GetDatabase(@"beatmaps"); + Connection.CreateTable(); + Connection.CreateTable(); + Connection.CreateTable(); + Connection.CreateTable(); } } @@ -44,10 +44,10 @@ namespace osu.Game.Database foreach (var setInfo in Query()) storage.Delete(setInfo.Path); - connection.DeleteAll(); - connection.DeleteAll(); - connection.DeleteAll(); - connection.DeleteAll(); + Connection.DeleteAll(); + Connection.DeleteAll(); + Connection.DeleteAll(); + Connection.DeleteAll(); } public void Import(params string[] paths) @@ -62,7 +62,7 @@ namespace osu.Game.Database using (var reader = ArchiveReader.GetReader(storage, path)) metadata = reader.ReadMetadata(); - if (connection.Table().Count(b => b.BeatmapSetID == metadata.BeatmapSetID) != 0) + if (Connection.Table().Count(b => b.BeatmapSetID == metadata.BeatmapSetID) != 0) return; // TODO: Update this beatmap instead if (File.Exists(path)) // Not always the case, i.e. for LegacyFilesystemReader @@ -104,7 +104,7 @@ namespace osu.Game.Database } } } - connection.InsertWithChildren(beatmapSet, true); + Connection.InsertWithChildren(beatmapSet, true); BeatmapSetAdded?.Invoke(beatmapSet); } } @@ -136,25 +136,25 @@ namespace osu.Game.Database public TableQuery Query() where T : class { - return connection.Table(); + return Connection.Table(); } public T GetWithChildren(object id) where T : class { - return connection.GetWithChildren(id); + return Connection.GetWithChildren(id); } public List GetAllWithChildren(Expression> filter = null, bool recursive = true) where T : class { - return connection.GetAllWithChildren(filter, recursive); + return Connection.GetAllWithChildren(filter, recursive); } public T GetChildren(T item, bool recursive = true) { if (item == null) return default(T); - connection.GetChildren(item, recursive); + Connection.GetChildren(item, recursive); return item; } @@ -171,9 +171,9 @@ namespace osu.Game.Database if (!validTypes.Any(t => t == typeof(T))) throw new ArgumentException(nameof(T), "Must be a type managed by BeatmapDatabase"); if (cascade) - connection.UpdateWithChildren(record); + Connection.UpdateWithChildren(record); else - connection.Update(record); + Connection.Update(record); } } } From cea660dce5c00f7a4fdd2f24885c59dc86b04d07 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Mon, 24 Oct 2016 15:01:04 -0400 Subject: [PATCH 45/58] Fix up JSON reference --- .../osu.Desktop.VisualTests.csproj | 12 +++++++++--- osu.Desktop.VisualTests/packages.config | 4 ++-- osu.Game.Tests/osu.Game.Tests.csproj | 10 +++++----- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj index 2f97d991a6..5a0fd5744d 100644 --- a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj +++ b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj @@ -85,12 +85,18 @@ True - - $(SolutionDir)\packages\SQLite.Net.Core-PCL.3.1.1\lib\portable-win8+net45+wp8+wpa81+MonoAndroid1+MonoTouch1\SQLite.Net.dll - $(SolutionDir)\packages\SQLiteNetExtensions.1.3.0\lib\portable-net45+netcore45+wpa81+wp8+MonoAndroid1+MonoTouch1\SQLiteNetExtensions.dll + + $(SolutionDir)\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll + + + $(SolutionDir)\packages\SQLite.Net-PCL.3.1.1\lib\net4\SQLite.Net.Platform.Win32.dll + + + $(SolutionDir)\packages\SQLite.Net-PCL.3.1.1\lib\net40\SQLite.Net.Platform.Generic.dll + diff --git a/osu.Desktop.VisualTests/packages.config b/osu.Desktop.VisualTests/packages.config index 62a2a41a2a..8c24263ce5 100644 --- a/osu.Desktop.VisualTests/packages.config +++ b/osu.Desktop.VisualTests/packages.config @@ -1,7 +1,7 @@  - + - + \ 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 5b7cb3e80b..72dbde0d43 100644 --- a/osu.Game.Tests/osu.Game.Tests.csproj +++ b/osu.Game.Tests/osu.Game.Tests.csproj @@ -28,19 +28,19 @@ - ..\packages\NUnit.3.5.0\lib\net45\nunit.framework.dll + $(SolutionDir)\packages\NUnit.3.5.0\lib\net45\nunit.framework.dll True - ..\packages\SQLite.Net-PCL.3.0.5\lib\net40\SQLite.Net.dll + $(SolutionDir)\packages\SQLite.Net-PCL.3.0.5\lib\net40\SQLite.Net.dll True - ..\packages\SQLite.Net-PCL.3.0.5\lib\net40\SQLite.Net.Platform.Generic.dll + $(SolutionDir)\packages\SQLite.Net-PCL.3.0.5\lib\net40\SQLite.Net.Platform.Generic.dll True - ..\packages\SQLite.Net-PCL.3.0.5\lib\net4\SQLite.Net.Platform.Win32.dll + $(SolutionDir)\packages\SQLite.Net-PCL.3.0.5\lib\net4\SQLite.Net.Platform.Win32.dll True @@ -48,7 +48,7 @@ $(SolutionDir)\packages\NUnit.2.6.4\lib\nunit.framework.dll - ..\packages\ppy.OpenTK.2.0.50727.1337\lib\net20\OpenTK.dll + $(SolutionDir)\packages\ppy.OpenTK.2.0.50727.1337\lib\net20\OpenTK.dll True From d986d66c2f4345f9bcd66d647cb1199735e9dadd Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Tue, 25 Oct 2016 10:44:43 -0400 Subject: [PATCH 46/58] Introduce TestStorage --- .../Platform/TestStorage.cs | 29 +++++++++++++++++++ osu.Desktop.VisualTests/VisualTestGame.cs | 3 +- .../osu.Desktop.VisualTests.csproj | 17 +++++++---- osu.Desktop.VisualTests/packages.config | 2 +- 4 files changed, 44 insertions(+), 7 deletions(-) create mode 100644 osu.Desktop.VisualTests/Platform/TestStorage.cs diff --git a/osu.Desktop.VisualTests/Platform/TestStorage.cs b/osu.Desktop.VisualTests/Platform/TestStorage.cs new file mode 100644 index 0000000000..4e7c1867e3 --- /dev/null +++ b/osu.Desktop.VisualTests/Platform/TestStorage.cs @@ -0,0 +1,29 @@ +using System; +using System.IO; +using osu.Framework; +using osu.Framework.Desktop.Platform; +using SQLite.Net; +using SQLite.Net.Platform.Generic; +using SQLite.Net.Interop; +using SQLite.Net.Platform.Win32; + +namespace osu.Desktop.Platform +{ + public class TestStorage : DesktopStorage + { + public TestStorage(string baseName) : base(baseName) + { + } + + public override SQLiteConnection GetDatabase(string name) + { + Directory.CreateDirectory(BasePath); + ISQLitePlatform platform; + if (RuntimeInfo.IsWindows) + platform = new SQLitePlatformWin32(); + else + platform = new SQLitePlatformGeneric(); + return new SQLiteConnection(platform, $@":memory:"); + } + } +} \ No newline at end of file diff --git a/osu.Desktop.VisualTests/VisualTestGame.cs b/osu.Desktop.VisualTests/VisualTestGame.cs index 38ac3b45f9..bc77a4b304 100644 --- a/osu.Desktop.VisualTests/VisualTestGame.cs +++ b/osu.Desktop.VisualTests/VisualTestGame.cs @@ -11,6 +11,7 @@ using System.IO; using System.Collections.Generic; using osu.Game.GameModes.Play; using SQLiteNetExtensions.Extensions; +using osu.Desktop.Platform; namespace osu.Framework.VisualTests { @@ -72,7 +73,7 @@ namespace osu.Framework.VisualTests public override void Load(BaseGame game) { - (Host.Storage as DesktopStorage).InMemorySQL = true; + Host.Storage = new TestStorage(@"visual-tests"); base.Load(game); for (int i = 0; i < 100; i += 10) InsertTestMap(i); diff --git a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj index 5a0fd5744d..f288c2529a 100644 --- a/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj +++ b/osu.Desktop.VisualTests/osu.Desktop.VisualTests.csproj @@ -85,17 +85,20 @@ True - - $(SolutionDir)\packages\SQLiteNetExtensions.1.3.0\lib\portable-net45+netcore45+wpa81+wp8+MonoAndroid1+MonoTouch1\SQLiteNetExtensions.dll - $(SolutionDir)\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll - $(SolutionDir)\packages\SQLite.Net-PCL.3.1.1\lib\net4\SQLite.Net.Platform.Win32.dll + $(SolutionDir)\packages\SQLite.Net-PCL.3.0.5\lib\net4\SQLite.Net.Platform.Win32.dll + + + $(SolutionDir)\packages\SQLite.Net-PCL.3.0.5\lib\net40\SQLite.Net.dll - $(SolutionDir)\packages\SQLite.Net-PCL.3.1.1\lib\net40\SQLite.Net.Platform.Generic.dll + $(SolutionDir)\packages\SQLite.Net-PCL.3.0.5\lib\net40\SQLite.Net.Platform.Generic.dll + + + $(SolutionDir)\packages\SQLiteNetExtensions.1.3.0\lib\portable-net45+netcore45+wpa81+wp8+MonoAndroid1+MonoTouch1\SQLiteNetExtensions.dll @@ -161,8 +164,12 @@ + + + + - + \ No newline at end of file From ba5b2f2d73fcb3285d0c45a49399e6c7361c8455 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Oct 2016 12:31:45 +0900 Subject: [PATCH 55/58] Remove difficulty width offsets and tidy up flow of information. --- osu.Game/Beatmaps/Drawable/BeatmapGroup.cs | 120 +++++++++++---------- osu.Game/Beatmaps/Drawable/BeatmapPanel.cs | 6 +- osu.Game/GameModes/Play/PlaySongSelect.cs | 26 ++--- 3 files changed, 74 insertions(+), 78 deletions(-) diff --git a/osu.Game/Beatmaps/Drawable/BeatmapGroup.cs b/osu.Game/Beatmaps/Drawable/BeatmapGroup.cs index f94d267475..9baa393854 100644 --- a/osu.Game/Beatmaps/Drawable/BeatmapGroup.cs +++ b/osu.Game/Beatmaps/Drawable/BeatmapGroup.cs @@ -9,7 +9,6 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Primitives; using osu.Framework.Input; using osu.Game.Database; -using osu.Game.Graphics; using OpenTK; using OpenTK.Graphics; @@ -22,60 +21,61 @@ namespace osu.Game.Beatmaps.Drawable Collapsed, Expanded, } - + private const float collapsedAlpha = 0.5f; private const float collapsedWidth = 0.8f; - - private BeatmapInfo selectedBeatmap; - public BeatmapInfo SelectedBeatmap - { - get { return selectedBeatmap; } - set - { - selectedBeatmap = value; - } - } - public Action BeatmapSelected; + private BeatmapInfo selectedBeatmap; + + /// + /// Fires when one of our difficulties was selected. Will fire on first expand. + /// + public Action SelectionChanged; + public BeatmapSetInfo BeatmapSet; private BeatmapSetHeader header; private FlowContainer difficulties; - private bool collapsed; + private GroupState state; public GroupState State { - get { return collapsed ? GroupState.Collapsed : GroupState.Expanded; } + get { return state; } set { - bool val = value == GroupState.Collapsed; - if (collapsed == val) - return; - collapsed = val; - ClearTransformations(); - const float uncollapsedAlpha = 1; - FadeTo(collapsed ? collapsedAlpha : uncollapsedAlpha, 250); - if (collapsed) - difficulties.Hide(); - else - difficulties.Show(); - header.ClearTransformations(); - header.Width = collapsed ? collapsedWidth : 1; // TODO: Transform - header.BorderColour = new Color4( - header.BorderColour.R, - header.BorderColour.G, - header.BorderColour.B, - collapsed ? 0 : 255); - header.GlowRadius = collapsed ? 0 : 5; + state = value; + switch (state) + { + case GroupState.Expanded: + FadeTo(1, 250); + difficulties.Show(); + + //todo: header should probably have a state, with this logic moved inside it. + header.Width = 1; + header.GlowRadius = 5; + header.BorderColour = new Color4(header.BorderColour.R, header.BorderColour.G, header.BorderColour.B, 255); + + if (selectedBeatmap == null) + (difficulties.Children.FirstOrDefault() as BeatmapPanel).Selected = true; + SelectionChanged?.Invoke(this, selectedBeatmap); + break; + case GroupState.Collapsed: + FadeTo(collapsedAlpha, 250); + difficulties.Hide(); + + //todo: header should probably have a state, with this logic moved inside it. + header.Width = collapsedWidth; + header.GlowRadius = 0; + header.BorderColour = new Color4(header.BorderColour.R, header.BorderColour.G, header.BorderColour.B, 0); + break; + } } } public BeatmapGroup(BeatmapSetInfo beatmapSet) { BeatmapSet = beatmapSet; - selectedBeatmap = beatmapSet.Beatmaps[0]; - Alpha = collapsedAlpha; + Alpha = 0; AutoSizeAxes = Axes.Y; RelativeSizeAxes = Axes.X; - float difficultyWidth = 1; Children = new[] { new FlowContainer @@ -101,38 +101,40 @@ namespace osu.Game.Beatmaps.Drawable Spacing = new Vector2(0, 5), Direction = FlowDirection.VerticalOnly, Alpha = 0, - Children = BeatmapSet.Beatmaps.Select( - b => { - float width = difficultyWidth; - if (difficultyWidth > 0.8f) difficultyWidth -= 0.025f; - return new BeatmapPanel(BeatmapSet, b) - { - MapSelected = updateSelected, - Selected = width == 1, - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - RelativeSizeAxes = Axes.X, - Width = width, - }; - }) + Children = BeatmapSet.Beatmaps.Select(b => + new BeatmapPanel(BeatmapSet, b) + { + GainedSelection = panelGainedSelection, + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + RelativeSizeAxes = Axes.X, + } + ) } } } }; - - collapsed = true; } - - private void updateSelected(BeatmapInfo map) + + public override void Load(BaseGame game) + { + base.Load(game); + State = GroupState.Collapsed; + } + + private void panelGainedSelection(BeatmapInfo map) { + selectedBeatmap = map; + foreach (BeatmapPanel panel in difficulties.Children) - panel.Selected = panel.Beatmap == map; - BeatmapSelected?.Invoke(this, map); + if (panel.Beatmap != map) panel.Selected = false; + + SelectionChanged?.Invoke(this, map); } - + protected override bool OnClick(InputState state) { - BeatmapSelected?.Invoke(this, selectedBeatmap); + State = GroupState.Expanded; return true; } } diff --git a/osu.Game/Beatmaps/Drawable/BeatmapPanel.cs b/osu.Game/Beatmaps/Drawable/BeatmapPanel.cs index fc658f5fd7..2283a0ce69 100644 --- a/osu.Game/Beatmaps/Drawable/BeatmapPanel.cs +++ b/osu.Game/Beatmaps/Drawable/BeatmapPanel.cs @@ -19,7 +19,7 @@ namespace osu.Game.Beatmaps.Drawable { public BeatmapInfo Beatmap; - public Action MapSelected; + public Action GainedSelection; private bool selected; @@ -37,6 +37,8 @@ namespace osu.Game.Beatmaps.Drawable BorderColour.B, selected ? 255 : 0); GlowRadius = selected ? 3 : 0; + + if (selected) GainedSelection?.Invoke(Beatmap); } } @@ -101,7 +103,7 @@ namespace osu.Game.Beatmaps.Drawable protected override bool OnClick(InputState state) { - MapSelected?.Invoke(Beatmap); + Selected = true; return true; } } diff --git a/osu.Game/GameModes/Play/PlaySongSelect.cs b/osu.Game/GameModes/Play/PlaySongSelect.cs index 410d3b1e2a..ae7204d0d8 100644 --- a/osu.Game/GameModes/Play/PlaySongSelect.cs +++ b/osu.Game/GameModes/Play/PlaySongSelect.cs @@ -120,7 +120,7 @@ namespace osu.Game.GameModes.Play // Temporary: scrollContainer.Padding = new MarginPadding { Top = osuGame.Toolbar.Height }; } - + beatmaps = (game as OsuGameBase).Beatmaps; beatmaps.BeatmapSetAdded += bset => Scheduler.Add(() => addBeatmapSet(bset)); Task.Factory.StartNew(addBeatmapSets); @@ -136,21 +136,16 @@ namespace osu.Game.GameModes.Play private void PlayMode_ValueChanged(object sender, EventArgs e) { } - - private void selectBeatmapSet(BeatmapGroup group) + + private void selectBeatmap(BeatmapGroup group, BeatmapInfo beatmap) { if (selectedBeatmapGroup == group) return; - selectedBeatmapGroup.State = BeatmapGroup.GroupState.Collapsed; + + if (selectedBeatmapGroup != null) + selectedBeatmapGroup.State = BeatmapGroup.GroupState.Collapsed; + selectedBeatmapGroup = group; - selectedBeatmapGroup.State = BeatmapGroup.GroupState.Expanded; - } - - private void selectBeatmap(BeatmapGroup group, BeatmapInfo beatmap) - { - if (selectedBeatmap == beatmap) - return; - selectBeatmapSet(group); selectedBeatmap = beatmap; } @@ -158,16 +153,13 @@ namespace osu.Game.GameModes.Play { beatmapSet = beatmaps.GetWithChildren(beatmapSet.BeatmapSetID); beatmapSet.Beatmaps.ForEach(b => beatmaps.GetChildren(b)); - beatmapSet.Beatmaps = beatmapSet.Beatmaps.OrderBy(b => b.BaseDifficulty.OverallDifficulty) - .ToList(); + beatmapSet.Beatmaps = beatmapSet.Beatmaps.OrderBy(b => b.BaseDifficulty.OverallDifficulty).ToList(); Schedule(() => { - var group = new BeatmapGroup(beatmapSet) { BeatmapSelected = selectBeatmap }; + var group = new BeatmapGroup(beatmapSet) { SelectionChanged = selectBeatmap }; setList.Add(group); if (setList.Children.Count() == 1) { - selectedBeatmapGroup = group; - selectedBeatmap = group.SelectedBeatmap; group.State = BeatmapGroup.GroupState.Expanded; } }); From ce73ae792fada7a425ca6e4c9f9e33ed681e8ba7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Oct 2016 13:36:04 +0900 Subject: [PATCH 56/58] Change panel selection logic to avoid looping. --- osu.Game/Beatmaps/Drawable/BeatmapGroup.cs | 16 +++++++--------- osu.Game/Beatmaps/Drawable/BeatmapPanel.cs | 4 ++-- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/osu.Game/Beatmaps/Drawable/BeatmapGroup.cs b/osu.Game/Beatmaps/Drawable/BeatmapGroup.cs index 9baa393854..6c3c15b576 100644 --- a/osu.Game/Beatmaps/Drawable/BeatmapGroup.cs +++ b/osu.Game/Beatmaps/Drawable/BeatmapGroup.cs @@ -25,7 +25,7 @@ namespace osu.Game.Beatmaps.Drawable private const float collapsedAlpha = 0.5f; private const float collapsedWidth = 0.8f; - private BeatmapInfo selectedBeatmap; + private BeatmapPanel selectedPanel; /// /// Fires when one of our difficulties was selected. Will fire on first expand. @@ -53,9 +53,9 @@ namespace osu.Game.Beatmaps.Drawable header.GlowRadius = 5; header.BorderColour = new Color4(header.BorderColour.R, header.BorderColour.G, header.BorderColour.B, 255); - if (selectedBeatmap == null) + if (selectedPanel == null) (difficulties.Children.FirstOrDefault() as BeatmapPanel).Selected = true; - SelectionChanged?.Invoke(this, selectedBeatmap); + SelectionChanged?.Invoke(this, selectedPanel?.Beatmap); break; case GroupState.Collapsed: FadeTo(collapsedAlpha, 250); @@ -122,14 +122,12 @@ namespace osu.Game.Beatmaps.Drawable State = GroupState.Collapsed; } - private void panelGainedSelection(BeatmapInfo map) + private void panelGainedSelection(BeatmapPanel panel) { - selectedBeatmap = map; - - foreach (BeatmapPanel panel in difficulties.Children) - if (panel.Beatmap != map) panel.Selected = false; + if (selectedPanel != null) selectedPanel.Selected = false; + selectedPanel = panel; - SelectionChanged?.Invoke(this, map); + SelectionChanged?.Invoke(this, panel.Beatmap); } protected override bool OnClick(InputState state) diff --git a/osu.Game/Beatmaps/Drawable/BeatmapPanel.cs b/osu.Game/Beatmaps/Drawable/BeatmapPanel.cs index 2283a0ce69..2d61a282f4 100644 --- a/osu.Game/Beatmaps/Drawable/BeatmapPanel.cs +++ b/osu.Game/Beatmaps/Drawable/BeatmapPanel.cs @@ -19,7 +19,7 @@ namespace osu.Game.Beatmaps.Drawable { public BeatmapInfo Beatmap; - public Action GainedSelection; + public Action GainedSelection; private bool selected; @@ -38,7 +38,7 @@ namespace osu.Game.Beatmaps.Drawable selected ? 255 : 0); GlowRadius = selected ? 3 : 0; - if (selected) GainedSelection?.Invoke(Beatmap); + if (selected) GainedSelection?.Invoke(this); } } From abfad501b605ba2411c356ef27869e6ba2e83913 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Oct 2016 13:41:30 +0900 Subject: [PATCH 57/58] beatmapSet can be private. --- osu.Game/Beatmaps/Drawable/BeatmapGroup.cs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/osu.Game/Beatmaps/Drawable/BeatmapGroup.cs b/osu.Game/Beatmaps/Drawable/BeatmapGroup.cs index 6c3c15b576..c262ff0fd8 100644 --- a/osu.Game/Beatmaps/Drawable/BeatmapGroup.cs +++ b/osu.Game/Beatmaps/Drawable/BeatmapGroup.cs @@ -27,15 +27,17 @@ namespace osu.Game.Beatmaps.Drawable private BeatmapPanel selectedPanel; - /// - /// Fires when one of our difficulties was selected. Will fire on first expand. - /// + /// + /// Fires when one of our difficulties was selected. Will fire on first expand. + /// public Action SelectionChanged; - public BeatmapSetInfo BeatmapSet; + private BeatmapSetInfo beatmapSet; private BeatmapSetHeader header; private FlowContainer difficulties; - private GroupState state; + + private GroupState state; + public GroupState State { get { return state; } @@ -72,7 +74,7 @@ namespace osu.Game.Beatmaps.Drawable public BeatmapGroup(BeatmapSetInfo beatmapSet) { - BeatmapSet = beatmapSet; + this.beatmapSet = beatmapSet; Alpha = 0; AutoSizeAxes = Axes.Y; RelativeSizeAxes = Axes.X; @@ -101,8 +103,8 @@ namespace osu.Game.Beatmaps.Drawable Spacing = new Vector2(0, 5), Direction = FlowDirection.VerticalOnly, Alpha = 0, - Children = BeatmapSet.Beatmaps.Select(b => - new BeatmapPanel(BeatmapSet, b) + Children = this.beatmapSet.Beatmaps.Select(b => + new BeatmapPanel(this.beatmapSet, b) { GainedSelection = panelGainedSelection, Anchor = Anchor.TopRight, From 456169f182151bf6892f9d0491b2e8bcefe506f6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 27 Oct 2016 13:42:37 +0900 Subject: [PATCH 58/58] Move BeatmapGroupState to outside class definition. --- osu.Game/Beatmaps/Drawable/BeatmapGroup.cs | 26 +++++++++++----------- osu.Game/GameModes/Play/PlaySongSelect.cs | 4 ++-- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/osu.Game/Beatmaps/Drawable/BeatmapGroup.cs b/osu.Game/Beatmaps/Drawable/BeatmapGroup.cs index c262ff0fd8..189fb4f3d2 100644 --- a/osu.Game/Beatmaps/Drawable/BeatmapGroup.cs +++ b/osu.Game/Beatmaps/Drawable/BeatmapGroup.cs @@ -14,14 +14,8 @@ using OpenTK.Graphics; namespace osu.Game.Beatmaps.Drawable { - class BeatmapGroup : Container, IStateful + class BeatmapGroup : Container, IStateful { - public enum GroupState - { - Collapsed, - Expanded, - } - private const float collapsedAlpha = 0.5f; private const float collapsedWidth = 0.8f; @@ -36,9 +30,9 @@ namespace osu.Game.Beatmaps.Drawable private BeatmapSetHeader header; private FlowContainer difficulties; - private GroupState state; + private BeatmapGroupState state; - public GroupState State + public BeatmapGroupState State { get { return state; } set @@ -46,7 +40,7 @@ namespace osu.Game.Beatmaps.Drawable state = value; switch (state) { - case GroupState.Expanded: + case BeatmapGroupState.Expanded: FadeTo(1, 250); difficulties.Show(); @@ -59,7 +53,7 @@ namespace osu.Game.Beatmaps.Drawable (difficulties.Children.FirstOrDefault() as BeatmapPanel).Selected = true; SelectionChanged?.Invoke(this, selectedPanel?.Beatmap); break; - case GroupState.Collapsed: + case BeatmapGroupState.Collapsed: FadeTo(collapsedAlpha, 250); difficulties.Hide(); @@ -121,7 +115,7 @@ namespace osu.Game.Beatmaps.Drawable public override void Load(BaseGame game) { base.Load(game); - State = GroupState.Collapsed; + State = BeatmapGroupState.Collapsed; } private void panelGainedSelection(BeatmapPanel panel) @@ -134,8 +128,14 @@ namespace osu.Game.Beatmaps.Drawable protected override bool OnClick(InputState state) { - State = GroupState.Expanded; + State = BeatmapGroupState.Expanded; return true; } + } + + public enum BeatmapGroupState + { + Collapsed, + Expanded, } } diff --git a/osu.Game/GameModes/Play/PlaySongSelect.cs b/osu.Game/GameModes/Play/PlaySongSelect.cs index ae7204d0d8..ec0b6b5478 100644 --- a/osu.Game/GameModes/Play/PlaySongSelect.cs +++ b/osu.Game/GameModes/Play/PlaySongSelect.cs @@ -143,7 +143,7 @@ namespace osu.Game.GameModes.Play return; if (selectedBeatmapGroup != null) - selectedBeatmapGroup.State = BeatmapGroup.GroupState.Collapsed; + selectedBeatmapGroup.State = BeatmapGroupState.Collapsed; selectedBeatmapGroup = group; selectedBeatmap = beatmap; @@ -160,7 +160,7 @@ namespace osu.Game.GameModes.Play setList.Add(group); if (setList.Children.Count() == 1) { - group.State = BeatmapGroup.GroupState.Expanded; + group.State = BeatmapGroupState.Expanded; } }); }