1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-30 13:59:40 +08:00
osu-lazer/osu.Game/Database/DatabaseWorkingBeatmap.cs

127 lines
4.6 KiB
C#
Raw Normal View History

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
{
public partial class BeatmapDatabase
{
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;
}
private ArchiveReader GetReader() => database?.GetReader(BeatmapSetInfo);
private Beatmap beatmap;
private object beatmapLock = new object();
public override Beatmap Beatmap
{
get
{
lock (beatmapLock)
{
if (beatmap != null) return beatmap;
try
{
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);
}
}
catch { return null; }
return beatmap;
}
}
}
private object backgroundLock = new object();
private Texture background;
public override Texture Background
{
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 null; }
return background;
}
}
}
private ArchiveReader trackReader;
private Track track;
private object trackLock = new object();
public override Track Track
{
get
{
lock (trackLock)
{
if (track != null) return track;
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 null; }
return track;
}
}
}
public override bool TrackLoaded => track != null;
public override void TransferTo(WorkingBeatmap other)
{
var _other = (DatabaseWorkingBeatmap)other;
if (track != null && BeatmapInfo.AudioEquals(_other.BeatmapInfo))
_other.track = track;
}
public override void Dispose()
{
background?.Dispose();
background = null;
}
}
}
}