1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-14 21:02:55 +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>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Diagnostics;
using JetBrains.Annotations;
using osu.Framework.Audio;
using osu.Framework.Audio.Track;
using osu.Framework.Configuration;
namespace osu.Game.Beatmaps
@ -11,18 +14,31 @@ namespace osu.Game.Beatmaps
/// A <see cref="Bindable{WorkingBeatmap}"/> for the <see cref="OsuGame"/> beatmap.
/// This should be used sparingly in-favour of <see cref="IGameBeatmap"/>.
/// </summary>
public class GameBeatmap : NonNullableBindable<WorkingBeatmap>, IGameBeatmap
public abstract class GameBeatmap : NonNullableBindable<WorkingBeatmap>, IGameBeatmap
{
private readonly AudioManager audioManager;
private AudioManager audioManager;
private WorkingBeatmap lastBeatmap;
public GameBeatmap(WorkingBeatmap defaultValue, AudioManager audioManager)
protected GameBeatmap(WorkingBeatmap 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;
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)
@ -46,17 +62,14 @@ namespace osu.Game.Beatmaps
lastBeatmap = beatmap;
}
[NotNull]
IGameBeatmap IGameBeatmap.GetBoundCopy() => GetBoundCopy();
/// <summary>
/// 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.
/// </summary>
public new GameBeatmap GetBoundCopy()
{
var copy = new GameBeatmap(Default, audioManager);
copy.BindTo(this);
return copy;
}
[NotNull]
public abstract GameBeatmap GetBoundCopy();
}
}

View File

@ -64,7 +64,8 @@ namespace osu.Game
protected override Container<Drawable> Content => content;
protected GameBeatmap Beatmap;
private OsuGameBeatmap beatmap;
protected GameBeatmap Beatmap => beatmap;
private Bindable<bool> fpsDisplayVisible;
@ -156,15 +157,15 @@ namespace osu.Game
Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Venera-Light"));
var defaultBeatmap = new DummyWorkingBeatmap(this);
Beatmap = new GameBeatmap(defaultBeatmap, Audio);
beatmap = new OsuGameBeatmap(defaultBeatmap, Audio);
BeatmapManager.DefaultBeatmap = defaultBeatmap;
// tracks play so loud our samples can't keep up.
// this adds a global reduction of track volume for the time being.
Audio.Track.AddAdjustment(AdjustableProperty.Volume, new BindableDouble(0.8));
dependencies.Cache(Beatmap);
dependencies.CacheAs<IGameBeatmap>(Beatmap);
dependencies.CacheAs<GameBeatmap>(beatmap);
dependencies.CacheAs<IGameBeatmap>(beatmap);
FileStore.Cleanup();
@ -235,5 +236,26 @@ namespace osu.Game
}
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
{
protected GameBeatmap Beatmap { get; private set; }
private readonly OsuTestBeatmap beatmap = new OsuTestBeatmap(new DummyWorkingBeatmap());
protected GameBeatmap Beatmap => beatmap;
private DependencyContainer dependencies;
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.CacheAs<IGameBeatmap>(Beatmap);
dependencies.Cache(Beatmap);
dependencies.CacheAs<GameBeatmap>(beatmap);
dependencies.CacheAs<IGameBeatmap>(beatmap);
return dependencies;
}
[BackgroundDependencyLoader]
private void load(AudioManager audioManager)
{
beatmap.SetAudioManager(audioManager);
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
if (Beatmap != null)
if (beatmap != null)
{
Beatmap.Disabled = true;
Beatmap.Value.Track.Stop();
beatmap.Disabled = true;
beatmap.Value.Track.Stop();
}
}
@ -58,5 +62,22 @@ namespace osu.Game.Tests.Visual
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;
}
}
}
}