diff --git a/osu-framework b/osu-framework index c95b9350ed..887db793c7 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit c95b9350edb6305cfefdf08f902f6f73d336736b +Subproject commit 887db793c705b45071aea5e0c1cc931a7887165f diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 959e71d48d..1d4ed75688 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -28,16 +28,11 @@ namespace osu.Game.Beatmaps Metadata = beatmapInfo.Metadata ?? BeatmapSetInfo?.Metadata ?? new BeatmapMetadata(); Mods.ValueChanged += mods => applyRateAdjustments(); - } - private void applyRateAdjustments() - { - var t = track; - if (t == null) return; - - t.ResetSpeedAdjustments(); - foreach (var mod in Mods.Value.OfType()) - mod.ApplyToClock(t); + beatmap = new Lazy(populateBeatmap); + background = new Lazy(populateBackground); + track = new Lazy(populateTrack); + waveform = new Lazy(populateWaveform); } protected abstract Beatmap GetBeatmap(); @@ -45,98 +40,72 @@ namespace osu.Game.Beatmaps protected abstract Track GetTrack(); protected virtual Waveform GetWaveform() => new Waveform(); - private Beatmap beatmap; - private readonly object beatmapLock = new object(); - public Beatmap Beatmap + public bool BeatmapLoaded => beatmap.IsValueCreated; + public Beatmap Beatmap => beatmap.Value; + private readonly Lazy beatmap; + + private Beatmap populateBeatmap() { - get - { - lock (beatmapLock) - { - if (beatmap != null) return beatmap; + var b = GetBeatmap() ?? new Beatmap(); - beatmap = GetBeatmap() ?? new Beatmap(); + // use the database-backed info. + b.BeatmapInfo = BeatmapInfo; - // use the database-backed info. - beatmap.BeatmapInfo = BeatmapInfo; - - return beatmap; - } - } + return b; } - private readonly object backgroundLock = new object(); - private Texture background; - public Texture Background + public bool BackgroundLoaded => background.IsValueCreated; + public Texture Background => background.Value; + private Lazy background; + + private Texture populateBackground() => GetBackground(); + + public bool TrackLoaded => track.IsValueCreated; + public Track Track => track.Value; + private Lazy track; + + private Track populateTrack() { - get - { - lock (backgroundLock) - { - return background ?? (background = GetBackground()); - } - } + // we want to ensure that we always have a track, even if it's a fake one. + var t = GetTrack() ?? new TrackVirtual(); + applyRateAdjustments(t); + return t; } - private Track track; - private readonly object trackLock = new object(); - public Track Track - { - get - { - lock (trackLock) - { - if (track != null) return track; + public bool WaveformLoaded => waveform.IsValueCreated; + public Waveform Waveform => waveform.Value; + private readonly Lazy waveform; - // we want to ensure that we always have a track, even if it's a fake one. - track = GetTrack() ?? new TrackVirtual(); - - applyRateAdjustments(); - return track; - } - } - } - - private Waveform waveform; - private readonly object waveformLock = new object(); - public Waveform Waveform - { - get - { - lock (waveformLock) - return waveform ?? (waveform = GetWaveform()); - } - } - - public bool TrackLoaded => track != null; + private Waveform populateWaveform() => GetWaveform(); public void TransferTo(WorkingBeatmap other) { - lock (trackLock) - { - if (track != null && BeatmapInfo.AudioEquals(other.BeatmapInfo)) - other.track = track; - } + if (track.IsValueCreated && Track != null && BeatmapInfo.AudioEquals(other.BeatmapInfo)) + other.track = track; - if (background != null && BeatmapInfo.BackgroundEquals(other.BeatmapInfo)) + if (background.IsValueCreated && Background != null && BeatmapInfo.BackgroundEquals(other.BeatmapInfo)) other.background = background; } public virtual void Dispose() { - background?.Dispose(); - background = null; - - waveform?.Dispose(); + if (BackgroundLoaded) Background?.Dispose(); + if (WaveformLoaded) Waveform?.Dispose(); } public void DisposeTrack() { - lock (trackLock) - { - track?.Dispose(); - track = null; - } + if (TrackLoaded) Track?.Dispose(); + } + + private void applyRateAdjustments(Track t = null) + { + if (t == null && track.IsValueCreated) t = Track; + if (t == null) return; + + t.ResetSpeedAdjustments(); + foreach (var mod in Mods.Value.OfType()) + mod.ApplyToClock(t); } } } diff --git a/osu.Game/Graphics/Containers/BeatSyncedContainer.cs b/osu.Game/Graphics/Containers/BeatSyncedContainer.cs index 123ef0662d..fb85af12cb 100644 --- a/osu.Game/Graphics/Containers/BeatSyncedContainer.cs +++ b/osu.Game/Graphics/Containers/BeatSyncedContainer.cs @@ -35,9 +35,12 @@ namespace osu.Game.Graphics.Containers protected override void Update() { - var track = Beatmap.Value.Track; + if (!Beatmap.Value.TrackLoaded || !Beatmap.Value.BeatmapLoaded) return; - if (track == null) + var track = Beatmap.Value.Track; + var beatmap = Beatmap.Value.Beatmap; + + if (track == null || beatmap == null) return; double currentTrackTime = track.Length > 0 ? track.CurrentTime + EarlyActivationMilliseconds : Clock.CurrentTime;