From c968ccdf9a66fda4eae1aa93b4c6df29e613c052 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 12 Apr 2024 19:15:51 +0800 Subject: [PATCH 1/3] Log all seeks --- .../Skins/TestSceneBeatmapSkinResources.cs | 4 +- .../Visual/Audio/TestSceneAudioFilter.cs | 6 +- .../Editing/TestSceneEditorBeatmapCreation.cs | 2 +- .../Visual/Editing/TimelineTestScene.cs | 2 +- osu.Game/Beatmaps/IWorkingBeatmap.cs | 4 +- osu.Game/Beatmaps/WorkingBeatmap.cs | 163 +++++++++++++++++- osu.Game/Overlays/MusicController.cs | 2 +- .../Edit/Components/BottomBarContainer.cs | 2 +- .../Timelines/Summary/Parts/TimelinePart.cs | 8 +- .../Compose/Components/Timeline/Timeline.cs | 2 +- osu.Game/Screens/Edit/EditorClock.cs | 8 +- .../Edit/Timing/WaveformComparisonDisplay.cs | 4 +- .../Screens/Play/FailAnimationContainer.cs | 2 +- .../Play/MasterGameplayClockContainer.cs | 2 +- 14 files changed, 183 insertions(+), 28 deletions(-) diff --git a/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs b/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs index d9212386c34c..f004efbbff81 100644 --- a/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs +++ b/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs @@ -30,8 +30,8 @@ public void TestRetrieveOggAudio() AddAssert("sample is non-null", () => beatmap.Skin.GetSample(new SampleInfo(@"sample")) != null); AddAssert("track is non-null", () => { - using (var track = beatmap.LoadTrack()) - return track is not TrackVirtual; + using (var track = ((LoggingTrack)beatmap.LoadTrack())) + return track.UnderlyingTrack is not TrackVirtual; }); } diff --git a/osu.Game.Tests/Visual/Audio/TestSceneAudioFilter.cs b/osu.Game.Tests/Visual/Audio/TestSceneAudioFilter.cs index d96c19a13ef9..d75919c7f061 100644 --- a/osu.Game.Tests/Visual/Audio/TestSceneAudioFilter.cs +++ b/osu.Game.Tests/Visual/Audio/TestSceneAudioFilter.cs @@ -7,13 +7,13 @@ using NUnit.Framework; using osu.Framework.Allocation; 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.Graphics.Sprites; using osu.Framework.Testing; using osu.Game.Audio.Effects; +using osu.Game.Beatmaps; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; @@ -27,7 +27,7 @@ public partial class TestSceneAudioFilter : OsuTestScene private OsuSpriteText highPassText; private AudioFilter highPassFilter; - private Track track; + private LoggingTrack track; private WaveformTestBeatmap beatmap; @@ -38,7 +38,7 @@ public partial class TestSceneAudioFilter : OsuTestScene private void load(AudioManager audio) { beatmap = new WaveformTestBeatmap(audio); - track = beatmap.LoadTrack(); + track = (LoggingTrack)beatmap.LoadTrack(); Add(new FillFlowContainer { diff --git a/osu.Game.Tests/Visual/Editing/TestSceneEditorBeatmapCreation.cs b/osu.Game.Tests/Visual/Editing/TestSceneEditorBeatmapCreation.cs index db8798781564..a2c651e5502f 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneEditorBeatmapCreation.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneEditorBeatmapCreation.cs @@ -99,7 +99,7 @@ public void TestAddAudioTrack() AddUntilStep("wait for timeline load", () => Editor.ChildrenOfType().FirstOrDefault()?.IsLoaded == true); AddStep("enter setup mode", () => InputManager.Key(Key.F4)); - AddAssert("track is virtual", () => Beatmap.Value.Track is TrackVirtual); + AddAssert("track is virtual", () => ((LoggingTrack)Beatmap.Value.Track).UnderlyingTrack is TrackVirtual); AddAssert("switch track to real track", () => { var setup = Editor.ChildrenOfType().First(); diff --git a/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs b/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs index cb45ad5a076e..01910530f123 100644 --- a/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs +++ b/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs @@ -121,7 +121,7 @@ protected override void Update() { base.Update(); - if (beatmap.Value.Track.IsLoaded) + if (((LoggingTrack)beatmap.Value.Track).IsLoaded) marker.X = (float)(editorClock.CurrentTime / beatmap.Value.Track.Length); } } diff --git a/osu.Game/Beatmaps/IWorkingBeatmap.cs b/osu.Game/Beatmaps/IWorkingBeatmap.cs index bdfa6bdf6d46..ce30867170d4 100644 --- a/osu.Game/Beatmaps/IWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/IWorkingBeatmap.cs @@ -72,7 +72,7 @@ public interface IWorkingBeatmap /// /// Retrieves the which this has loaded. /// - Track Track { get; } + ITrack Track { get; } /// /// Constructs a playable from using the applicable converters for a specific . @@ -118,7 +118,7 @@ public interface IWorkingBeatmap /// outside of the game context. /// /// A fresh track instance, which will also be available via . - Track LoadTrack(); + ITrack LoadTrack(); /// /// Returns the stream of the file from the given storage path. diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 25159996f3d2..bb8ae6c7d24e 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -13,7 +13,9 @@ using JetBrains.Annotations; using osu.Framework.Audio; using osu.Framework.Audio.Track; +using osu.Framework.Bindables; using osu.Framework.Extensions; +using osu.Framework.Extensions.TypeExtensions; using osu.Framework.Graphics.Textures; using osu.Framework.Logging; using osu.Game.Rulesets; @@ -45,7 +47,7 @@ public abstract class WorkingBeatmap : IWorkingBeatmap private readonly Lazy storyboard; private readonly Lazy skin; - private Track track; // track is not Lazy as we allow transferring and loading multiple times. + private ITrack track; // track is not Lazy as we allow transferring and loading multiple times. private Waveform waveform; // waveform is also not Lazy as the track may change. protected WorkingBeatmap(BeatmapInfo beatmapInfo, AudioManager audioManager) @@ -103,9 +105,9 @@ public void CancelAsyncLoad() public virtual bool TrackLoaded => track != null; - public Track LoadTrack() + public ITrack LoadTrack() { - track = GetBeatmapTrack() ?? GetVirtualTrack(1000); + track = new LoggingTrack(GetBeatmapTrack() ?? GetVirtualTrack(1000)); // the track may have changed, recycle the current waveform. waveform?.Dispose(); @@ -121,7 +123,7 @@ public void PrepareTrackForPreview(bool looping, double offsetFromPreviewPoint = if (Track.RestartPoint == -1) { - if (!Track.IsLoaded) + if (!((LoggingTrack)Track).IsLoaded) { // force length to be populated (https://github.com/ppy/osu-framework/issues/4202) Track.Seek(Track.CurrentTime); @@ -153,7 +155,7 @@ public virtual bool TryTransferTrack([NotNull] WorkingBeatmap target) /// This generally happens via MusicController when changing the global beatmap. /// [NotNull] - public Track Track + public ITrack Track { get { @@ -353,4 +355,155 @@ public BeatmapLoadTimeoutException(BeatmapInfo beatmapInfo) } } } + + internal class LoggingTrack : ITrack, IDisposable + { + public readonly Track UnderlyingTrack; + + public LoggingTrack(Track underlyingTrack) + { + UnderlyingTrack = underlyingTrack; + } + + public double CurrentTime => UnderlyingTrack.CurrentTime; + + public void Reset() + { + UnderlyingTrack.Reset(); + } + + public void Start() + { + UnderlyingTrack.Start(); + } + + public void Stop() + { + UnderlyingTrack.Stop(); + } + + public bool Seek(double position) + { + Logger.Log($"{nameof(Seek)} on {UnderlyingTrack.GetType().ReadableName()} from {UnderlyingTrack.CurrentTime:N2} to {position:N2}"); + return UnderlyingTrack.Seek(position); + } + + public void ResetSpeedAdjustments() + { + UnderlyingTrack.ResetSpeedAdjustments(); + } + + public double Rate + { + get => UnderlyingTrack.Rate; + set => UnderlyingTrack.Rate = value; + } + + public bool IsRunning => UnderlyingTrack.IsRunning; + + public ChannelAmplitudes CurrentAmplitudes => UnderlyingTrack.CurrentAmplitudes; + + public IBindable AggregateVolume => UnderlyingTrack.AggregateVolume; + + IBindable IAggregateAudioAdjustment.AggregateVolume => UnderlyingTrack.AggregateVolume; + + public IBindable AggregateBalance => UnderlyingTrack.AggregateBalance; + + public IBindable AggregateFrequency => UnderlyingTrack.AggregateFrequency; + + public IBindable AggregateTempo => UnderlyingTrack.AggregateTempo; + + public void BindAdjustments(IAggregateAudioAdjustment component) + { + UnderlyingTrack.BindAdjustments(component); + } + + public void UnbindAdjustments(IAggregateAudioAdjustment component) + { + UnderlyingTrack.UnbindAdjustments(component); + } + + void IAdjustableAudioComponent.AddAdjustment(AdjustableProperty type, IBindable adjustBindable) + { + UnderlyingTrack.AddAdjustment(type, adjustBindable); + } + + void IAdjustableAudioComponent.RemoveAdjustment(AdjustableProperty type, IBindable adjustBindable) + { + UnderlyingTrack.RemoveAdjustment(type, adjustBindable); + } + + public void AddAdjustment(AdjustableProperty type, IBindable adjustBindable) + { + UnderlyingTrack.AddAdjustment(type, adjustBindable); + } + + public void RemoveAdjustment(AdjustableProperty type, IBindable adjustBindable) + { + UnderlyingTrack.RemoveAdjustment(type, adjustBindable); + } + + public void RemoveAllAdjustments(AdjustableProperty type) + { + UnderlyingTrack.RemoveAllAdjustments(type); + } + + public BindableNumber Volume => UnderlyingTrack.Volume; + + public BindableNumber Balance => UnderlyingTrack.Balance; + + public BindableNumber Frequency => UnderlyingTrack.Frequency; + + public BindableNumber Tempo => UnderlyingTrack.Tempo; + + public void Restart() + { + UnderlyingTrack.Restart(); + } + + public bool Looping + { + get => UnderlyingTrack.Looping; + set => UnderlyingTrack.Looping = value; + } + + public bool IsDummyDevice => UnderlyingTrack.IsDummyDevice; + + public double RestartPoint + { + get => UnderlyingTrack.RestartPoint; + set => UnderlyingTrack.RestartPoint = value; + } + + public double Length + { + get => UnderlyingTrack.Length; + set => UnderlyingTrack.Length = value; + } + + public int? Bitrate => UnderlyingTrack.Bitrate; + + public bool IsReversed => UnderlyingTrack.IsReversed; + + public bool HasCompleted => UnderlyingTrack.HasCompleted; + + public bool IsLoaded => UnderlyingTrack.IsLoaded; + + public event Action Completed + { + add => UnderlyingTrack.Completed += value; + remove => UnderlyingTrack.Completed -= value; + } + + public event Action Failed + { + add => UnderlyingTrack.Failed += value; + remove => UnderlyingTrack.Failed -= value; + } + + public void Dispose() + { + UnderlyingTrack.Dispose(); + } + } } diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 0986c0513ca8..01739d434119 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -361,7 +361,7 @@ private DrawableTrack getQueuedTrack() { // Important to keep this in its own method to avoid inadvertently capturing unnecessary variables in the callback. // Can lead to leaks. - var queuedTrack = new DrawableTrack(current.LoadTrack()); + var queuedTrack = new DrawableTrack(((LoggingTrack)current.LoadTrack()).UnderlyingTrack); queuedTrack.Completed += onTrackCompleted; return queuedTrack; } diff --git a/osu.Game/Screens/Edit/Components/BottomBarContainer.cs b/osu.Game/Screens/Edit/Components/BottomBarContainer.cs index 0ba1ab925840..e01e6becd6da 100644 --- a/osu.Game/Screens/Edit/Components/BottomBarContainer.cs +++ b/osu.Game/Screens/Edit/Components/BottomBarContainer.cs @@ -18,7 +18,7 @@ public partial class BottomBarContainer : Container protected readonly IBindable Beatmap = new Bindable(); - protected readonly IBindable Track = new Bindable(); + protected readonly IBindable Track = new Bindable(); protected readonly Drawable Background; private readonly Container content; diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs index ee7e759ebced..493070d9a9f5 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs @@ -26,7 +26,7 @@ public partial class TimelinePart : Container where T : Drawable [Resolved] protected EditorBeatmap EditorBeatmap { get; private set; } = null!; - protected readonly IBindable Track = new Bindable(); + protected readonly IBindable Track = new Bindable(); private readonly Container content; @@ -56,11 +56,13 @@ private void load(IBindable beatmap, EditorClock clock) private void updateRelativeChildSize() { // If the track is not loaded, assign a default sane length otherwise relative positioning becomes meaningless. - double trackLength = beatmap.Value.Track.IsLoaded ? beatmap.Value.Track.Length : 60000; + var track = (LoggingTrack)beatmap.Value.Track; + + double trackLength = track.IsLoaded ? track.Length : 60000; content.RelativeChildSize = new Vector2((float)Math.Max(1, trackLength), 1); // The track may not be loaded completely (only has a length once it is). - if (!beatmap.Value.Track.IsLoaded) + if (!track.IsLoaded) Schedule(updateRelativeChildSize); } diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs index a2704e550c8e..3ee0183fd237 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs @@ -91,7 +91,7 @@ public Timeline(Drawable userContent) private double trackLengthForZoom; - private readonly IBindable track = new Bindable(); + private readonly IBindable track = new Bindable(); [BackgroundDependencyLoader] private void load(IBindable beatmap, OsuColour colours, OsuConfigManager config) diff --git a/osu.Game/Screens/Edit/EditorClock.cs b/osu.Game/Screens/Edit/EditorClock.cs index d5ca6fc35e46..cd0025965661 100644 --- a/osu.Game/Screens/Edit/EditorClock.cs +++ b/osu.Game/Screens/Edit/EditorClock.cs @@ -23,11 +23,11 @@ namespace osu.Game.Screens.Edit /// public partial class EditorClock : CompositeComponent, IFrameBasedClock, IAdjustableClock, ISourceChangeableClock { - public IBindable Track => track; + public IBindable Track => track; - private readonly Bindable track = new Bindable(); + private readonly Bindable track = new Bindable(); - public double TrackLength => track.Value?.IsLoaded == true ? track.Value.Length : 60000; + public double TrackLength => (track.Value as LoggingTrack)?.IsLoaded == true ? track.Value.Length : 60000; public ControlPointInfo ControlPointInfo => Beatmap.ControlPointInfo; @@ -231,7 +231,7 @@ public void ProcessFrame() public void ChangeSource(IClock source) { - track.Value = source as Track; + track.Value = source as ITrack; underlyingClock.ChangeSource(source); } diff --git a/osu.Game/Screens/Edit/Timing/WaveformComparisonDisplay.cs b/osu.Game/Screens/Edit/Timing/WaveformComparisonDisplay.cs index 45213b7bdb46..081dcc752052 100644 --- a/osu.Game/Screens/Edit/Timing/WaveformComparisonDisplay.cs +++ b/osu.Game/Screens/Edit/Timing/WaveformComparisonDisplay.cs @@ -192,7 +192,7 @@ private void showFromTime(double time, bool animated) private void regenerateDisplay(bool animated) { // Before a track is loaded, it won't have a valid length, which will break things. - if (!beatmap.Value.Track.IsLoaded) + if (!((LoggingTrack)beatmap.Value.Track).IsLoaded) { Scheduler.AddOnce(regenerateDisplay, animated); return; @@ -305,7 +305,7 @@ internal partial class WaveformRow : CompositeDrawable [Resolved] private IBindable beatmap { get; set; } = null!; - private readonly IBindable track = new Bindable(); + private readonly IBindable track = new Bindable(); public WaveformRow(bool isMainRow) { diff --git a/osu.Game/Screens/Play/FailAnimationContainer.cs b/osu.Game/Screens/Play/FailAnimationContainer.cs index ebb0d7772620..d0c38cfe05e7 100644 --- a/osu.Game/Screens/Play/FailAnimationContainer.cs +++ b/osu.Game/Screens/Play/FailAnimationContainer.cs @@ -42,7 +42,7 @@ public partial class FailAnimationContainer : Container private Box redFlashLayer = null!; - private Track track = null!; + private ITrack track = null!; private AudioFilter failLowPassFilter = null!; private AudioFilter failHighPassFilter = null!; diff --git a/osu.Game/Screens/Play/MasterGameplayClockContainer.cs b/osu.Game/Screens/Play/MasterGameplayClockContainer.cs index b2f0ae5561c8..0bcc2a9ab5c3 100644 --- a/osu.Game/Screens/Play/MasterGameplayClockContainer.cs +++ b/osu.Game/Screens/Play/MasterGameplayClockContainer.cs @@ -55,7 +55,7 @@ public partial class MasterGameplayClockContainer : GameplayClockContainer, IBea private readonly WorkingBeatmap beatmap; - private Track track; + private ITrack track; private readonly double skipTargetTime; From fcf4404430fe49ad618ad7cfea7d6735c086ff2a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 12 Apr 2024 20:21:49 +0800 Subject: [PATCH 2/3] Use extension methods to clean up code --- .../Skins/TestSceneBeatmapSkinResources.cs | 4 +-- .../Visual/Audio/TestSceneAudioFilter.cs | 5 +-- .../Editing/TestSceneEditorBeatmapCreation.cs | 2 +- .../Visual/Editing/TimelineTestScene.cs | 2 +- osu.Game/Beatmaps/WorkingBeatmap.cs | 33 ++++++++++++++++++- osu.Game/Overlays/MusicController.cs | 2 +- .../Timelines/Summary/Parts/TimelinePart.cs | 2 +- osu.Game/Screens/Edit/EditorClock.cs | 2 +- .../Edit/Timing/WaveformComparisonDisplay.cs | 2 +- 9 files changed, 43 insertions(+), 11 deletions(-) diff --git a/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs b/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs index f004efbbff81..78721f1525bc 100644 --- a/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs +++ b/osu.Game.Tests/Skins/TestSceneBeatmapSkinResources.cs @@ -30,8 +30,8 @@ public void TestRetrieveOggAudio() AddAssert("sample is non-null", () => beatmap.Skin.GetSample(new SampleInfo(@"sample")) != null); AddAssert("track is non-null", () => { - using (var track = ((LoggingTrack)beatmap.LoadTrack())) - return track.UnderlyingTrack is not TrackVirtual; + using (var track = beatmap.LoadTrack().GetUnderlyingTrack()) + return track is not TrackVirtual; }); } diff --git a/osu.Game.Tests/Visual/Audio/TestSceneAudioFilter.cs b/osu.Game.Tests/Visual/Audio/TestSceneAudioFilter.cs index d75919c7f061..2dc1cbe43c7e 100644 --- a/osu.Game.Tests/Visual/Audio/TestSceneAudioFilter.cs +++ b/osu.Game.Tests/Visual/Audio/TestSceneAudioFilter.cs @@ -7,6 +7,7 @@ using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Audio; +using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -27,7 +28,7 @@ public partial class TestSceneAudioFilter : OsuTestScene private OsuSpriteText highPassText; private AudioFilter highPassFilter; - private LoggingTrack track; + private Track track; private WaveformTestBeatmap beatmap; @@ -38,7 +39,7 @@ public partial class TestSceneAudioFilter : OsuTestScene private void load(AudioManager audio) { beatmap = new WaveformTestBeatmap(audio); - track = (LoggingTrack)beatmap.LoadTrack(); + track = beatmap.LoadTrack().GetUnderlyingTrack(); Add(new FillFlowContainer { diff --git a/osu.Game.Tests/Visual/Editing/TestSceneEditorBeatmapCreation.cs b/osu.Game.Tests/Visual/Editing/TestSceneEditorBeatmapCreation.cs index a2c651e5502f..9841b103cecc 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneEditorBeatmapCreation.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneEditorBeatmapCreation.cs @@ -99,7 +99,7 @@ public void TestAddAudioTrack() AddUntilStep("wait for timeline load", () => Editor.ChildrenOfType().FirstOrDefault()?.IsLoaded == true); AddStep("enter setup mode", () => InputManager.Key(Key.F4)); - AddAssert("track is virtual", () => ((LoggingTrack)Beatmap.Value.Track).UnderlyingTrack is TrackVirtual); + AddAssert("track is virtual", () => Beatmap.Value.Track.GetUnderlyingTrack() is TrackVirtual); AddAssert("switch track to real track", () => { var setup = Editor.ChildrenOfType().First(); diff --git a/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs b/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs index 01910530f123..7d85237b6aa8 100644 --- a/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs +++ b/osu.Game.Tests/Visual/Editing/TimelineTestScene.cs @@ -121,7 +121,7 @@ protected override void Update() { base.Update(); - if (((LoggingTrack)beatmap.Value.Track).IsLoaded) + if (beatmap.Value.Track.IsLoaded()) marker.X = (float)(editorClock.CurrentTime / beatmap.Value.Track.Length); } } diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index bb8ae6c7d24e..bd3658a970fc 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -123,7 +123,7 @@ public void PrepareTrackForPreview(bool looping, double offsetFromPreviewPoint = if (Track.RestartPoint == -1) { - if (!((LoggingTrack)Track).IsLoaded) + if (!Track.IsLoaded()) { // force length to be populated (https://github.com/ppy/osu-framework/issues/4202) Track.Seek(Track.CurrentTime); @@ -356,6 +356,37 @@ public BeatmapLoadTimeoutException(BeatmapInfo beatmapInfo) } } + /// + /// Temporary helper extension methods to aid in using with minimal code damage. + /// + internal static class TrackExtensions + { + public static Track GetUnderlyingTrack(this ITrack track) + { + if (track is Track t) + return t; + + if (track is LoggingTrack lt) + return lt.UnderlyingTrack; + + return null; + } + + public static bool IsLoaded(this ITrack track) + { + if (track is Track t) + return t.IsLoaded; + + if (track is LoggingTrack lt) + return lt.UnderlyingTrack.IsLoaded; + + return false; + } + } + + /// + /// Temporary redirect class for logging purposes. + /// internal class LoggingTrack : ITrack, IDisposable { public readonly Track UnderlyingTrack; diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 01739d434119..499ae0c3dec4 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -361,7 +361,7 @@ private DrawableTrack getQueuedTrack() { // Important to keep this in its own method to avoid inadvertently capturing unnecessary variables in the callback. // Can lead to leaks. - var queuedTrack = new DrawableTrack(((LoggingTrack)current.LoadTrack()).UnderlyingTrack); + var queuedTrack = new DrawableTrack(current.LoadTrack().GetUnderlyingTrack()); queuedTrack.Completed += onTrackCompleted; return queuedTrack; } diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs index 493070d9a9f5..347153ea72f3 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs @@ -56,7 +56,7 @@ private void load(IBindable beatmap, EditorClock clock) private void updateRelativeChildSize() { // If the track is not loaded, assign a default sane length otherwise relative positioning becomes meaningless. - var track = (LoggingTrack)beatmap.Value.Track; + var track = beatmap.Value.Track.GetUnderlyingTrack(); double trackLength = track.IsLoaded ? track.Length : 60000; content.RelativeChildSize = new Vector2((float)Math.Max(1, trackLength), 1); diff --git a/osu.Game/Screens/Edit/EditorClock.cs b/osu.Game/Screens/Edit/EditorClock.cs index cd0025965661..101d587678c5 100644 --- a/osu.Game/Screens/Edit/EditorClock.cs +++ b/osu.Game/Screens/Edit/EditorClock.cs @@ -27,7 +27,7 @@ public partial class EditorClock : CompositeComponent, IFrameBasedClock, IAdjust private readonly Bindable track = new Bindable(); - public double TrackLength => (track.Value as LoggingTrack)?.IsLoaded == true ? track.Value.Length : 60000; + public double TrackLength => track.Value?.IsLoaded() == true ? track.Value.Length : 60000; public ControlPointInfo ControlPointInfo => Beatmap.ControlPointInfo; diff --git a/osu.Game/Screens/Edit/Timing/WaveformComparisonDisplay.cs b/osu.Game/Screens/Edit/Timing/WaveformComparisonDisplay.cs index 081dcc752052..d8f88cd5ace4 100644 --- a/osu.Game/Screens/Edit/Timing/WaveformComparisonDisplay.cs +++ b/osu.Game/Screens/Edit/Timing/WaveformComparisonDisplay.cs @@ -192,7 +192,7 @@ private void showFromTime(double time, bool animated) private void regenerateDisplay(bool animated) { // Before a track is loaded, it won't have a valid length, which will break things. - if (!((LoggingTrack)beatmap.Value.Track).IsLoaded) + if (beatmap.Value.Track.IsLoaded()) { Scheduler.AddOnce(regenerateDisplay, animated); return; From 482288983c9f7577cae4b69ced4437ae572c75c4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 12 Apr 2024 21:03:05 +0800 Subject: [PATCH 3/3] Fix back-to-front comparison --- osu.Game/Screens/Edit/Timing/WaveformComparisonDisplay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Timing/WaveformComparisonDisplay.cs b/osu.Game/Screens/Edit/Timing/WaveformComparisonDisplay.cs index d8f88cd5ace4..3cadf8e6e637 100644 --- a/osu.Game/Screens/Edit/Timing/WaveformComparisonDisplay.cs +++ b/osu.Game/Screens/Edit/Timing/WaveformComparisonDisplay.cs @@ -192,7 +192,7 @@ private void showFromTime(double time, bool animated) private void regenerateDisplay(bool animated) { // Before a track is loaded, it won't have a valid length, which will break things. - if (beatmap.Value.Track.IsLoaded()) + if (!beatmap.Value.Track.IsLoaded()) { Scheduler.AddOnce(regenerateDisplay, animated); return;