Merge pull request #527 from SirCmpwn/working-beatmap

Refactor WorkingBeatmap
This commit is contained in:
Dean Herbert
2017-03-23 10:13:13 +09:00
committed by GitHub
8 changed files with 133 additions and 125 deletions

View File

@ -0,0 +1,24 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Audio.Track;
using osu.Framework.Graphics.Textures;
using osu.Game.Beatmaps;
namespace osu.Desktop.VisualTests.Beatmaps
{
public class TestWorkingBeatmap : WorkingBeatmap
{
public TestWorkingBeatmap(Beatmap beatmap)
: base(beatmap.BeatmapInfo, beatmap.BeatmapInfo.BeatmapSet)
{
this.beatmap = beatmap;
}
private Beatmap beatmap;
protected override Beatmap GetBeatmap() => beatmap;
protected override Texture GetBackground() => null;
protected override Track GetTrack() => null;
}
}

View File

@ -8,7 +8,6 @@ using osu.Framework.MathUtils;
using osu.Framework.Screens.Testing; using osu.Framework.Screens.Testing;
using osu.Framework.Timing; using osu.Framework.Timing;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Beatmaps.IO;
using osu.Game.Database; using osu.Game.Database;
using osu.Game.Modes.Catch.UI; using osu.Game.Modes.Catch.UI;
using osu.Game.Modes.Mania.UI; using osu.Game.Modes.Mania.UI;
@ -17,6 +16,7 @@ using osu.Game.Modes.Osu.Objects;
using osu.Game.Modes.Osu.UI; using osu.Game.Modes.Osu.UI;
using osu.Game.Modes.Taiko.UI; using osu.Game.Modes.Taiko.UI;
using System.Collections.Generic; using System.Collections.Generic;
using osu.Desktop.VisualTests.Beatmaps;
namespace osu.Desktop.VisualTests.Tests namespace osu.Desktop.VisualTests.Tests
{ {
@ -95,16 +95,5 @@ namespace osu.Desktop.VisualTests.Tests
} }
}); });
} }
private class TestWorkingBeatmap : WorkingBeatmap
{
public TestWorkingBeatmap(Beatmap beatmap)
: base(beatmap.BeatmapInfo, beatmap.BeatmapInfo.BeatmapSet)
{
Beatmap = beatmap;
}
protected override ArchiveReader GetReader() => null;
}
} }
} }

View File

@ -8,13 +8,13 @@ using osu.Framework.Screens.Testing;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using OpenTK; using OpenTK;
using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Sprites;
using osu.Game.Beatmaps.IO;
using osu.Game.Database; using osu.Game.Database;
using osu.Game.Modes; using osu.Game.Modes;
using osu.Game.Modes.Objects; using osu.Game.Modes.Objects;
using osu.Game.Modes.Osu.Objects; using osu.Game.Modes.Osu.Objects;
using osu.Game.Screens.Play; using osu.Game.Screens.Play;
using OpenTK.Graphics; using OpenTK.Graphics;
using osu.Desktop.VisualTests.Beatmaps;
namespace osu.Desktop.VisualTests.Tests namespace osu.Desktop.VisualTests.Tests
{ {
@ -23,7 +23,6 @@ namespace osu.Desktop.VisualTests.Tests
protected Player Player; protected Player Player;
private BeatmapDatabase db; private BeatmapDatabase db;
public override string Description => @"Showing everything to play the game."; public override string Description => @"Showing everything to play the game.";
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
@ -97,16 +96,5 @@ namespace osu.Desktop.VisualTests.Tests
Beatmap = beatmap Beatmap = beatmap
}; };
} }
private class TestWorkingBeatmap : WorkingBeatmap
{
public TestWorkingBeatmap(Beatmap beatmap)
: base(beatmap.BeatmapInfo, beatmap.BeatmapInfo.BeatmapSet)
{
Beatmap = beatmap;
}
protected override ArchiveReader GetReader() => null;
}
} }
} }

View File

@ -205,9 +205,13 @@
<Compile Include="Tests\TestCaseDialogOverlay.cs" /> <Compile Include="Tests\TestCaseDialogOverlay.cs" />
<Compile Include="Tests\TestCaseBeatmapOptionsOverlay.cs" /> <Compile Include="Tests\TestCaseBeatmapOptionsOverlay.cs" />
<Compile Include="Tests\TestCaseLeaderboard.cs" /> <Compile Include="Tests\TestCaseLeaderboard.cs" />
<Compile Include="Beatmaps\TestWorkingBeatmap.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup /> <ItemGroup />
<ItemGroup /> <ItemGroup />
<ItemGroup>
<Folder Include="Beatmaps\" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets. Other similar extension points exist, see Microsoft.Common.targets.

