1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-28 04:42:58 +08:00

Add the concept of a "WorkingBeatmap" and make player load beatmaps and audio from SongSelect.

This commit is contained in:
Dean Herbert 2016-10-28 14:14:45 +09:00
parent 2cdda98b47
commit feccb7286c
5 changed files with 138 additions and 28 deletions

View File

@ -46,10 +46,11 @@ namespace osu.Desktop.VisualTests.Tests
Add(new Player() Add(new Player()
{ {
Beatmap = new Beatmap Beatmap = new WorkingBeatmap(
{ new Beatmap
HitObjects = objects {
} HitObjects = objects
})
}); });
} }

View File

@ -0,0 +1,62 @@
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using osu.Framework.Audio.Track;
using osu.Game.Beatmaps.IO;
namespace osu.Game.Beatmaps
{
public class WorkingBeatmap : IDisposable
{
public readonly ArchiveReader Reader;
public readonly Beatmap Beatmap;
private AudioTrack track;
public AudioTrack Track
{
get
{
if (track == null)
{
var trackData = Reader.ReadFile(Beatmap.Metadata.AudioFile);
if (trackData != null)
track = new AudioTrackBass(trackData);
}
return track;
}
set { track = value; }
}
public WorkingBeatmap(Beatmap beatmap, ArchiveReader reader = null)
{
Beatmap = beatmap;
Reader = reader;
}
private bool isDisposed;
protected virtual void Dispose(bool disposing)
{
if (!isDisposed)
{
track?.Dispose();
Reader?.Dispose();
isDisposed = true;
}
}
~WorkingBeatmap()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
}

View File

@ -136,19 +136,22 @@ namespace osu.Game.Database
return Query<BeatmapSetInfo>().Where(s => s.BeatmapSetID == id).FirstOrDefault(); return Query<BeatmapSetInfo>().Where(s => s.BeatmapSetID == id).FirstOrDefault();
} }
public WorkingBeatmap GetBeatmapData(BeatmapInfo beatmapInfo)
{
var beatmapSet = Query<BeatmapSetInfo>().Where(s => s.BeatmapSetID == beatmapInfo.BeatmapSetID).FirstOrDefault();
if (beatmapSet == null)
throw new InvalidOperationException($@"Beatmap set {beatmapInfo.BeatmapSetID} is not in the local database.");
var reader = GetReader(beatmapSet);
using (var stream = new StreamReader(reader.ReadFile(beatmapInfo.Path)))
return new WorkingBeatmap(BeatmapDecoder.GetDecoder(stream)?.Decode(stream), reader);
}
public Beatmap GetBeatmap(BeatmapInfo beatmapInfo) public Beatmap GetBeatmap(BeatmapInfo beatmapInfo)
{ {
var beatmapSet = Query<BeatmapSetInfo>() using (WorkingBeatmap data = GetBeatmapData(beatmapInfo))
.Where(s => s.BeatmapSetID == beatmapInfo.BeatmapSetID).FirstOrDefault(); return data.Beatmap;
if (beatmapSet == null)
throw new InvalidOperationException(
$@"Beatmap set {beatmapInfo.BeatmapSetID} is not in the local database.");
using (var reader = GetReader(beatmapSet))
using (var stream = new StreamReader(reader.ReadFile(beatmapInfo.Path)))
{
var decoder = BeatmapDecoder.GetDecoder(stream);
return decoder.Decode(stream);
}
} }
public TableQuery<T> Query<T>() where T : class public TableQuery<T> Query<T>() where T : class

View File

