// Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Framework.Audio.Track; using osu.Framework.Configuration; using osu.Framework.Graphics.Textures; using osu.Game.Rulesets.Mods; using System; using System.Collections.Generic; using System.Linq; namespace osu.Game.Beatmaps { public abstract class WorkingBeatmap : IDisposable { public readonly BeatmapInfo BeatmapInfo; public readonly BeatmapSetInfo BeatmapSetInfo; public readonly BeatmapMetadata Metadata; public readonly Bindable> Mods = new Bindable>(new Mod[] { }); protected WorkingBeatmap(BeatmapInfo beatmapInfo) { BeatmapInfo = beatmapInfo; BeatmapSetInfo = beatmapInfo.BeatmapSet; Metadata = beatmapInfo.Metadata ?? BeatmapSetInfo?.Metadata ?? new BeatmapMetadata(); Mods.ValueChanged += mods => applyRateAdjustments(); beatmap = new Lazy(populateBeatmap); background = new Lazy(populateBackground); track = new Lazy(populateTrack); waveform = new Lazy(populateWaveform); } protected abstract Beatmap GetBeatmap(); protected abstract Texture GetBackground(); protected abstract Track GetTrack(); protected virtual Waveform GetWaveform() => new Waveform(); public bool BeatmapLoaded => beatmap.IsValueCreated; public Beatmap Beatmap => beatmap.Value; private readonly Lazy beatmap; private Beatmap populateBeatmap() { var b = GetBeatmap() ?? new Beatmap(); // use the database-backed info. b.BeatmapInfo = BeatmapInfo; return b; } 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() { // 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; } public bool WaveformLoaded => waveform.IsValueCreated; public Waveform Waveform => waveform.Value; private readonly Lazy waveform; private Waveform populateWaveform() => GetWaveform(); public void TransferTo(WorkingBeatmap other) { if (track.IsValueCreated && track.Value != null && BeatmapInfo.AudioEquals(other.BeatmapInfo)) other.track = track; if (background.IsValueCreated && background.Value != null && BeatmapInfo.BackgroundEquals(other.BeatmapInfo)) other.background = background; } public virtual void Dispose() { if (BackgroundLoaded) Background.Dispose(); if (WaveformLoaded) Waveform.Dispose(); } public void DisposeTrack() { if (!track.IsValueCreated) return; track.Value?.Dispose(); track = null; } private void applyRateAdjustments(Track t = null) { if (t == null && track.IsValueCreated) t = track.Value; if (t == null) return; t.ResetSpeedAdjustments(); foreach (var mod in Mods.Value.OfType()) mod.ApplyToClock(t); } } }