1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-15 00:53:22 +08:00

Make GameBeatmap late-bind its AudioManager for ctor Beatmap access

This commit is contained in:
smoogipoo 2018-05-28 17:55:41 +09:00
parent 7961c56239
commit 3a5228af43
3 changed files with 79 additions and 23 deletions

View File

@ -1,8 +1,11 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>. // Copyright (c) 2007-2018 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;
using System.Diagnostics; using System.Diagnostics;
using JetBrains.Annotations;
using osu.Framework.Audio; using osu.Framework.Audio;
using osu.Framework.Audio.Track;
using osu.Framework.Configuration; using osu.Framework.Configuration;
namespace osu.Game.Beatmaps namespace osu.Game.Beatmaps
@ -11,18 +14,31 @@ namespace osu.Game.Beatmaps
/// A <see cref="Bindable{WorkingBeatmap}"/> for the <see cref="OsuGame"/> beatmap. /// A <see cref="Bindable{WorkingBeatmap}"/> for the <see cref="OsuGame"/> beatmap.
/// This should be used sparingly in-favour of <see cref="IGameBeatmap"/>. /// This should be used sparingly in-favour of <see cref="IGameBeatmap"/>.
/// </summary> /// </summary>
public class GameBeatmap : NonNullableBindable<WorkingBeatmap>, IGameBeatmap public abstract class GameBeatmap : NonNullableBindable<WorkingBeatmap>, IGameBeatmap
{ {
private readonly AudioManager audioManager; private AudioManager audioManager;
private WorkingBeatmap lastBeatmap; private WorkingBeatmap lastBeatmap;
public GameBeatmap(WorkingBeatmap defaultValue, AudioManager audioManager) protected GameBeatmap(WorkingBeatmap defaultValue)
: base(defaultValue) : base(defaultValue)
{ {
}
/// <summary>
/// Registers an <see cref="AudioManager"/> for <see cref="Track"/>s to be added to.
/// </summary>
/// <param name="audioManager">The <see cref="AudioManager"/>.</param>
protected void RegisterAudioManager([NotNull] AudioManager audioManager)
{
if (this.audioManager != null) throw new InvalidOperationException($"Cannot register multiple {nameof(AudioManager)}s.");
this.audioManager = audioManager; this.audioManager = audioManager;
ValueChanged += registerAudioTrack; ValueChanged += registerAudioTrack;
// 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 registerAudioTrack(WorkingBeatmap beatmap)
@ -46,17 +62,14 @@ namespace osu.Game.Beatmaps
lastBeatmap = beatmap; lastBeatmap = beatmap;
} }
[NotNull]
IGameBeatmap IGameBeatmap.GetBoundCopy() => GetBoundCopy(); IGameBeatmap IGameBeatmap.GetBoundCopy() => GetBoundCopy();
/// <summary> /// <summary>
/// Retrieve a new <see cref="GameBeatmap"/> instance weakly bound to this <see cref="GameBeatmap"/>. /// Retrieve a new <see cref="GameBeatmap"/> instance weakly bound to this <see cref="GameBeatmap"/>.
/// If you are further binding to events of the retrieved <see cref="GameBeatmap"/>, ensure a local reference is held. /// If you are further binding to events of the retrieved <see cref="GameBeatmap"/>, ensure a local reference is held.
/// </summary> /// </summary>
public new GameBeatmap GetBoundCopy() [NotNull]
{ public abstract GameBeatmap GetBoundCopy();
var copy = new GameBeatmap(Default, audioManager);
copy.BindTo(this);
return copy;
}
} }
} }

View File

