Apply proposed changes to remove inheritance from MasterGameplayClockContainer

This commit is contained in:
Dean Herbert 2022-09-07 17:38:00 +09:00
parent 66c44f5913
commit 75d0deef72
7 changed files with 24 additions and 72 deletions

View File

@ -1,8 +1,9 @@
// 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.Collections.Generic;
using NUnit.Framework;
using osu.Framework.Audio;
using osu.Framework.Bindables;
using osu.Framework.Timing;
using osu.Game.Screens.Play;
@ -23,11 +24,10 @@ namespace osu.Game.Tests.NonVisual
private class TestGameplayClockContainer : GameplayClockContainer
{
public override IEnumerable<double> GameplayAdjustments => new[] { 2.0 };
public TestGameplayClockContainer(IFrameBasedClock underlyingClock)
: base(underlyingClock)
{
GameplayAdjustments.AddAdjustment(AdjustableProperty.Frequency, new BindableDouble(2.0));
}
}
}

View File

@ -2,10 +2,9 @@
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@ -264,7 +263,9 @@ namespace osu.Game.Rulesets.UI
public double StartTime => parentGameplayClock?.StartTime ?? 0;
public IEnumerable<double> GameplayAdjustments => parentGameplayClock?.GameplayAdjustments ?? Enumerable.Empty<double>();
private readonly AudioAdjustments gameplayAdjustments = new AudioAdjustments();
public IAdjustableAudioComponent GameplayAdjustments => parentGameplayClock?.GameplayAdjustments ?? gameplayAdjustments;
#endregion

View File

@ -2,9 +2,8 @@
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@ -45,7 +44,7 @@ namespace osu.Game.Screens.Play
/// </remarks>
public double StartTime { get; protected set; }
public virtual IEnumerable<double> GameplayAdjustments => Enumerable.Empty<double>();
public IAdjustableAudioComponent GameplayAdjustments { get; } = new AudioAdjustments();
private readonly BindableBool isPaused = new BindableBool(true);

View File

@ -13,10 +13,12 @@ namespace osu.Game.Screens.Play
/// </summary>
public static double GetTrueGameplayRate(this IGameplayClock clock)
{
// To handle rewind, we still want to maintain the same direction as the underlying clock.
double rate = Math.Sign(clock.Rate);
foreach (double a in clock.GameplayAdjustments)
rate *= a;
return rate;
return rate
* clock.GameplayAdjustments.AggregateFrequency.Value
* clock.GameplayAdjustments.AggregateTempo.Value;
}
}
}

View File

@ -1,7 +1,7 @@
// 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.Collections.Generic;
using osu.Framework.Audio;
using osu.Framework.Bindables;
using osu.Framework.Timing;
@ -19,9 +19,9 @@ namespace osu.Game.Screens.Play
double StartTime { get; }
/// <summary>
/// All adjustments applied to this clock which don't come from gameplay or mods.
/// All adjustments applied to this clock which come from gameplay or mods.
/// </summary>
IEnumerable<double> GameplayAdjustments { get; }
IAdjustableAudioComponent GameplayAdjustments { get; }
IBindable<bool> IsPaused { get; }
}

View File

