diff --git a/osu.Game.Tests/Visual/Components/TestScenePreviewTrackManager.cs b/osu.Game.Tests/Visual/Components/TestScenePreviewTrackManager.cs index e85e879ef5..0784725ea4 100644 --- a/osu.Game.Tests/Visual/Components/TestScenePreviewTrackManager.cs +++ b/osu.Game.Tests/Visual/Components/TestScenePreviewTrackManager.cs @@ -5,6 +5,7 @@ using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Audio.Track; using osu.Framework.Graphics.Containers; +using osu.Framework.IO.Stores; using osu.Game.Audio; using osu.Game.Beatmaps; @@ -111,11 +112,11 @@ namespace osu.Game.Tests.Visual.Components private class TestPreviewTrackManager : PreviewTrackManager { - protected override TrackManagerPreviewTrack CreatePreviewTrack(BeatmapSetInfo beatmapSetInfo, TrackStore trackStore) => new TestPreviewTrack(beatmapSetInfo, trackStore); + protected override TrackManagerPreviewTrack CreatePreviewTrack(BeatmapSetInfo beatmapSetInfo, IResourceStore trackStore) => new TestPreviewTrack(beatmapSetInfo, trackStore); protected class TestPreviewTrack : TrackManagerPreviewTrack { - public TestPreviewTrack(BeatmapSetInfo beatmapSetInfo, TrackStore trackManager) + public TestPreviewTrack(BeatmapSetInfo beatmapSetInfo, IResourceStore trackManager) : base(beatmapSetInfo, trackManager) { } diff --git a/osu.Game/Audio/PreviewTrackManager.cs b/osu.Game/Audio/PreviewTrackManager.cs index 695051f508..4b7277c3fd 100644 --- a/osu.Game/Audio/PreviewTrackManager.cs +++ b/osu.Game/Audio/PreviewTrackManager.cs @@ -20,17 +20,16 @@ namespace osu.Game.Audio private readonly BindableDouble muteBindable = new BindableDouble(); private AudioManager audio; - private TrackStore trackStore; + private IAdjustableResourceStore trackStore; private TrackManagerPreviewTrack current; [BackgroundDependencyLoader] private void load(AudioManager audio, FrameworkConfigManager config) { - trackStore = new TrackStore(new OnlineStore()); + trackStore = audio.GetTrackStore(new OnlineStore()); this.audio = audio; - audio.AddItem(trackStore); config.BindWith(FrameworkSetting.VolumeMusic, trackStore.Volume); } @@ -81,16 +80,16 @@ namespace osu.Game.Audio /// /// Creates the . /// - protected virtual TrackManagerPreviewTrack CreatePreviewTrack(BeatmapSetInfo beatmapSetInfo, TrackStore trackStore) => new TrackManagerPreviewTrack(beatmapSetInfo, trackStore); + protected virtual TrackManagerPreviewTrack CreatePreviewTrack(BeatmapSetInfo beatmapSetInfo, IResourceStore trackStore) => new TrackManagerPreviewTrack(beatmapSetInfo, trackStore); protected class TrackManagerPreviewTrack : PreviewTrack { public IPreviewTrackOwner Owner { get; private set; } private readonly BeatmapSetInfo beatmapSetInfo; - private readonly TrackStore trackManager; + private readonly IResourceStore trackManager; - public TrackManagerPreviewTrack(BeatmapSetInfo beatmapSetInfo, TrackStore trackManager) + public TrackManagerPreviewTrack(BeatmapSetInfo beatmapSetInfo, IResourceStore trackManager) { this.beatmapSetInfo = beatmapSetInfo; this.trackManager = trackManager; diff --git a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs index 0bdab22dd2..cfeb6b0a92 100644 --- a/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/BeatmapManager_WorkingBeatmap.cs @@ -20,14 +20,13 @@ namespace osu.Game.Beatmaps protected class BeatmapManagerWorkingBeatmap : WorkingBeatmap { private readonly IResourceStore store; - private readonly AudioManager audioManager; public BeatmapManagerWorkingBeatmap(IResourceStore store, TextureStore textureStore, BeatmapInfo beatmapInfo, AudioManager audioManager) : base(beatmapInfo) { this.store = store; this.textureStore = textureStore; - this.audioManager = audioManager; + AudioManager = audioManager; } protected override IBeatmap GetBeatmap() @@ -47,6 +46,8 @@ namespace osu.Game.Beatmaps private TextureStore textureStore; + private IAdjustableResourceStore trackStore; + protected override bool BackgroundStillValid(Texture b) => false; // bypass lazy logic. we want to return a new background each time for refcounting purposes. protected override Texture GetBackground() @@ -68,8 +69,7 @@ namespace osu.Game.Beatmaps { try { - var trackData = store.GetStream(getPathForFile(Metadata.AudioFile)); - return trackData == null ? null : new TrackBass(trackData); + return (trackStore ?? (trackStore = AudioManager.GetTrackStore(store))).Get(getPathForFile(Metadata.AudioFile)); } catch { @@ -77,6 +77,14 @@ namespace osu.Game.Beatmaps } } + public override void RecycleTrack() + { + base.RecycleTrack(); + + trackStore?.Dispose(); + trackStore = null; + } + public override void TransferTo(WorkingBeatmap other) { base.TransferTo(other); @@ -135,7 +143,7 @@ namespace osu.Game.Beatmaps try { - skin = new LegacyBeatmapSkin(BeatmapInfo, store, audioManager); + skin = new LegacyBeatmapSkin(BeatmapInfo, store, AudioManager); } catch (Exception e) { diff --git a/osu.Game/Beatmaps/BindableBeatmap.cs b/osu.Game/Beatmaps/BindableBeatmap.cs index dcce18b1be..6614a6f2fb 100644 --- a/osu.Game/Beatmaps/BindableBeatmap.cs +++ b/osu.Game/Beatmaps/BindableBeatmap.cs @@ -1,11 +1,9 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; using System.Diagnostics; using JetBrains.Annotations; using osu.Framework.Audio; -using osu.Framework.Audio.Track; using osu.Framework.Bindables; namespace osu.Game.Beatmaps @@ -16,32 +14,26 @@ namespace osu.Game.Beatmaps /// public abstract class BindableBeatmap : NonNullableBindable { - private AudioManager audioManager; + protected AudioManager AudioManager; + private WorkingBeatmap lastBeatmap; - protected BindableBeatmap(WorkingBeatmap defaultValue) + protected BindableBeatmap(WorkingBeatmap defaultValue, AudioManager audioManager) : base(defaultValue) { + // we don't want to attempt to update tracks if we are a bound copy. + if (audioManager != null) + { + AudioManager = audioManager; + ValueChanged += b => updateAudioTrack(b.NewValue); + + // If the track has changed prior to this being called, let's register it + if (Value != Default) + updateAudioTrack(Value); + } } - /// - /// Registers an for s to be added to. - /// - /// The to register. - protected void RegisterAudioManager([NotNull] AudioManager audioManager) - { - if (this.audioManager != null) throw new InvalidOperationException($"Cannot register multiple {nameof(AudioManager)}s."); - - this.audioManager = audioManager; - - ValueChanged += b => registerAudioTrack(b.NewValue); - - // If the track has changed prior to this being called, let's register it - if (Value != Default) - registerAudioTrack(Value); - } - - private void registerAudioTrack(WorkingBeatmap beatmap) + private void updateAudioTrack(WorkingBeatmap beatmap) { var trackLoaded = lastBeatmap?.TrackLoaded ?? false; @@ -55,8 +47,6 @@ namespace osu.Game.Beatmaps lastBeatmap.RecycleTrack(); } - - audioManager.Tracks.AddItem(beatmap.Track); } lastBeatmap = beatmap; diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 4b0720d867..288bd0773c 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -11,6 +11,7 @@ using osu.Framework.IO.File; using System.IO; using System.Linq; using System.Threading; +using osu.Framework.Audio; using osu.Game.IO.Serialization; using osu.Game.Rulesets; using osu.Game.Rulesets.Objects; @@ -150,6 +151,9 @@ namespace osu.Game.Beatmaps public bool SkinLoaded => skin.IsResultAvailable; public Skin Skin => skin.Value; + + public AudioManager AudioManager { get; set; } + protected virtual Skin GetSkin() => new DefaultSkin(); private readonly RecyclableLazy skin; @@ -175,7 +179,7 @@ namespace osu.Game.Beatmaps /// Eagerly dispose of the audio track associated with this (if any). /// Accessing track again will load a fresh instance. /// - public void RecycleTrack() => track.Recycle(); + public virtual void RecycleTrack() => track.Recycle(); public class RecyclableLazy { diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 40cb26ec54..8e663de8c5 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -281,20 +281,19 @@ namespace osu.Game private class OsuBindableBeatmap : BindableBeatmap { - public OsuBindableBeatmap(WorkingBeatmap defaultValue, AudioManager audioManager) - : this(defaultValue) + public OsuBindableBeatmap(WorkingBeatmap defaultValue) + : base(defaultValue, null) { - RegisterAudioManager(audioManager); } - public OsuBindableBeatmap(WorkingBeatmap defaultValue) - : base(defaultValue) + public OsuBindableBeatmap(WorkingBeatmap defaultValue, AudioManager audioManager) + : base(defaultValue, audioManager) { } public override BindableBeatmap GetBoundCopy() { - var copy = new OsuBindableBeatmap(Default); + var copy = new OsuBindableBeatmap(Default, AudioManager); copy.BindTo(this); return copy; } diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index ea3e1ca00c..d7b915efe3 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -350,7 +350,7 @@ namespace osu.Game.Overlays direction = last > next ? TransformDirection.Prev : TransformDirection.Next; } - current.Track.Completed -= currentTrackCompleted; + //current.Track.Completed -= currentTrackCompleted; } current = beatmap.NewValue; diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index b266a73eb5..6d5be607f4 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -580,9 +580,6 @@ namespace osu.Game.Screens.Select if (!track.IsRunning || restart) { - // Ensure the track is added to the TrackManager, since it is removed after the player finishes the map. - // Using AddItemToList rather than AddItem so that it doesn't attempt to register adjustment dependencies more than once. - Game.Audio.Tracks.AddItem(track); track.RestartPoint = Beatmap.Value.Metadata.PreviewTime; track.Restart(); } diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 9f31783a6b..8d38f944d0 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -21,7 +21,7 @@ namespace osu.Game.Skinning { protected TextureStore Textures; - protected SampleStore Samples; + protected IResourceStore Samples; public LegacySkin(SkinInfo skin, IResourceStore storage, AudioManager audioManager) : this(skin, new LegacySkinResourceStore(skin, storage), audioManager, "skin.ini") @@ -42,6 +42,13 @@ namespace osu.Game.Skinning Textures = new TextureStore(new TextureLoaderStore(storage)); } + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + Textures?.Dispose(); + Samples?.Dispose(); + } + public override Drawable GetDrawableComponent(string componentName) { switch (componentName) diff --git a/osu.Game/Tests/Visual/OsuTestScene.cs b/osu.Game/Tests/Visual/OsuTestScene.cs index 9b775fd498..806b73b517 100644 --- a/osu.Game/Tests/Visual/OsuTestScene.cs +++ b/osu.Game/Tests/Visual/OsuTestScene.cs @@ -19,7 +19,7 @@ namespace osu.Game.Tests.Visual { [Cached(typeof(Bindable))] [Cached(typeof(IBindable))] - private readonly OsuTestBeatmap beatmap = new OsuTestBeatmap(new DummyWorkingBeatmap()); + private readonly OsuTestBeatmap beatmap = new OsuTestBeatmap(new DummyWorkingBeatmap(), null); protected BindableBeatmap Beatmap => beatmap; @@ -52,8 +52,6 @@ namespace osu.Game.Tests.Visual [BackgroundDependencyLoader] private void load(AudioManager audioManager, RulesetStore rulesets) { - beatmap.SetAudioManager(audioManager); - Ruleset.Value = rulesets.AvailableRulesets.First(); } @@ -95,16 +93,14 @@ namespace osu.Game.Tests.Visual private class OsuTestBeatmap : BindableBeatmap { - public OsuTestBeatmap(WorkingBeatmap defaultValue) - : base(defaultValue) + public OsuTestBeatmap(WorkingBeatmap defaultValue, AudioManager audioManager) + : base(defaultValue, audioManager) { } - public void SetAudioManager(AudioManager audioManager) => RegisterAudioManager(audioManager); - public override BindableBeatmap GetBoundCopy() { - var copy = new OsuTestBeatmap(Default); + var copy = new OsuTestBeatmap(Default, AudioManager); copy.BindTo(this); return copy; }