From 10ef34b8053e50fdbe156d56e8a3ccd7813f7dd7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 28 Oct 2016 20:24:14 +0900 Subject: [PATCH] Lazy parse beatmap; Don't reload audio track if it hasn't changed. --- .../Tests/TestCasePlayer.cs | 10 +++-- osu.Game/Beatmaps/WorkingBeatmap.cs | 37 +++++++++++++++++-- osu.Game/Database/BeatmapDatabase.cs | 22 ++++++++--- osu.Game/GameModes/Play/PlaySongSelect.cs | 3 +- 4 files changed, 56 insertions(+), 16 deletions(-) diff --git a/osu.Desktop.VisualTests/Tests/TestCasePlayer.cs b/osu.Desktop.VisualTests/Tests/TestCasePlayer.cs index 90d45fe7eb..a3ae103f28 100644 --- a/osu.Desktop.VisualTests/Tests/TestCasePlayer.cs +++ b/osu.Desktop.VisualTests/Tests/TestCasePlayer.cs @@ -44,13 +44,15 @@ namespace osu.Desktop.VisualTests.Tests time += 500; } - Add(new Player() + Add(new Player { - Beatmap = new WorkingBeatmap( - new Beatmap + Beatmap = new WorkingBeatmap + { + Beatmap = new Beatmap { HitObjects = objects - }) + } + } }); } diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index a805454441..04c9cadd88 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -2,15 +2,38 @@ //Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using System.IO; using osu.Framework.Audio.Track; +using osu.Game.Beatmaps.Formats; using osu.Game.Beatmaps.IO; +using osu.Game.Database; namespace osu.Game.Beatmaps { public class WorkingBeatmap : IDisposable { + private BeatmapInfo beatmapInfo; + public readonly ArchiveReader Reader; - public readonly Beatmap Beatmap; + + private Beatmap beatmap; + public Beatmap Beatmap + { + get + { + if (beatmap != null) return beatmap; + + try + { + using (var stream = new StreamReader(Reader.ReadFile(beatmapInfo.Path))) + beatmap = BeatmapDecoder.GetDecoder(stream)?.Decode(stream); + } + catch { } + + return beatmap; + } + set { beatmap = value; } + } private AudioTrack track; public AudioTrack Track @@ -21,7 +44,7 @@ namespace osu.Game.Beatmaps try { - var trackData = Reader.ReadFile(Beatmap.Metadata.AudioFile); + var trackData = Reader.ReadFile(beatmapInfo.Metadata.AudioFile); if (trackData != null) track = new AudioTrackBass(trackData); } @@ -32,9 +55,9 @@ namespace osu.Game.Beatmaps set { track = value; } } - public WorkingBeatmap(Beatmap beatmap, ArchiveReader reader = null) + public WorkingBeatmap(BeatmapInfo beatmapInfo = null, ArchiveReader reader = null) { - Beatmap = beatmap; + this.beatmapInfo = beatmapInfo; Reader = reader; } @@ -54,5 +77,11 @@ namespace osu.Game.Beatmaps { Dispose(true); } + + public void TransferTo(WorkingBeatmap working) + { + if (track != null && working.beatmapInfo.Metadata.AudioFile == beatmapInfo.Metadata.AudioFile && working.beatmapInfo.BeatmapSet.Path == beatmapInfo.BeatmapSet.Path) + working.track = track; + } } } diff --git a/osu.Game/Database/BeatmapDatabase.cs b/osu.Game/Database/BeatmapDatabase.cs index 7f4bd32f70..5d0834bad7 100644 --- a/osu.Game/Database/BeatmapDatabase.cs +++ b/osu.Game/Database/BeatmapDatabase.cs @@ -136,16 +136,26 @@ namespace osu.Game.Database return Query().Where(s => s.BeatmapSetID == id).FirstOrDefault(); } - public WorkingBeatmap GetWorkingBeatmap(BeatmapInfo beatmapInfo) + public WorkingBeatmap GetWorkingBeatmap(BeatmapInfo beatmapInfo, WorkingBeatmap previous = null) { - var beatmapSet = Query().Where(s => s.BeatmapSetID == beatmapInfo.BeatmapSetID).FirstOrDefault(); - if (beatmapSet == null) + var beatmapSetInfo = Query().FirstOrDefault(s => s.BeatmapSetID == beatmapInfo.BeatmapSetID); + + //we need metadata + GetChildren(beatmapSetInfo); + + if (beatmapSetInfo == null) throw new InvalidOperationException($@"Beatmap set {beatmapInfo.BeatmapSetID} is not in the local database."); - var reader = GetReader(beatmapSet); + var reader = GetReader(beatmapSetInfo); - using (var stream = new StreamReader(reader.ReadFile(beatmapInfo.Path))) - return new WorkingBeatmap(BeatmapDecoder.GetDecoder(stream)?.Decode(stream), reader); + if (beatmapInfo.Metadata == null) + beatmapInfo.Metadata = beatmapSetInfo.Metadata; + + var working = new WorkingBeatmap(beatmapInfo, reader); + + previous?.TransferTo(working); + + return working; } public Beatmap GetBeatmap(BeatmapInfo beatmapInfo) diff --git a/osu.Game/GameModes/Play/PlaySongSelect.cs b/osu.Game/GameModes/Play/PlaySongSelect.cs index 9e2302f25a..4b7bf54fc6 100644 --- a/osu.Game/GameModes/Play/PlaySongSelect.cs +++ b/osu.Game/GameModes/Play/PlaySongSelect.cs @@ -152,7 +152,6 @@ namespace osu.Game.GameModes.Play protected override void OnResuming(GameMode last) { ensurePlayingSelected(); - base.OnResuming(last); } @@ -195,7 +194,7 @@ namespace osu.Game.GameModes.Play if (!beatmap.Equals(Beatmap?.Beatmap?.BeatmapInfo)) { - Beatmap = database.GetWorkingBeatmap(beatmap); + Beatmap = database.GetWorkingBeatmap(beatmap, Beatmap); } ensurePlayingSelected();