@ -2,13 +2,11 @@
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Audio;
using osu.Framework.Audio.Track;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Timing;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
@ -25,7 +23,7 @@ namespace osu.Game.Screens.Play
/// <remarks>
/// This is intended to be used as a single controller for gameplay, or as a reference source for other <see cref="GameplayClockContainer"/>s.
/// </remarks>
public class MasterGameplayClockContainer : GameplayClockContainer, IBeatSyncProvider, IAdjustableAudioComponent
public class MasterGameplayClockContainer : GameplayClockContainer, IBeatSyncProvider
{
/// <summary>
/// Duration before gameplay start time required before skip button displays.
@ -57,11 +55,6 @@ namespace osu.Game.Screens.Play
/// </summary>
private double? actualStopTime;
/// <summary>
/// Maintained solely to delegate <see cref="IAdjustableAudioComponent"/> pieces to (to maintain parent lookups).
/// </summary>
private readonly AudioContainer audioContainer;
/// <summary>
/// Create a new master gameplay clock container.
/// </summary>
@ -75,8 +68,6 @@ namespace osu.Game.Screens.Play
this.skipTargetTime = skipTargetTime;
StartTime = findEarliestStartTime();
AddInternal(audioContainer = new AudioContainer());
}
private double findEarliestStartTime()
@ -202,6 +193,7 @@ namespace osu.Game.Screens.Play
if (speedAdjustmentsApplied)
return;
track.BindAdjustments(GameplayAdjustments);
track.AddAdjustment(AdjustableProperty.Frequency, GameplayClock.ExternalPauseFrequencyAdjust);
track.AddAdjustment(AdjustableProperty.Tempo, UserPlaybackRate);
@ -213,6 +205,7 @@ namespace osu.Game.Screens.Play
if (!speedAdjustmentsApplied)
return;
track.UnbindAdjustments(GameplayAdjustments);
track.RemoveAdjustment(AdjustableProperty.Frequency, GameplayClock.ExternalPauseFrequencyAdjust);
track.RemoveAdjustment(AdjustableProperty.Tempo, UserPlaybackRate);
@ -229,49 +222,5 @@ namespace osu.Game.Screens.Play
IClock IBeatSyncProvider.Clock => this;
ChannelAmplitudes IHasAmplitudes.CurrentAmplitudes => beatmap.TrackLoaded ? beatmap.Track.CurrentAmplitudes : ChannelAmplitudes.Empty;
private readonly List<IBindable<double>> speedAdjustments = new List<IBindable<double>>();
public override IEnumerable<double> GameplayAdjustments => speedAdjustments.Select(bindable => bindable.Value);
void IAdjustableAudioComponent.AddAdjustment(AdjustableProperty type, IBindable<double> adjustBindable)
{
speedAdjustments.Add(adjustBindable);
track.AddAdjustment(type, adjustBindable);
}
void IAdjustableAudioComponent.RemoveAdjustment(AdjustableProperty type, IBindable<double> adjustBindable)
{
speedAdjustments.Remove(adjustBindable);
track.RemoveAdjustment(type, adjustBindable);
}
void IAdjustableAudioComponent.RemoveAllAdjustments(AdjustableProperty type) => audioContainer.RemoveAllAdjustments(type);
void IAdjustableAudioComponent.BindAdjustments(IAggregateAudioAdjustment component) => audioContainer.BindAdjustments(component);
void IAdjustableAudioComponent.UnbindAdjustments(IAggregateAudioAdjustment component) => audioContainer.UnbindAdjustments(component);
BindableNumber<double> IAdjustableAudioComponent.Volume => audioContainer.Volume;
BindableNumber<double> IAdjustableAudioComponent.Balance => audioContainer.Balance;
BindableNumber<double> IAdjustableAudioComponent.Frequency => audioContainer.Frequency;
BindableNumber<double> IAdjustableAudioComponent.Tempo => audioContainer.Tempo;
public override void ResetSpeedAdjustments()
{
track.RemoveAllAdjustments(AdjustableProperty.Frequency);
track.RemoveAllAdjustments(AdjustableProperty.Tempo);
}
IBindable<double> IAggregateAudioAdjustment.AggregateVolume => audioContainer.AggregateVolume;
IBindable<double> IAggregateAudioAdjustment.AggregateBalance => audioContainer.AggregateBalance;
IBindable<double> IAggregateAudioAdjustment.AggregateFrequency => audioContainer.AggregateFrequency;
IBindable<double> IAggregateAudioAdjustment.AggregateTempo => audioContainer.AggregateTempo;
}
}

View File

@ -999,11 +999,12 @@ namespace osu.Game.Screens.Play
// Our mods are local copies of the global mods so they need to be re-applied to the track.
// This is done through the music controller (for now), because resetting speed adjustments on the beatmap track also removes adjustments provided by DrawableTrack.
// Todo: In the future, player will receive in a track and will probably not have to worry about this...
if (GameplayClockContainer is IAdjustableAudioComponent adjustableClock)
if (GameplayClockContainer is MasterGameplayClockContainer masterClock)
{
GameplayClockContainer.ResetSpeedAdjustments();
musicController.ResetTrackAdjustments();
foreach (var mod in GameplayState.Mods.OfType<IApplicableToTrack>())
mod.ApplyToTrack(adjustableClock);
mod.ApplyToTrack(masterClock.GameplayAdjustments);
}
updateGameplayState();