1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-15 16:42:57 +08:00

Merge pull request #10841 from bdach/fix-spectator-preview-crash

Add support for previewing tracks on spectator screen
This commit is contained in:
Dean Herbert 2020-11-16 01:09:37 +09:00 committed by GitHub
commit 67db278864
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 44 additions and 7 deletions

View File

@ -167,6 +167,21 @@ namespace osu.Game.Tests.Visual.Components
AddAssert("game not muted", () => audio.Tracks.AggregateVolume.Value != 0); AddAssert("game not muted", () => audio.Tracks.AggregateVolume.Value != 0);
} }
[Test]
public void TestOwnerNotRegistered()
{
PreviewTrack track = null;
AddStep("get track", () => Add(new TestTrackOwner(track = getTrack(), registerAsOwner: false)));
AddUntilStep("wait for loaded", () => track.IsLoaded);
AddStep("start track", () => track.Start());
AddUntilStep("track is running", () => track.IsRunning);
AddStep("cancel from anyone", () => trackManager.StopAnyPlaying(this));
AddAssert("track stopped", () => !track.IsRunning);
}
private TestPreviewTrack getTrack() => (TestPreviewTrack)trackManager.Get(null); private TestPreviewTrack getTrack() => (TestPreviewTrack)trackManager.Get(null);
private TestPreviewTrack getOwnedTrack() private TestPreviewTrack getOwnedTrack()
@ -181,10 +196,12 @@ namespace osu.Game.Tests.Visual.Components
private class TestTrackOwner : CompositeDrawable, IPreviewTrackOwner private class TestTrackOwner : CompositeDrawable, IPreviewTrackOwner
{ {
private readonly PreviewTrack track; private readonly PreviewTrack track;
private readonly bool registerAsOwner;
public TestTrackOwner(PreviewTrack track) public TestTrackOwner(PreviewTrack track, bool registerAsOwner = true)
{ {
this.track = track; this.track = track;
this.registerAsOwner = registerAsOwner;
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
@ -196,7 +213,8 @@ namespace osu.Game.Tests.Visual.Components
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
{ {
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
dependencies.CacheAs<IPreviewTrackOwner>(this); if (registerAsOwner)
dependencies.CacheAs<IPreviewTrackOwner>(this);
return dependencies; return dependencies;
} }
} }

View File

@ -11,6 +11,7 @@ using osu.Framework.Audio.Track;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.IO.Stores; using osu.Framework.IO.Stores;
using osu.Framework.Logging;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
namespace osu.Game.Audio namespace osu.Game.Audio
@ -76,7 +77,7 @@ namespace osu.Game.Audio
/// <param name="source">The <see cref="IPreviewTrackOwner"/> which may be the owner of the <see cref="PreviewTrack"/>.</param> /// <param name="source">The <see cref="IPreviewTrackOwner"/> which may be the owner of the <see cref="PreviewTrack"/>.</param>
public void StopAnyPlaying(IPreviewTrackOwner source) public void StopAnyPlaying(IPreviewTrackOwner source)
{ {
if (CurrentTrack == null || CurrentTrack.Owner != source) if (CurrentTrack == null || (CurrentTrack.Owner != null && CurrentTrack.Owner != source))
return; return;
CurrentTrack.Stop(); CurrentTrack.Stop();
@ -86,11 +87,12 @@ namespace osu.Game.Audio
/// <summary> /// <summary>
/// Creates the <see cref="TrackManagerPreviewTrack"/>. /// Creates the <see cref="TrackManagerPreviewTrack"/>.
/// </summary> /// </summary>
protected virtual TrackManagerPreviewTrack CreatePreviewTrack(BeatmapSetInfo beatmapSetInfo, ITrackStore trackStore) => new TrackManagerPreviewTrack(beatmapSetInfo, trackStore); protected virtual TrackManagerPreviewTrack CreatePreviewTrack(BeatmapSetInfo beatmapSetInfo, ITrackStore trackStore) =>
new TrackManagerPreviewTrack(beatmapSetInfo, trackStore);
public class TrackManagerPreviewTrack : PreviewTrack public class TrackManagerPreviewTrack : PreviewTrack
{ {
[Resolved] [Resolved(canBeNull: true)]
public IPreviewTrackOwner Owner { get; private set; } public IPreviewTrackOwner Owner { get; private set; }
private readonly BeatmapSetInfo beatmapSetInfo; private readonly BeatmapSetInfo beatmapSetInfo;
@ -102,6 +104,12 @@ namespace osu.Game.Audio
this.trackManager = trackManager; this.trackManager = trackManager;
} }
protected override void LoadComplete()
{
base.LoadComplete();
Logger.Log($"A {nameof(PreviewTrack)} was created without a containing {nameof(IPreviewTrackOwner)}. An owner should be added for correct behaviour.");
}
protected override Track GetTrack() => trackManager.Get($"https://b.ppy.sh/preview/{beatmapSetInfo?.OnlineBeatmapSetID}.mp3"); protected override Track GetTrack() => trackManager.Get($"https://b.ppy.sh/preview/{beatmapSetInfo?.OnlineBeatmapSetID}.mp3");
} }

View File

@ -13,6 +13,7 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Sprites;
using osu.Framework.Screens; using osu.Framework.Screens;
using osu.Game.Audio;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Configuration; using osu.Game.Configuration;
using osu.Game.Graphics; using osu.Game.Graphics;
@ -35,7 +36,8 @@ using osuTK;
namespace osu.Game.Screens.Play namespace osu.Game.Screens.Play
{ {
public class Spectator : OsuScreen [Cached(typeof(IPreviewTrackOwner))]
public class Spectator : OsuScreen, IPreviewTrackOwner
{ {
private readonly User targetUser; private readonly User targetUser;
@ -62,6 +64,9 @@ namespace osu.Game.Screens.Play
[Resolved] [Resolved]
private RulesetStore rulesets { get; set; } private RulesetStore rulesets { get; set; }
[Resolved]
private PreviewTrackManager previewTrackManager { get; set; }
private Score score; private Score score;
private readonly object scoreLock = new object(); private readonly object scoreLock = new object();
@ -275,6 +280,7 @@ namespace osu.Game.Screens.Play
{ {
watchButton.Enabled.Value = false; watchButton.Enabled.Value = false;
beatmapPanelContainer.Clear(); beatmapPanelContainer.Clear();
previewTrackManager.StopAnyPlaying(this);
} }
private void attemptStart() private void attemptStart()
@ -326,7 +332,6 @@ namespace osu.Game.Screens.Play
{ {
if (state?.BeatmapID == null) if (state?.BeatmapID == null)
{ {
beatmapPanelContainer.Clear();
onlineBeatmap = null; onlineBeatmap = null;
return; return;
} }
@ -359,6 +364,12 @@ namespace osu.Game.Screens.Play
beatmaps.Download(onlineBeatmap); beatmaps.Download(onlineBeatmap);
} }
public override bool OnExiting(IScreen next)
{
previewTrackManager.StopAnyPlaying(this);
return base.OnExiting(next);
}
protected override void Dispose(bool isDisposing) protected override void Dispose(bool isDisposing)
{ {
base.Dispose(isDisposing); base.Dispose(isDisposing);