@ -1,7 +1,6 @@
//Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>. //Copyright (c) 2007-2016 ppy Pty Ltd <contact@ppy.sh>.
//Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE //Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Collections.Generic;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Objects; using osu.Game.Beatmaps.Objects;
@ -12,6 +11,9 @@ using osu.Game.GameModes.Play.Osu;
using osu.Game.GameModes.Play.Taiko; using osu.Game.GameModes.Play.Taiko;
using osu.Framework; using osu.Framework;
using osu.Game.Database; using osu.Game.Database;
using osu.Framework.Timing;
using osu.Framework.GameModes;
using osu.Framework.Audio.Track;
namespace osu.Game.GameModes.Play namespace osu.Game.GameModes.Play
{ {
@ -20,10 +22,29 @@ namespace osu.Game.GameModes.Play
protected override BackgroundMode CreateBackground() => new BackgroundModeCustom(@"Backgrounds/bg4"); protected override BackgroundMode CreateBackground() => new BackgroundModeCustom(@"Backgrounds/bg4");
public BeatmapInfo BeatmapInfo; public BeatmapInfo BeatmapInfo;
public Beatmap Beatmap; public WorkingBeatmap Beatmap;
public PlayMode PlayMode; public PlayMode PlayMode;
protected override IFrameBasedClock Clock => playerClock;
private InterpolatingFramedClock playerClock;
private IAdjustableClock sourceClock;
protected override void Dispose(bool isDisposing)
{
Beatmap?.Dispose();
base.Dispose(isDisposing);
}
protected override bool OnExiting(GameMode next)
{
//eagerly dispose as the finalizer runs too late right now.
Beatmap?.Dispose();
return base.OnExiting(next);
}
public override void Load(BaseGame game) public override void Load(BaseGame game)
{ {
base.Load(game); base.Load(game);
@ -31,7 +52,7 @@ namespace osu.Game.GameModes.Play
try try
{ {
if (Beatmap == null) if (Beatmap == null)
Beatmap = ((OsuGame)game).Beatmaps.GetBeatmap(BeatmapInfo); Beatmap = ((OsuGame)game).Beatmaps.GetBeatmapData(BeatmapInfo);
} }
catch catch
{ {
@ -40,6 +61,22 @@ namespace osu.Game.GameModes.Play
return; return;
} }
AudioTrack track = Beatmap.Track;
if (track != null)
{
game.Audio.Track.SetExclusive(track);
sourceClock = track;
}
sourceClock = (IAdjustableClock)Beatmap.Track ?? new StopwatchClock();
playerClock = new InterpolatingFramedClock(sourceClock);
Schedule(() =>
{
sourceClock.Start();
});
HitRenderer hitRenderer; HitRenderer hitRenderer;
ScoreOverlay scoreOverlay; ScoreOverlay scoreOverlay;
@ -50,7 +87,7 @@ namespace osu.Game.GameModes.Play
hitRenderer = new OsuHitRenderer hitRenderer = new OsuHitRenderer
{ {
Objects = Beatmap.HitObjects, Objects = Beatmap.Beatmap.HitObjects,
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre Origin = Anchor.Centre
}; };
@ -60,7 +97,7 @@ namespace osu.Game.GameModes.Play
hitRenderer = new TaikoHitRenderer hitRenderer = new TaikoHitRenderer
{ {
Objects = Beatmap.HitObjects, Objects = Beatmap.Beatmap.HitObjects,
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre Origin = Anchor.Centre
}; };
@ -70,7 +107,7 @@ namespace osu.Game.GameModes.Play
hitRenderer = new CatchHitRenderer hitRenderer = new CatchHitRenderer
{ {
Objects = Beatmap.HitObjects, Objects = Beatmap.Beatmap.HitObjects,
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre Origin = Anchor.Centre
}; };
@ -80,7 +117,7 @@ namespace osu.Game.GameModes.Play
hitRenderer = new ManiaHitRenderer hitRenderer = new ManiaHitRenderer
{ {
Objects = Beatmap.HitObjects, Objects = Beatmap.Beatmap.HitObjects,
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre Origin = Anchor.Centre
}; };
@ -96,5 +133,11 @@ namespace osu.Game.GameModes.Play
scoreOverlay, scoreOverlay,
}; };
} }
protected override void Update()
{
base.Update();
playerClock.ProcessFrame();
}
} }
} }

View File

@ -64,6 +64,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Beatmaps\Beatmap.cs" /> <Compile Include="Beatmaps\Beatmap.cs" />
<Compile Include="Beatmaps\WorkingBeatmap.cs" />
<Compile Include="Beatmaps\Drawable\BeatmapSetHeader.cs" /> <Compile Include="Beatmaps\Drawable\BeatmapSetHeader.cs" />
<Compile Include="Beatmaps\Drawable\DifficultyIcon.cs" /> <Compile Include="Beatmaps\Drawable\DifficultyIcon.cs" />
<Compile Include="Beatmaps\Drawable\Panel.cs" /> <Compile Include="Beatmaps\Drawable\Panel.cs" />