View File

@ -4,14 +4,11 @@
using osu.Framework.Audio.Track; using osu.Framework.Audio.Track;
using osu.Framework.Configuration; using osu.Framework.Configuration;
using osu.Framework.Graphics.Textures; using osu.Framework.Graphics.Textures;
using osu.Game.Beatmaps.Formats;
using osu.Game.Beatmaps.IO;
using osu.Game.Database; using osu.Game.Database;
using osu.Game.Modes; using osu.Game.Modes;
using osu.Game.Modes.Mods; using osu.Game.Modes.Mods;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
namespace osu.Game.Beatmaps namespace osu.Game.Beatmaps
{ {
@ -27,14 +24,12 @@ namespace osu.Game.Beatmaps
/// </summary> /// </summary>
public PlayMode? PreferredPlayMode; public PlayMode? PreferredPlayMode;
public PlayMode PlayMode => beatmap?.BeatmapInfo?.Mode > PlayMode.Osu ? beatmap.BeatmapInfo.Mode : PreferredPlayMode ?? PlayMode.Osu; public PlayMode PlayMode => Beatmap?.BeatmapInfo?.Mode > PlayMode.Osu ? Beatmap.BeatmapInfo.Mode : PreferredPlayMode ?? PlayMode.Osu;
public readonly Bindable<IEnumerable<Mod>> Mods = new Bindable<IEnumerable<Mod>>(); public readonly Bindable<IEnumerable<Mod>> Mods = new Bindable<IEnumerable<Mod>>();
public readonly bool WithStoryboard; public readonly bool WithStoryboard;
protected abstract ArchiveReader GetReader();
protected WorkingBeatmap(BeatmapInfo beatmapInfo, BeatmapSetInfo beatmapSetInfo, bool withStoryboard = false) protected WorkingBeatmap(BeatmapInfo beatmapInfo, BeatmapSetInfo beatmapSetInfo, bool withStoryboard = false)
{ {
BeatmapInfo = beatmapInfo; BeatmapInfo = beatmapInfo;
@ -42,31 +37,10 @@ namespace osu.Game.Beatmaps
WithStoryboard = withStoryboard; WithStoryboard = withStoryboard;
} }
private Texture background; protected abstract Beatmap GetBeatmap();
private object backgroundLock = new object(); protected abstract Texture GetBackground();
public Texture Background protected abstract Track GetTrack();
{
get
{
lock (backgroundLock)
{
if (background != null) return background;
if (BeatmapInfo?.Metadata?.BackgroundFile == null) return null;
try
{
using (var reader = GetReader())
background = new TextureStore(new RawTextureLoaderStore(reader), false).Get(BeatmapInfo.Metadata.BackgroundFile);
}
catch { }
return background;
}
}
set { lock (backgroundLock) background = value; }
}
private Beatmap beatmap; private Beatmap beatmap;
private object beatmapLock = new object(); private object beatmapLock = new object();
public Beatmap Beatmap public Beatmap Beatmap
@ -75,33 +49,24 @@ namespace osu.Game.Beatmaps
{ {
lock (beatmapLock) lock (beatmapLock)
{ {
if (beatmap != null) return beatmap; return beatmap ?? (beatmap = GetBeatmap());
}
try }
{ }
using (var reader = GetReader())
{ private object backgroundLock = new object();
BeatmapDecoder decoder; private Texture background;
using (var stream = new StreamReader(reader.GetStream(BeatmapInfo.Path))) public Texture Background
{ {
decoder = BeatmapDecoder.GetDecoder(stream); get
beatmap = decoder?.Decode(stream); {
} lock (backgroundLock)
{
if (WithStoryboard && beatmap != null && BeatmapSetInfo.StoryboardFile != null) return background ?? (background = GetBackground());
using (var stream = new StreamReader(reader.GetStream(BeatmapSetInfo.StoryboardFile)))
decoder?.Decode(stream, beatmap);
}
}
catch { }
return beatmap;
} }
} }
set { lock (beatmapLock) beatmap = value; }
} }
private ArchiveReader trackReader;
private Track track; private Track track;
private object trackLock = new object(); private object trackLock = new object();
public Track Track public Track Track
@ -110,48 +75,25 @@ namespace osu.Game.Beatmaps
{ {
lock (trackLock) lock (trackLock)
{ {
if (track != null) return track; return track ?? (track = GetTrack());
try
{
//store a reference to the reader as we may continue accessing the stream in the background.
trackReader = GetReader();
var trackData = trackReader?.GetStream(BeatmapInfo.Metadata.AudioFile);
if (trackData != null)
track = new TrackBass(trackData);
}
catch { }
return track;
} }
} }
set { lock (trackLock) track = value; }
} }
public bool TrackLoaded => track != null; public bool TrackLoaded => track != null;
private bool isDisposed; public void TransferTo(WorkingBeatmap other)
protected virtual void Dispose(bool disposing)
{ {
if (!isDisposed) if (track != null && BeatmapInfo.AudioEquals(other.BeatmapInfo))
{ other.track = track;
track?.Dispose();
background?.Dispose();
isDisposed = true;
}
} }
public void Dispose() public virtual void Dispose()
{ {
Dispose(true); track?.Dispose();
GC.SuppressFinalize(this); track = null;
} background?.Dispose();
background = null;
public void TransferTo(WorkingBeatmap working)
{
if (track != null && BeatmapInfo.AudioEquals(working.BeatmapInfo))
working.track = track;
} }
} }
} }