@ -64,7 +64,8 @@ namespace osu.Game
protected override Container<Drawable> Content => content; protected override Container<Drawable> Content => content;
protected GameBeatmap Beatmap; private OsuGameBeatmap beatmap;
protected GameBeatmap Beatmap => beatmap;
private Bindable<bool> fpsDisplayVisible; private Bindable<bool> fpsDisplayVisible;
@ -156,15 +157,15 @@ namespace osu.Game
Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Venera-Light")); Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Venera-Light"));
var defaultBeatmap = new DummyWorkingBeatmap(this); var defaultBeatmap = new DummyWorkingBeatmap(this);
Beatmap = new GameBeatmap(defaultBeatmap, Audio); beatmap = new OsuGameBeatmap(defaultBeatmap, Audio);
BeatmapManager.DefaultBeatmap = defaultBeatmap; BeatmapManager.DefaultBeatmap = defaultBeatmap;
// tracks play so loud our samples can't keep up. // tracks play so loud our samples can't keep up.
// this adds a global reduction of track volume for the time being. // this adds a global reduction of track volume for the time being.
Audio.Track.AddAdjustment(AdjustableProperty.Volume, new BindableDouble(0.8)); Audio.Track.AddAdjustment(AdjustableProperty.Volume, new BindableDouble(0.8));
dependencies.Cache(Beatmap); dependencies.CacheAs<GameBeatmap>(beatmap);
dependencies.CacheAs<IGameBeatmap>(Beatmap); dependencies.CacheAs<IGameBeatmap>(beatmap);
FileStore.Cleanup(); FileStore.Cleanup();
@ -235,5 +236,26 @@ namespace osu.Game
} }
public string[] HandledExtensions => fileImporters.SelectMany(i => i.HandledExtensions).ToArray(); public string[] HandledExtensions => fileImporters.SelectMany(i => i.HandledExtensions).ToArray();
private class OsuGameBeatmap : GameBeatmap
{
public OsuGameBeatmap(WorkingBeatmap defaultValue, AudioManager audioManager)
: this(defaultValue)
{
RegisterAudioManager(audioManager);
}
private OsuGameBeatmap(WorkingBeatmap defaultValue)
: base(defaultValue)
{
}
public override GameBeatmap GetBoundCopy()
{
var copy = new OsuGameBeatmap(Default);
copy.BindTo(this);
return copy;
}
}
} }
} }

View File

@ -12,31 +12,35 @@ namespace osu.Game.Tests.Visual
{ {
public abstract class OsuTestCase : TestCase public abstract class OsuTestCase : TestCase
{ {
protected GameBeatmap Beatmap { get; private set; } private readonly OsuTestBeatmap beatmap = new OsuTestBeatmap(new DummyWorkingBeatmap());
protected GameBeatmap Beatmap => beatmap;
private DependencyContainer dependencies; private DependencyContainer dependencies;
protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent)
{ {
// The beatmap is constructed here rather than load() because our children get dependencies injected before our load() runs
Beatmap = new GameBeatmap(new DummyWorkingBeatmap(), parent.Get<AudioManager>());
dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); dependencies = new DependencyContainer(base.CreateLocalDependencies(parent));
dependencies.CacheAs<IGameBeatmap>(Beatmap); dependencies.CacheAs<GameBeatmap>(beatmap);
dependencies.Cache(Beatmap); dependencies.CacheAs<IGameBeatmap>(beatmap);
return dependencies; return dependencies;
} }
[BackgroundDependencyLoader]
private void load(AudioManager audioManager)
{
beatmap.SetAudioManager(audioManager);
}
protected override void Dispose(bool isDisposing) protected override void Dispose(bool isDisposing)
{ {
base.Dispose(isDisposing); base.Dispose(isDisposing);
if (Beatmap != null) if (beatmap != null)
{ {
Beatmap.Disabled = true; beatmap.Disabled = true;
Beatmap.Value.Track.Stop(); beatmap.Value.Track.Stop();
} }
} }
@ -58,5 +62,22 @@ namespace osu.Game.Tests.Visual
public void RunTestBlocking(TestCase test) => runner.RunTestBlocking(test); public void RunTestBlocking(TestCase test) => runner.RunTestBlocking(test);
} }
private class OsuTestBeatmap : GameBeatmap
{
public OsuTestBeatmap(WorkingBeatmap defaultValue)
: base(defaultValue)
{
}
public void SetAudioManager(AudioManager audioManager) => RegisterAudioManager(audioManager);
public override GameBeatmap GetBoundCopy()
{
var copy = new OsuTestBeatmap(Default);
copy.BindTo(this);
return copy;
}
}
} }
} }