mirror of
https://github.com/ppy/osu.git
synced 2025-01-12 17:43:05 +08:00
Merge pull request #15535 from peppy/remove-bass-track-ctor-usage
Rewrite `PreviewTrackManager` to avoid constructing `TrackBass` locally
This commit is contained in:
commit
baa5285b59
@ -13,10 +13,17 @@ namespace osu.Game.Tests.Visual.Components
|
|||||||
{
|
{
|
||||||
public class TestScenePreviewTrackManager : OsuTestScene, IPreviewTrackOwner
|
public class TestScenePreviewTrackManager : OsuTestScene, IPreviewTrackOwner
|
||||||
{
|
{
|
||||||
private readonly TestPreviewTrackManager trackManager = new TestPreviewTrackManager();
|
private readonly IAdjustableAudioComponent gameTrackAudio = new AudioAdjustments();
|
||||||
|
|
||||||
|
private readonly TestPreviewTrackManager trackManager;
|
||||||
|
|
||||||
private AudioManager audio;
|
private AudioManager audio;
|
||||||
|
|
||||||
|
public TestScenePreviewTrackManager()
|
||||||
|
{
|
||||||
|
trackManager = new TestPreviewTrackManager(gameTrackAudio);
|
||||||
|
}
|
||||||
|
|
||||||
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));
|
||||||
@ -151,19 +158,19 @@ namespace osu.Game.Tests.Visual.Components
|
|||||||
audio.VolumeTrack.Value = 1;
|
audio.VolumeTrack.Value = 1;
|
||||||
});
|
});
|
||||||
|
|
||||||
AddAssert("game not muted", () => audio.Tracks.AggregateVolume.Value != 0);
|
AddAssert("game not muted", () => gameTrackAudio.AggregateVolume.Value != 0);
|
||||||
|
|
||||||
AddStep("get track", () => Add(owner = new TestTrackOwner(track = getTrack())));
|
AddStep("get track", () => Add(owner = new TestTrackOwner(track = getTrack())));
|
||||||
AddUntilStep("wait loaded", () => track.IsLoaded);
|
AddUntilStep("wait loaded", () => track.IsLoaded);
|
||||||
AddStep("start track", () => track.Start());
|
AddStep("start track", () => track.Start());
|
||||||
AddAssert("game is muted", () => audio.Tracks.AggregateVolume.Value == 0);
|
AddAssert("game is muted", () => gameTrackAudio.AggregateVolume.Value == 0);
|
||||||
|
|
||||||
if (stopAnyPlaying)
|
if (stopAnyPlaying)
|
||||||
AddStep("stop any playing", () => trackManager.StopAnyPlaying(owner));
|
AddStep("stop any playing", () => trackManager.StopAnyPlaying(owner));
|
||||||
else
|
else
|
||||||
AddStep("stop track", () => track.Stop());
|
AddStep("stop track", () => track.Stop());
|
||||||
|
|
||||||
AddAssert("game not muted", () => audio.Tracks.AggregateVolume.Value != 0);
|
AddAssert("game not muted", () => gameTrackAudio.AggregateVolume.Value != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -224,6 +231,11 @@ namespace osu.Game.Tests.Visual.Components
|
|||||||
|
|
||||||
public new PreviewTrack CurrentTrack => base.CurrentTrack;
|
public new PreviewTrack CurrentTrack => base.CurrentTrack;
|
||||||
|
|
||||||
|
public TestPreviewTrackManager(IAdjustableAudioComponent mainTrackAdjustments)
|
||||||
|
: base(mainTrackAdjustments)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
protected override TrackManagerPreviewTrack CreatePreviewTrack(IBeatmapSetInfo beatmapSetInfo, ITrackStore trackStore) => new TestPreviewTrack(beatmapSetInfo, trackStore);
|
protected override TrackManagerPreviewTrack CreatePreviewTrack(IBeatmapSetInfo beatmapSetInfo, ITrackStore trackStore) => new TestPreviewTrack(beatmapSetInfo, trackStore);
|
||||||
|
|
||||||
public override bool UpdateSubTree()
|
public override bool UpdateSubTree()
|
||||||
|
@ -1,13 +1,8 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// 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.Allocation;
|
||||||
using osu.Framework.Audio;
|
using osu.Framework.Audio;
|
||||||
using osu.Framework.Audio.Mixing;
|
|
||||||
using osu.Framework.Audio.Track;
|
using osu.Framework.Audio.Track;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
@ -19,27 +14,26 @@ namespace osu.Game.Audio
|
|||||||
{
|
{
|
||||||
public class PreviewTrackManager : Component
|
public class PreviewTrackManager : Component
|
||||||
{
|
{
|
||||||
|
private readonly IAdjustableAudioComponent mainTrackAdjustments;
|
||||||
|
|
||||||
private readonly BindableDouble muteBindable = new BindableDouble();
|
private readonly BindableDouble muteBindable = new BindableDouble();
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private AudioManager audio { get; set; }
|
private AudioManager audio { get; set; }
|
||||||
|
|
||||||
private PreviewTrackStore trackStore;
|
private ITrackStore trackStore;
|
||||||
|
|
||||||
protected TrackManagerPreviewTrack CurrentTrack;
|
protected TrackManagerPreviewTrack CurrentTrack;
|
||||||
|
|
||||||
private readonly BindableNumber<double> globalTrackVolumeAdjust = new BindableNumber<double>(OsuGameBase.GLOBAL_TRACK_VOLUME_ADJUST);
|
public PreviewTrackManager(IAdjustableAudioComponent mainTrackAdjustments)
|
||||||
|
{
|
||||||
|
this.mainTrackAdjustments = mainTrackAdjustments;
|
||||||
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(AudioManager audioManager)
|
private void load(AudioManager audioManager)
|
||||||
{
|
{
|
||||||
// this is a temporary solution to get around muting ourselves.
|
trackStore = audioManager.GetTrackStore(new OnlineStore());
|
||||||
// todo: update this once we have a BackgroundTrackManager or similar.
|
|
||||||
trackStore = new PreviewTrackStore(audioManager.TrackMixer, new OnlineStore());
|
|
||||||
|
|
||||||
audio.AddItem(trackStore);
|
|
||||||
trackStore.AddAdjustment(AdjustableProperty.Volume, globalTrackVolumeAdjust);
|
|
||||||
trackStore.AddAdjustment(AdjustableProperty.Volume, audio.VolumeTrack);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -55,7 +49,7 @@ namespace osu.Game.Audio
|
|||||||
{
|
{
|
||||||
CurrentTrack?.Stop();
|
CurrentTrack?.Stop();
|
||||||
CurrentTrack = track;
|
CurrentTrack = track;
|
||||||
audio.Tracks.AddAdjustment(AdjustableProperty.Volume, muteBindable);
|
mainTrackAdjustments.AddAdjustment(AdjustableProperty.Volume, muteBindable);
|
||||||
});
|
});
|
||||||
|
|
||||||
track.Stopped += () => Schedule(() =>
|
track.Stopped += () => Schedule(() =>
|
||||||
@ -64,7 +58,7 @@ namespace osu.Game.Audio
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
CurrentTrack = null;
|
CurrentTrack = null;
|
||||||
audio.Tracks.RemoveAdjustment(AdjustableProperty.Volume, muteBindable);
|
mainTrackAdjustments.RemoveAdjustment(AdjustableProperty.Volume, muteBindable);
|
||||||
});
|
});
|
||||||
|
|
||||||
return track;
|
return track;
|
||||||
@ -116,52 +110,5 @@ namespace osu.Game.Audio
|
|||||||
|
|
||||||
protected override Track GetTrack() => trackManager.Get($"https://b.ppy.sh/preview/{beatmapSetInfo.OnlineID}.mp3");
|
protected override Track GetTrack() => trackManager.Get($"https://b.ppy.sh/preview/{beatmapSetInfo.OnlineID}.mp3");
|
||||||
}
|
}
|
||||||
|
|
||||||
private class PreviewTrackStore : AudioCollectionManager<AdjustableAudioComponent>, ITrackStore
|
|
||||||
{
|
|
||||||
private readonly AudioMixer defaultMixer;
|
|
||||||
private readonly IResourceStore<byte[]> store;
|
|
||||||
|
|
||||||
internal PreviewTrackStore(AudioMixer defaultMixer, IResourceStore<byte[]> store)
|
|
||||||
{
|
|
||||||
this.defaultMixer = defaultMixer;
|
|
||||||
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;
|
|
||||||
|
|
||||||
// Todo: This is quite unsafe. TrackBass shouldn't be exposed as public.
|
|
||||||
Track track = new TrackBass(dataStream);
|
|
||||||
|
|
||||||
defaultMixer.Add(track);
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,8 @@ using System.Threading;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using osu.Framework.Audio;
|
using osu.Framework.Audio;
|
||||||
|
using osu.Framework.Audio.Mixing;
|
||||||
|
using osu.Framework.Audio.Track;
|
||||||
using osu.Framework.IO.Stores;
|
using osu.Framework.IO.Stores;
|
||||||
using osu.Framework.Platform;
|
using osu.Framework.Platform;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
@ -30,18 +32,23 @@ namespace osu.Game.Beatmaps
|
|||||||
[ExcludeFromDynamicCompile]
|
[ExcludeFromDynamicCompile]
|
||||||
public class BeatmapManager : IModelDownloader<IBeatmapSetInfo>, IModelManager<BeatmapSetInfo>, IModelFileManager<BeatmapSetInfo, BeatmapSetFileInfo>, IModelImporter<BeatmapSetInfo>, IWorkingBeatmapCache, IDisposable
|
public class BeatmapManager : IModelDownloader<IBeatmapSetInfo>, IModelManager<BeatmapSetInfo>, IModelFileManager<BeatmapSetInfo, BeatmapSetFileInfo>, IModelImporter<BeatmapSetInfo>, IWorkingBeatmapCache, IDisposable
|
||||||
{
|
{
|
||||||
|
public ITrackStore BeatmapTrackStore { get; }
|
||||||
|
|
||||||
private readonly BeatmapModelManager beatmapModelManager;
|
private readonly BeatmapModelManager beatmapModelManager;
|
||||||
private readonly BeatmapModelDownloader beatmapModelDownloader;
|
private readonly BeatmapModelDownloader beatmapModelDownloader;
|
||||||
|
|
||||||
private readonly WorkingBeatmapCache workingBeatmapCache;
|
private readonly WorkingBeatmapCache workingBeatmapCache;
|
||||||
private readonly BeatmapOnlineLookupQueue onlineBeatmapLookupQueue;
|
private readonly BeatmapOnlineLookupQueue onlineBeatmapLookupQueue;
|
||||||
|
|
||||||
public BeatmapManager(Storage storage, IDatabaseContextFactory contextFactory, RulesetStore rulesets, IAPIProvider api, [NotNull] AudioManager audioManager, IResourceStore<byte[]> resources, GameHost host = null,
|
public BeatmapManager(Storage storage, IDatabaseContextFactory contextFactory, RulesetStore rulesets, IAPIProvider api, [NotNull] AudioManager audioManager, IResourceStore<byte[]> gameResources, GameHost host = null, WorkingBeatmap defaultBeatmap = null, bool performOnlineLookups = false, AudioMixer mainTrackMixer = null)
|
||||||
WorkingBeatmap defaultBeatmap = null, bool performOnlineLookups = false)
|
|
||||||
{
|
{
|
||||||
|
var userResources = new FileStore(contextFactory, storage).Store;
|
||||||
|
|
||||||
|
BeatmapTrackStore = audioManager.GetTrackStore(userResources);
|
||||||
|
|
||||||
beatmapModelManager = CreateBeatmapModelManager(storage, contextFactory, rulesets, api, host);
|
beatmapModelManager = CreateBeatmapModelManager(storage, contextFactory, rulesets, api, host);
|
||||||
beatmapModelDownloader = CreateBeatmapModelDownloader(beatmapModelManager, api, host);
|
beatmapModelDownloader = CreateBeatmapModelDownloader(beatmapModelManager, api, host);
|
||||||
workingBeatmapCache = CreateWorkingBeatmapCache(audioManager, resources, new FileStore(contextFactory, storage).Store, defaultBeatmap, host);
|
workingBeatmapCache = CreateWorkingBeatmapCache(audioManager, gameResources, userResources, defaultBeatmap, host);
|
||||||
|
|
||||||
workingBeatmapCache.BeatmapManager = beatmapModelManager;
|
workingBeatmapCache.BeatmapManager = beatmapModelManager;
|
||||||
beatmapModelManager.WorkingBeatmapCache = workingBeatmapCache;
|
beatmapModelManager.WorkingBeatmapCache = workingBeatmapCache;
|
||||||
@ -58,8 +65,10 @@ namespace osu.Game.Beatmaps
|
|||||||
return new BeatmapModelDownloader(modelManager, api, host);
|
return new BeatmapModelDownloader(modelManager, api, host);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual WorkingBeatmapCache CreateWorkingBeatmapCache(AudioManager audioManager, IResourceStore<byte[]> resources, IResourceStore<byte[]> storage, WorkingBeatmap defaultBeatmap, GameHost host) =>
|
protected virtual WorkingBeatmapCache CreateWorkingBeatmapCache(AudioManager audioManager, IResourceStore<byte[]> resources, IResourceStore<byte[]> storage, WorkingBeatmap defaultBeatmap, GameHost host)
|
||||||
new WorkingBeatmapCache(audioManager, resources, storage, defaultBeatmap, host);
|
{
|
||||||
|
return new WorkingBeatmapCache(BeatmapTrackStore, audioManager, resources, storage, defaultBeatmap, host);
|
||||||
|
}
|
||||||
|
|
||||||
protected virtual BeatmapModelManager CreateBeatmapModelManager(Storage storage, IDatabaseContextFactory contextFactory, RulesetStore rulesets, IAPIProvider api, GameHost host) =>
|
protected virtual BeatmapModelManager CreateBeatmapModelManager(Storage storage, IDatabaseContextFactory contextFactory, RulesetStore rulesets, IAPIProvider api, GameHost host) =>
|
||||||
new BeatmapModelManager(storage, contextFactory, rulesets, host);
|
new BeatmapModelManager(storage, contextFactory, rulesets, host);
|
||||||
|
@ -41,7 +41,7 @@ namespace osu.Game.Beatmaps
|
|||||||
[CanBeNull]
|
[CanBeNull]
|
||||||
private readonly GameHost host;
|
private readonly GameHost host;
|
||||||
|
|
||||||
public WorkingBeatmapCache([NotNull] AudioManager audioManager, IResourceStore<byte[]> resources, IResourceStore<byte[]> files, WorkingBeatmap defaultBeatmap = null, GameHost host = null)
|
public WorkingBeatmapCache(ITrackStore trackStore, AudioManager audioManager, IResourceStore<byte[]> resources, IResourceStore<byte[]> files, WorkingBeatmap defaultBeatmap = null, GameHost host = null)
|
||||||
{
|
{
|
||||||
DefaultBeatmap = defaultBeatmap;
|
DefaultBeatmap = defaultBeatmap;
|
||||||
|
|
||||||
@ -50,7 +50,7 @@ namespace osu.Game.Beatmaps
|
|||||||
this.host = host;
|
this.host = host;
|
||||||
this.files = files;
|
this.files = files;
|
||||||
largeTextureStore = new LargeTextureStore(host?.CreateTextureLoaderStore(files));
|
largeTextureStore = new LargeTextureStore(host?.CreateTextureLoaderStore(files));
|
||||||
trackStore = audioManager.GetTrackStore(files);
|
this.trackStore = trackStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Invalidate(BeatmapSetInfo info)
|
public void Invalidate(BeatmapSetInfo info)
|
||||||
|
@ -65,7 +65,7 @@ namespace osu.Game
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The maximum volume at which audio tracks should playback. This can be set lower than 1 to create some head-room for sound effects.
|
/// The maximum volume at which audio tracks should playback. This can be set lower than 1 to create some head-room for sound effects.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal const double GLOBAL_TRACK_VOLUME_ADJUST = 0.8;
|
private const double global_track_volume_adjust = 0.8;
|
||||||
|
|
||||||
public bool UseDevelopmentServer { get; }
|
public bool UseDevelopmentServer { get; }
|
||||||
|
|
||||||
@ -159,7 +159,7 @@ namespace osu.Game
|
|||||||
|
|
||||||
private Bindable<bool> fpsDisplayVisible;
|
private Bindable<bool> fpsDisplayVisible;
|
||||||
|
|
||||||
private readonly BindableNumber<double> globalTrackVolumeAdjust = new BindableNumber<double>(GLOBAL_TRACK_VOLUME_ADJUST);
|
private readonly BindableNumber<double> globalTrackVolumeAdjust = new BindableNumber<double>(global_track_volume_adjust);
|
||||||
|
|
||||||
private RealmRulesetStore realmRulesetStore;
|
private RealmRulesetStore realmRulesetStore;
|
||||||
|
|
||||||
@ -315,7 +315,7 @@ namespace osu.Game
|
|||||||
dependencies.Cache(globalBindings);
|
dependencies.Cache(globalBindings);
|
||||||
|
|
||||||
PreviewTrackManager previewTrackManager;
|
PreviewTrackManager previewTrackManager;
|
||||||
dependencies.Cache(previewTrackManager = new PreviewTrackManager());
|
dependencies.Cache(previewTrackManager = new PreviewTrackManager(BeatmapManager.BeatmapTrackStore));
|
||||||
Add(previewTrackManager);
|
Add(previewTrackManager);
|
||||||
|
|
||||||
AddInternal(MusicController = new MusicController());
|
AddInternal(MusicController = new MusicController());
|
||||||
|
@ -137,7 +137,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
private readonly TestBeatmapManager testBeatmapManager;
|
private readonly TestBeatmapManager testBeatmapManager;
|
||||||
|
|
||||||
public TestWorkingBeatmapCache(TestBeatmapManager testBeatmapManager, AudioManager audioManager, IResourceStore<byte[]> resourceStore, IResourceStore<byte[]> storage, WorkingBeatmap defaultBeatmap, GameHost gameHost)
|
public TestWorkingBeatmapCache(TestBeatmapManager testBeatmapManager, AudioManager audioManager, IResourceStore<byte[]> resourceStore, IResourceStore<byte[]> storage, WorkingBeatmap defaultBeatmap, GameHost gameHost)
|
||||||
: base(audioManager, resourceStore, storage, defaultBeatmap, gameHost)
|
: base(testBeatmapManager.BeatmapTrackStore, audioManager, resourceStore, storage, defaultBeatmap, gameHost)
|
||||||
{
|
{
|
||||||
this.testBeatmapManager = testBeatmapManager;
|
this.testBeatmapManager = testBeatmapManager;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user