View File

@ -342,18 +342,5 @@ namespace osu.Game.Database
} }
public bool Exists(BeatmapSetInfo beatmapSet) => storage.Exists(beatmapSet.Path); public bool Exists(BeatmapSetInfo beatmapSet) => storage.Exists(beatmapSet.Path);
private class DatabaseWorkingBeatmap : WorkingBeatmap
{
private readonly BeatmapDatabase database;
public DatabaseWorkingBeatmap(BeatmapDatabase database, BeatmapInfo beatmapInfo, BeatmapSetInfo beatmapSetInfo, bool withStoryboard = false)
: base(beatmapInfo, beatmapSetInfo, withStoryboard)
{
this.database = database;
}
protected override ArchiveReader GetReader() => database?.GetReader(BeatmapSetInfo);
}
} }
} }

View File

@ -0,0 +1,73 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.IO;
using osu.Framework.Audio.Track;
using osu.Framework.Graphics.Textures;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Formats;
using osu.Game.Beatmaps.IO;
namespace osu.Game.Database
{
internal class DatabaseWorkingBeatmap : WorkingBeatmap
{
private readonly BeatmapDatabase database;
public DatabaseWorkingBeatmap(BeatmapDatabase database, BeatmapInfo beatmapInfo, BeatmapSetInfo beatmapSetInfo, bool withStoryboard = false)
: base(beatmapInfo, beatmapSetInfo, withStoryboard)
{
this.database = database;
}
private ArchiveReader getReader() => database?.GetReader(BeatmapSetInfo);
protected override Beatmap GetBeatmap()
{
try
{
Beatmap beatmap;
using (var reader = getReader())
{
BeatmapDecoder decoder;
using (var stream = new StreamReader(reader.GetStream(BeatmapInfo.Path)))
{
decoder = BeatmapDecoder.GetDecoder(stream);
beatmap = decoder?.Decode(stream);
}
if (WithStoryboard && beatmap != null && BeatmapSetInfo.StoryboardFile != null)
using (var stream = new StreamReader(reader.GetStream(BeatmapSetInfo.StoryboardFile)))
decoder.Decode(stream, beatmap);
}
return beatmap;
}
catch { return null; }
}
protected override Texture GetBackground()
{
if (BeatmapInfo?.Metadata?.BackgroundFile == null)
return null;
try
{
using (var reader = getReader())
return new TextureStore(new RawTextureLoaderStore(reader), false).Get(BeatmapInfo.Metadata.BackgroundFile);
}
catch { return null; }
}
protected override Track GetTrack()
{
try
{
var trackData = getReader()?.GetStream(BeatmapInfo.Metadata.AudioFile);
return trackData == null ? null : new TrackBass(trackData);
}
catch { return null; }
}
}
}

View File

@ -279,6 +279,7 @@
<Compile Include="Database\BeatmapMetadata.cs" /> <Compile Include="Database\BeatmapMetadata.cs" />
<Compile Include="Database\BeatmapInfo.cs" /> <Compile Include="Database\BeatmapInfo.cs" />
<Compile Include="Database\BaseDifficulty.cs" /> <Compile Include="Database\BaseDifficulty.cs" />
<Compile Include="Database\DatabaseWorkingBeatmap.cs" />
<Compile Include="Graphics\UserInterface\OsuButton.cs" /> <Compile Include="Graphics\UserInterface\OsuButton.cs" />
<Compile Include="Overlays\Options\Sections\MaintenanceSection.cs" /> <Compile Include="Overlays\Options\Sections\MaintenanceSection.cs" />
<Compile Include="Overlays\Options\OptionsSection.cs" /> <Compile Include="Overlays\Options\OptionsSection.cs" />