From 9f740f69bb8ab61459dc72bd7c6dce4062e78759 Mon Sep 17 00:00:00 2001
From: Dean Herbert <pe@ppy.sh>
Date: Fri, 7 Jun 2019 11:20:39 +0900
Subject: [PATCH] Fix preview tracks muting themselves

Closes #4937
---
 osu.Game/Audio/PreviewTrackManager.cs | 57 ++++++++++++++++++++++++---
 1 file changed, 52 insertions(+), 5 deletions(-)

diff --git a/osu.Game/Audio/PreviewTrackManager.cs b/osu.Game/Audio/PreviewTrackManager.cs
index d479483508..6e162ca95e 100644
--- a/osu.Game/Audio/PreviewTrackManager.cs
+++ b/osu.Game/Audio/PreviewTrackManager.cs
@@ -1,6 +1,10 @@
 // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
 // See the LICENCE file in the repository root for full licence text.
 
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Threading.Tasks;
 using osu.Framework.Allocation;
 using osu.Framework.Audio;
 using osu.Framework.Audio.Track;
@@ -12,22 +16,24 @@ using osu.Game.Beatmaps;
 
 namespace osu.Game.Audio
 {
-    /// <summary>
-    /// A central store for the retrieval of <see cref="PreviewTrack"/>s.
-    /// </summary>
     public class PreviewTrackManager : Component
     {
         private readonly BindableDouble muteBindable = new BindableDouble();
 
         private AudioManager audio;
-        private ITrackStore trackStore;
+        private PreviewTrackStore trackStore;
 
         private TrackManagerPreviewTrack current;
 
         [BackgroundDependencyLoader]
         private void load(AudioManager audio, FrameworkConfigManager config)
         {
-            trackStore = audio.GetTrackStore(new OnlineStore());
+            // this is a temporary solution to get around muting ourselves.
+            // todo: update this once we have a BackgroundTrackManager or similar.
+            trackStore = new PreviewTrackStore(new OnlineStore());
+
+            audio.AddItem(trackStore);
+            trackStore.AddAdjustment(AdjustableProperty.Volume, audio.VolumeTrack);
 
             this.audio = audio;
 
@@ -103,5 +109,46 @@ namespace osu.Game.Audio
 
             protected override Track GetTrack() => trackManager.Get($"https://b.ppy.sh/preview/{beatmapSetInfo?.OnlineBeatmapSetID}.mp3");
         }
+
+        private class PreviewTrackStore : AudioCollectionManager<AdjustableAudioComponent>, ITrackStore
+        {
+            private readonly IResourceStore<byte[]> store;
+
+            internal PreviewTrackStore(IResourceStore<byte[]> store)
+            {
+                this.store = store;
+            }
+
+            public Track GetVirtual(double length = double.PositiveInfinity)
+            {
+                if (IsDisposed) throw new ObjectDisposedException($"Cannot retrieve items for an already disposed {nameof(PreviewTrackStore)}");
+
+                var track = new TrackVirtual(length);
+                AddItem(track);
+                return track;
+            }
+
+            public Track Get(string name)
+            {
+                if (IsDisposed) throw new ObjectDisposedException($"Cannot retrieve items for an already disposed {nameof(PreviewTrackStore)}");
+
+                if (string.IsNullOrEmpty(name)) return null;
+
+                var dataStream = store.GetStream(name);
+
+                if (dataStream == null)
+                    return null;
+
+                Track track = new TrackBass(dataStream);
+                AddItem(track);
+                return track;
+            }
+
+            public Task<Track> GetAsync(string name) => Task.Run(() => Get(name));
+
+            public Stream GetStream(string name) => store.GetStream(name);
+
+            public IEnumerable<string> GetAvailableResources() => store.GetAvailableResources();
+        }
     }
 }