diff --git a/osu-framework b/osu-framework index f839a542ee..1d43e1ed56 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit f839a542eed0508c2e7eeb9ba86b5c7ba0620652 +Subproject commit 1d43e1ed56421fbbefdf6c23dab8deeeaa0f592a diff --git a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs index 7acbdbf3d9..37d89b6497 100644 --- a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs +++ b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs @@ -35,29 +35,31 @@ namespace osu.Game.Tests.Beatmaps.IO 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.Dependencies.Get().Import(osz_path); - ensureLoaded(osu); + using (HeadlessGameHost host = new HeadlessGameHost()) + { + var osu = loadOsu(host); + osu.Dependencies.Get().Import(osz_path); + ensureLoaded(osu); + } } [Test] public void TestImportOverIPC() { - HeadlessGameHost host = new HeadlessGameHost("host", true); - HeadlessGameHost client = new HeadlessGameHost("client", true); + using (HeadlessGameHost host = new HeadlessGameHost("host", true)) + using (HeadlessGameHost client = new HeadlessGameHost("client", true)) + { + Assert.IsTrue(host.IsPrimaryInstance); + Assert.IsTrue(!client.IsPrimaryInstance); - Assert.IsTrue(host.IsPrimaryInstance); - Assert.IsTrue(!client.IsPrimaryInstance); + var osu = loadOsu(host); - var osu = loadOsu(host); + var importer = new BeatmapImporter(client); + if (!importer.Import(osz_path).Wait(1000)) + Assert.Fail(@"IPC took too long to send"); - var importer = new BeatmapImporter(client); - if (!importer.Import(osz_path).Wait(1000)) - Assert.Fail(@"IPC took too long to send"); - - ensureLoaded(osu, 10000); + ensureLoaded(osu, 10000); + } } private OsuGameBase loadOsu(BasicGameHost host) diff --git a/osu.Game/Beatmaps/Drawable/BeatmapGroup.cs b/osu.Game/Beatmaps/Drawable/BeatmapGroup.cs index 2dc4218d39..ec9e36af3b 100644 --- a/osu.Game/Beatmaps/Drawable/BeatmapGroup.cs +++ b/osu.Game/Beatmaps/Drawable/BeatmapGroup.cs @@ -26,12 +26,12 @@ namespace osu.Game.Beatmaps.Drawable /// public Action SelectionChanged; - private BeatmapSetInfo beatmapSet; public BeatmapSetHeader Header; private BeatmapGroupState state; public List BeatmapPanels; + private WorkingBeatmap beatmap; public BeatmapGroupState State { @@ -65,11 +65,11 @@ namespace osu.Game.Beatmaps.Drawable } } - public BeatmapGroup(BeatmapSetInfo beatmapSet, WorkingBeatmap working) + public BeatmapGroup(WorkingBeatmap beatmap) { - this.beatmapSet = beatmapSet; + this.beatmap = beatmap; - Header = new BeatmapSetHeader(beatmapSet, working) + Header = new BeatmapSetHeader(beatmap) { GainedSelection = headerGainedSelection, RelativeSizeAxes = Axes.X, @@ -77,7 +77,7 @@ namespace osu.Game.Beatmaps.Drawable Origin = Anchor.TopRight, }; - BeatmapPanels = beatmapSet.Beatmaps.Select(b => new BeatmapPanel(b) + BeatmapPanels = beatmap.BeatmapSetInfo.Beatmaps.Select(b => new BeatmapPanel(b) { GainedSelection = panelGainedSelection, Anchor = Anchor.TopRight, diff --git a/osu.Game/Beatmaps/Drawable/BeatmapSetHeader.cs b/osu.Game/Beatmaps/Drawable/BeatmapSetHeader.cs index e42a6271c6..4d46a02388 100644 --- a/osu.Game/Beatmaps/Drawable/BeatmapSetHeader.cs +++ b/osu.Game/Beatmaps/Drawable/BeatmapSetHeader.cs @@ -14,107 +14,27 @@ using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Game.Configuration; using osu.Framework.Graphics.Colour; +using osu.Framework; namespace osu.Game.Beatmaps.Drawable { class BeatmapSetHeader : Panel { public Action GainedSelection; - private BeatmapSetInfo beatmapSet; private SpriteText title, artist; private OsuConfigManager config; - private Bindable preferUnicode; - - protected override void Selected() - { - base.Selected(); - - GainedSelection?.Invoke(this); - } + private Bindable preferUnicode; + private WorkingBeatmap beatmap; - protected override void Deselected() - { - base.Deselected(); - } - - [BackgroundDependencyLoader] - private void load(OsuConfigManager config) - { - this.config = config; - - preferUnicode = config.GetBindable(OsuConfig.ShowUnicode); - preferUnicode.ValueChanged += preferUnicode_changed; - preferUnicode_changed(preferUnicode, null); - } - private void preferUnicode_changed(object sender, EventArgs e) + public BeatmapSetHeader(WorkingBeatmap beatmap) { - title.Text = config.GetUnicodeString(beatmapSet.Metadata.Title, beatmapSet.Metadata.TitleUnicode); - artist.Text = config.GetUnicodeString(beatmapSet.Metadata.Artist, beatmapSet.Metadata.ArtistUnicode); - } - - protected override void Dispose(bool isDisposing) - { - if (preferUnicode != null) - preferUnicode.ValueChanged -= preferUnicode_changed; - base.Dispose(isDisposing); - } + this.beatmap = beatmap; - public BeatmapSetHeader(BeatmapSetInfo beatmapSet, WorkingBeatmap working) - { - this.beatmapSet = beatmapSet; Children = new Framework.Graphics.Drawable[] { - new BufferedContainer + new PanelBackground(beatmap) { - CacheDrawnFrameBuffer = true, RelativeSizeAxes = Axes.Both, - Children = new Framework.Graphics.Drawable[] - { - working.Background == null ? new Box{ RelativeSizeAxes = Axes.Both, Colour = new Color4(200, 200, 200, 255) } : new Sprite - { - Texture = working.Background, - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Scale = new Vector2(1366 / working.Background.Width * 0.6f), - }, - new FlowContainer - { - Direction = FlowDirection.HorizontalOnly, - RelativeSizeAxes = Axes.Both, - // This makes the gradient not be perfectly horizontal, but diagonal at a ~40° angle - Shear = new Vector2(0.8f, 0), - Alpha = 0.5f, - Children = new[] - { - // The left half with no gradient applied - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black, - Width = 0.4f, - }, - // Piecewise-linear gradient with 3 segments to make it appear smoother - new Box - { - RelativeSizeAxes = Axes.Both, - ColourInfo = ColourInfo.GradientHorizontal(Color4.Black, new Color4(0f, 0f, 0f, 0.9f)), - Width = 0.05f, - }, - new Box - { - RelativeSizeAxes = Axes.Both, - ColourInfo = ColourInfo.GradientHorizontal(new Color4(0f, 0f, 0f, 0.9f), new Color4(0f, 0f, 0f, 0.1f)), - Width = 0.2f, - }, - new Box - { - RelativeSizeAxes = Axes.Both, - ColourInfo = ColourInfo.GradientHorizontal(new Color4(0f, 0f, 0f, 0.1f), new Color4(0, 0, 0, 0)), - Width = 0.05f, - }, - } - }, - } }, new FlowContainer { @@ -126,7 +46,7 @@ namespace osu.Game.Beatmaps.Drawable title = new SpriteText { Font = @"Exo2.0-BoldItalic", - Text = beatmapSet.Metadata.Title, + Text = beatmap.BeatmapSetInfo.Metadata.Title, TextSize = 22, Shadow = true, }, @@ -134,7 +54,7 @@ namespace osu.Game.Beatmaps.Drawable { Margin = new MarginPadding { Top = -1 }, Font = @"Exo2.0-SemiBoldItalic", - Text = beatmapSet.Metadata.Artist, + Text = beatmap.BeatmapSetInfo.Metadata.Artist, TextSize = 17, Shadow = true, }, @@ -151,6 +71,125 @@ namespace osu.Game.Beatmaps.Drawable } } }; + } + + protected override void Selected() + { + base.Selected(); + GainedSelection?.Invoke(this); + } + + [BackgroundDependencyLoader] + private void load(OsuConfigManager config) + { + this.config = config; + + preferUnicode = config.GetBindable(OsuConfig.ShowUnicode); + preferUnicode.ValueChanged += preferUnicode_changed; + preferUnicode_changed(preferUnicode, null); + } + private void preferUnicode_changed(object sender, EventArgs e) + { + title.Text = config.GetUnicodeString(beatmap.BeatmapSetInfo.Metadata.Title, beatmap.BeatmapSetInfo.Metadata.TitleUnicode); + artist.Text = config.GetUnicodeString(beatmap.BeatmapSetInfo.Metadata.Artist, beatmap.BeatmapSetInfo.Metadata.ArtistUnicode); + } + + protected override void Dispose(bool isDisposing) + { + if (preferUnicode != null) + preferUnicode.ValueChanged -= preferUnicode_changed; + base.Dispose(isDisposing); + } + + class PanelBackground : BufferedContainer + { + private readonly WorkingBeatmap working; + + public PanelBackground(WorkingBeatmap working) + { + this.working = working; + + CacheDrawnFrameBuffer = true; + + Children = new[] + { + new FlowContainer + { + Depth = 1, + Direction = FlowDirection.HorizontalOnly, + RelativeSizeAxes = Axes.Both, + // This makes the gradient not be perfectly horizontal, but diagonal at a ~40° angle + Shear = new Vector2(0.8f, 0), + Alpha = 0.5f, + Children = new[] + { + // The left half with no gradient applied + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black, + Width = 0.4f, + }, + // Piecewise-linear gradient with 3 segments to make it appear smoother + new Box + { + RelativeSizeAxes = Axes.Both, + ColourInfo = ColourInfo.GradientHorizontal(Color4.Black, new Color4(0f, 0f, 0f, 0.9f)), + Width = 0.05f, + }, + new Box + { + RelativeSizeAxes = Axes.Both, + ColourInfo = ColourInfo.GradientHorizontal(new Color4(0f, 0f, 0f, 0.9f), new Color4(0f, 0f, 0f, 0.1f)), + Width = 0.2f, + }, + new Box + { + RelativeSizeAxes = Axes.Both, + ColourInfo = ColourInfo.GradientHorizontal(new Color4(0f, 0f, 0f, 0.1f), new Color4(0, 0, 0, 0)), + Width = 0.05f, + }, + } + }, + }; + } + + [BackgroundDependencyLoader] + private void load(OsuGameBase game) + { + //todo: masking check + new BeatmapBackground(working) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }.Preload(game, (bg) => + { + Add(bg); + ForceRedraw(); + }); + } + + class BeatmapBackground : Sprite + { + private readonly WorkingBeatmap working; + + public BeatmapBackground(WorkingBeatmap working) + { + this.working = working; + } + + [BackgroundDependencyLoader] + private void load(OsuGameBase game) + { + Texture = working.Background; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + Scale = new Vector2(1366 / (Texture?.Width ?? 1) * 0.6f); + } + } } } } \ No newline at end of file diff --git a/osu.Game/Beatmaps/IO/ArchiveReader.cs b/osu.Game/Beatmaps/IO/ArchiveReader.cs index bde6bb8b35..a052b9eb0d 100644 --- a/osu.Game/Beatmaps/IO/ArchiveReader.cs +++ b/osu.Game/Beatmaps/IO/ArchiveReader.cs @@ -14,7 +14,7 @@ namespace osu.Game.Beatmaps.IO public Func Test { get; set; } public Type Type { get; set; } } - + private static List readers { get; } = new List(); public static ArchiveReader GetReader(BasicStorage storage, string path) diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index f2f4a39d91..4c9848363b 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -18,7 +18,7 @@ namespace osu.Game.Beatmaps public readonly BeatmapSetInfo BeatmapSetInfo; private readonly BeatmapDatabase database; - private ArchiveReader reader => database?.GetReader(BeatmapSetInfo); + private ArchiveReader GetReader() => database?.GetReader(BeatmapSetInfo); private Texture background; private object backgroundLock = new object(); @@ -32,7 +32,8 @@ namespace osu.Game.Beatmaps try { - background = new TextureStore(new RawTextureLoaderStore(reader)).Get(BeatmapInfo.Metadata.BackgroundFile); + using (var reader = GetReader()) + background = new TextureStore(new RawTextureLoaderStore(reader), false).Get(BeatmapInfo.Metadata.BackgroundFile); } catch { } @@ -54,6 +55,7 @@ namespace osu.Game.Beatmaps try { + using (var reader = GetReader()) using (var stream = new StreamReader(reader.GetStream(BeatmapInfo.Path))) beatmap = BeatmapDecoder.GetDecoder(stream)?.Decode(stream); } @@ -77,9 +79,12 @@ namespace osu.Game.Beatmaps try { - var trackData = reader?.GetStream(BeatmapInfo.Metadata.AudioFile); - if (trackData != null) - track = new AudioTrackBass(trackData); + using (var reader = GetReader()) + { + var trackData = reader?.GetStream(BeatmapInfo.Metadata.AudioFile); + if (trackData != null) + track = new AudioTrackBass(trackData); + } } catch { } @@ -89,6 +94,8 @@ namespace osu.Game.Beatmaps set { lock (trackLock) track = value; } } + public bool TrackLoaded => track != null; + public WorkingBeatmap(Beatmap beatmap) { this.beatmap = beatmap; @@ -108,7 +115,7 @@ namespace osu.Game.Beatmaps if (!isDisposed) { track?.Dispose(); - reader?.Dispose(); + background?.Dispose(); isDisposed = true; } } @@ -116,6 +123,7 @@ namespace osu.Game.Beatmaps public void Dispose() { Dispose(true); + GC.SuppressFinalize(this); } public void TransferTo(WorkingBeatmap working) diff --git a/osu.Game/Database/BeatmapDatabase.cs b/osu.Game/Database/BeatmapDatabase.cs index aa68a3be15..619eacc90f 100644 --- a/osu.Game/Database/BeatmapDatabase.cs +++ b/osu.Game/Database/BeatmapDatabase.cs @@ -136,7 +136,7 @@ namespace osu.Game.Database public BeatmapSetInfo GetBeatmapSet(int id) { - return Query().Where(s => s.BeatmapSetID == id).FirstOrDefault(); + return Query().FirstOrDefault(s => s.BeatmapSetID == id); } public WorkingBeatmap GetWorkingBeatmap(BeatmapInfo beatmapInfo, WorkingBeatmap previous = null) @@ -144,7 +144,7 @@ namespace osu.Game.Database var beatmapSetInfo = Query().FirstOrDefault(s => s.BeatmapSetID == beatmapInfo.BeatmapSetID); //we need metadata - GetChildren(beatmapSetInfo); + GetChildren(beatmapSetInfo, false); if (beatmapSetInfo == null) throw new InvalidOperationException($@"Beatmap set {beatmapInfo.BeatmapSetID} is not in the local database."); @@ -175,10 +175,10 @@ namespace osu.Game.Database return connection.GetWithChildren(id); } - public List GetAllWithChildren(Expression> filter = null, - bool recursive = true) where T : class + 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) @@ -199,7 +199,7 @@ namespace osu.Game.Database public void Update(T record, bool cascade = true) where T : class { - if (!validTypes.Any(t => t == typeof(T))) + if (validTypes.All(t => t != typeof(T))) throw new ArgumentException(nameof(T), "Must be a type managed by BeatmapDatabase"); if (cascade) connection.UpdateWithChildren(record); diff --git a/osu.Game/Graphics/UserInterface/Volume/VolumeMeter.cs b/osu.Game/Graphics/UserInterface/Volume/VolumeMeter.cs index bcd1d9f8db..4cba437883 100644 --- a/osu.Game/Graphics/UserInterface/Volume/VolumeMeter.cs +++ b/osu.Game/Graphics/UserInterface/Volume/VolumeMeter.cs @@ -75,7 +75,7 @@ namespace osu.Game.Graphics.UserInterface.Volume protected override bool OnWheel(InputState state) { - Volume += 0.05f * state.Mouse.WheelDiff; + Volume += 0.05f * state.Mouse.WheelDelta; return true; } diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index f84d2052c3..1a3245e41c 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -34,7 +34,6 @@ namespace osu.Game.Overlays private DragBar progress; private TextAwesome playButton, listButton; private SpriteText title, artist; - private Texture fallbackTexture; private List playList; private List playHistory = new List(); @@ -47,6 +46,7 @@ namespace osu.Game.Overlays private OsuConfigManager config; private WorkingBeatmap current; private BeatmapDatabase beatmaps; + private BaseGame game; public MusicController() { @@ -208,7 +208,7 @@ namespace osu.Game.Overlays beatmapSource = osuGame.Beatmap ?? new Bindable(); playList = beatmaps.GetAllWithChildren(); - backgroundSprite = new MusicControllerBackground(fallbackTexture = textures.Get(@"Backgrounds/bg4")); + backgroundSprite = new MusicControllerBackground(); AddInternal(backgroundSprite); } @@ -222,12 +222,15 @@ namespace osu.Game.Overlays protected override void Update() { base.Update(); - if (current?.Track == null) return; - progress.UpdatePosition((float)(current.Track.CurrentTime / current.Track.Length)); - playButton.Icon = current.Track.IsRunning ? FontAwesome.fa_pause_circle_o : FontAwesome.fa_play_circle_o; + if (current?.TrackLoaded ?? false) + { - if (current.Track.HasCompleted && !current.Track.Looping) next(); + progress.UpdatePosition((float)(current.Track.CurrentTime / current.Track.Length)); + playButton.Icon = current.Track.IsRunning ? FontAwesome.fa_pause_circle_o : FontAwesome.fa_play_circle_o; + + if (current.Track.HasCompleted && !current.Track.Looping) next(); + } } void preferUnicode_changed(object sender, EventArgs e) @@ -304,36 +307,49 @@ namespace osu.Game.Overlays updateDisplay(current, isNext ? TransformDirection.Next : TransformDirection.Prev); } + protected override void PerformLoad(BaseGame game) + { + this.game = game; + base.PerformLoad(game); + } + private void updateDisplay(WorkingBeatmap beatmap, TransformDirection direction) { - if (beatmap.Beatmap == null) - //todo: we may need to display some default text here (currently in the constructor). - return; - - BeatmapMetadata metadata = beatmap.Beatmap.BeatmapInfo.Metadata; - title.Text = config.GetUnicodeString(metadata.Title, metadata.TitleUnicode); - artist.Text = config.GetUnicodeString(metadata.Artist, metadata.ArtistUnicode); - - MusicControllerBackground newBackground = new MusicControllerBackground(beatmap.Background ?? fallbackTexture); - - Add(newBackground); - - switch (direction) + Task.Run(() => { - case TransformDirection.Next: - newBackground.Position = new Vector2(400, 0); - newBackground.MoveToX(0, 500, EasingTypes.OutCubic); - backgroundSprite.MoveToX(-400, 500, EasingTypes.OutCubic); - break; - case TransformDirection.Prev: - newBackground.Position = new Vector2(-400, 0); - newBackground.MoveToX(0, 500, EasingTypes.OutCubic); - backgroundSprite.MoveToX(400, 500, EasingTypes.OutCubic); - break; - } + if (beatmap.Beatmap == null) + //todo: we may need to display some default text here (currently in the constructor). + return; - backgroundSprite.Expire(); - backgroundSprite = newBackground; + BeatmapMetadata metadata = beatmap.Beatmap.BeatmapInfo.Metadata; + title.Text = config.GetUnicodeString(metadata.Title, metadata.TitleUnicode); + artist.Text = config.GetUnicodeString(metadata.Artist, metadata.ArtistUnicode); + }); + + MusicControllerBackground newBackground; + + (newBackground = new MusicControllerBackground(beatmap)).Preload(game, delegate + { + + Add(newBackground); + + switch (direction) + { + case TransformDirection.Next: + newBackground.Position = new Vector2(400, 0); + newBackground.MoveToX(0, 500, EasingTypes.OutCubic); + backgroundSprite.MoveToX(-400, 500, EasingTypes.OutCubic); + break; + case TransformDirection.Prev: + newBackground.Position = new Vector2(-400, 0); + newBackground.MoveToX(0, 500, EasingTypes.OutCubic); + backgroundSprite.MoveToX(400, 500, EasingTypes.OutCubic); + break; + } + + backgroundSprite.Expire(); + backgroundSprite = newBackground; + }); } private void seek(float position) @@ -363,9 +379,11 @@ namespace osu.Game.Overlays private class MusicControllerBackground : BufferedContainer { private Sprite sprite; + private WorkingBeatmap beatmap; - public MusicControllerBackground(Texture backgroundTexture) + public MusicControllerBackground(WorkingBeatmap beatmap = null) { + this.beatmap = beatmap; CacheDrawnFrameBuffer = true; RelativeSizeAxes = Axes.Both; Depth = float.MinValue; @@ -374,7 +392,6 @@ namespace osu.Game.Overlays { sprite = new Sprite { - Texture = backgroundTexture, Colour = new Color4(150, 150, 150, 255) }, new Box @@ -388,6 +405,12 @@ namespace osu.Game.Overlays }; } + [BackgroundDependencyLoader] + private void load(TextureStore textures) + { + sprite.Texture = beatmap?.Background ?? textures.Get(@"Backgrounds/bg4"); + } + protected override void LoadComplete() { base.LoadComplete(); diff --git a/osu.Game/Screens/Backgrounds/BackgroundModeBeatmap.cs b/osu.Game/Screens/Backgrounds/BackgroundModeBeatmap.cs index 649952ccfb..e599198009 100644 --- a/osu.Game/Screens/Backgrounds/BackgroundModeBeatmap.cs +++ b/osu.Game/Screens/Backgrounds/BackgroundModeBeatmap.cs @@ -1,9 +1,8 @@ //Copyright (c) 2007-2016 ppy Pty Ltd . //Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Framework.Allocation; using OpenTK; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Transformations; using osu.Game.Beatmaps; using osu.Game.Graphics.Background; @@ -15,6 +14,7 @@ namespace osu.Game.Screens.Backgrounds private Background background; private WorkingBeatmap beatmap; + private Vector2 blurTarget; public WorkingBeatmap Beatmap { @@ -30,20 +30,26 @@ namespace osu.Game.Screens.Backgrounds beatmap = value; - Background oldBackground = background; - - addBackground(background = new Background()); - background.Sprite.Texture = beatmap.Background; - - if (oldBackground != null) + Schedule(() => { - oldBackground.Depth = 1; - oldBackground.Flush(); - oldBackground.FadeOut(250); - oldBackground.Expire(); + Background newBackground = new BeatmapBackground(beatmap); - background.BlurSigma = oldBackground.BlurSigma; - } + newBackground.Preload(Game, delegate + { + Background oldBackground = background; + + Add(background = newBackground); + background.BlurSigma = blurTarget; + + if (oldBackground != null) + { + oldBackground.Depth = 1; + oldBackground.Flush(); + oldBackground.FadeOut(250); + oldBackground.Expire(); + } + }); + }); } } @@ -52,20 +58,33 @@ namespace osu.Game.Screens.Backgrounds Beatmap = beatmap; } - private void addBackground(Background background) - { - background.CacheDrawnFrameBuffer = true; - Add(background); - } - public void BlurTo(Vector2 sigma, double duration) { background?.BlurTo(sigma, duration, EasingTypes.OutExpo); + blurTarget = sigma; } public override bool Equals(BackgroundMode other) { return base.Equals(other) && beatmap == ((BackgroundModeBeatmap)other).Beatmap; } + + class BeatmapBackground : Background + { + private WorkingBeatmap beatmap; + + public BeatmapBackground(WorkingBeatmap beatmap) + { + this.beatmap = beatmap; + CacheDrawnFrameBuffer = true; + } + + [BackgroundDependencyLoader] + private void load() + { + Sprite.Texture = beatmap.Background; + } + + } } } diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 90abf55421..14df8d37b4 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -125,9 +125,9 @@ namespace osu.Game.Screens.Play { } - protected override void UpdateMouseState(InputState state) + protected override void TransformState(InputState state) { - base.UpdateMouseState(state); + base.TransformState(state); MouseState mouse = (MouseState)state.Mouse; diff --git a/osu.Game/Screens/Select/PlaySongSelect.cs b/osu.Game/Screens/Select/PlaySongSelect.cs index dae703232a..9df2b339a7 100644 --- a/osu.Game/Screens/Select/PlaySongSelect.cs +++ b/osu.Game/Screens/Select/PlaySongSelect.cs @@ -3,6 +3,7 @@ using System; using System.Linq; +using System.Threading; using System.Threading.Tasks; using osu.Framework.Allocation; using osu.Framework.Audio; @@ -44,6 +45,7 @@ namespace osu.Game.Screens.Select private Container wedgedBeatmapInfo; private static readonly Vector2 BACKGROUND_BLUR = new Vector2(20); + private CancellationTokenSource initialAddSetsTask; /// Optionally provide a database to use instead of the OsuGame one. public PlaySongSelect(BeatmapDatabase database = null) @@ -153,11 +155,18 @@ namespace osu.Game.Screens.Select if (database == null) database = beatmaps; - database.BeatmapSetAdded += s => Schedule(() => addBeatmapSet(s, game)); + database.BeatmapSetAdded += onDatabaseOnBeatmapSetAdded; trackManager = audio.Track; - Task.Factory.StartNew(() => addBeatmapSets(game)); + initialAddSetsTask = new CancellationTokenSource(); + + Task.Factory.StartNew(() => addBeatmapSets(game, initialAddSetsTask.Token), initialAddSetsTask.Token); + } + + private void onDatabaseOnBeatmapSetAdded(BeatmapSetInfo s) + { + Schedule(() => addBeatmapSet(s, Game)); } protected override void OnEntering(GameMode last) @@ -196,6 +205,10 @@ namespace osu.Game.Screens.Select base.Dispose(isDisposing); if (playMode != null) playMode.ValueChanged -= playMode_ValueChanged; + + database.BeatmapSetAdded -= onDatabaseOnBeatmapSetAdded; + + initialAddSetsTask.Cancel(); } private void playMode_ValueChanged(object sender, EventArgs e) @@ -215,6 +228,7 @@ namespace osu.Game.Screens.Select (Background as BackgroundModeBeatmap)?.BlurTo(BACKGROUND_BLUR, 1000); } + //todo: move to own class and fix async logic (move every call on WorkingBeatmap.* to load() and use Preload to create it. refreshWedgedBeatmapInfo(beatmap); } @@ -329,6 +343,7 @@ namespace osu.Game.Screens.Select { base.OnBeatmapChanged(beatmap); + //todo: change background in selectionChanged instead; support per-difficulty backgrounds. changeBackground(beatmap); selectBeatmap(beatmap.BeatmapInfo); @@ -372,9 +387,9 @@ namespace osu.Game.Screens.Select beatmapSet.Beatmaps.ForEach(b => database.GetChildren(b)); beatmapSet.Beatmaps = beatmapSet.Beatmaps.OrderBy(b => b.BaseDifficulty.OverallDifficulty).ToList(); - var working = database.GetWorkingBeatmap(beatmapSet.Beatmaps.FirstOrDefault()); + var beatmap = database.GetWorkingBeatmap(beatmapSet.Beatmaps.FirstOrDefault()); - var group = new BeatmapGroup(beatmapSet, working) { SelectionChanged = selectionChanged }; + var group = new BeatmapGroup(beatmap) { SelectionChanged = selectionChanged }; //for the time being, let's completely load the difficulty panels in the background. //this likely won't scale so well, but allows us to completely async the loading flow. @@ -393,10 +408,13 @@ namespace osu.Game.Screens.Select })); } - private void addBeatmapSets(BaseGame game) + private void addBeatmapSets(BaseGame game, CancellationToken token) { foreach (var beatmapSet in database.Query()) + { + if (token.IsCancellationRequested) return; addBeatmapSet(beatmapSet, game); + } } } }