// Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; using Microsoft.EntityFrameworkCore.Internal; using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; using osu.Game.Online.API.Requests; namespace osu.Game.Overlays.Direct { public abstract class DownloadTrackingComposite : CompositeDrawable { public readonly Bindable BeatmapSet = new Bindable(); private BeatmapManager beatmaps; /// /// Holds the current download state of the beatmap, whether is has already been downloaded, is in progress, or is not downloaded. /// protected readonly Bindable State = new Bindable(); protected readonly Bindable Progress = new Bindable(); protected DownloadTrackingComposite(BeatmapSetInfo beatmapSet = null) { BeatmapSet.Value = beatmapSet; } [BackgroundDependencyLoader(true)] private void load(BeatmapManager beatmaps) { this.beatmaps = beatmaps; BeatmapSet.BindValueChanged(set => { if (set == null) attachDownload(null); else if (beatmaps.QueryBeatmapSets(s => s.OnlineBeatmapSetID == set.OnlineBeatmapSetID).Any()) State.Value = DownloadState.LocallyAvailable; else attachDownload(beatmaps.GetExistingDownload(set)); }, true); beatmaps.BeatmapDownloadBegan += download => { if (download.BeatmapSet.OnlineBeatmapSetID == BeatmapSet.Value?.OnlineBeatmapSetID) attachDownload(download); }; beatmaps.ItemAdded += setAdded; } #region Disposal protected override void Dispose(bool isDisposing) { base.Dispose(isDisposing); beatmaps.BeatmapDownloadBegan -= attachDownload; beatmaps.ItemAdded -= setAdded; } #endregion private DownloadBeatmapSetRequest attachedRequest; private void attachDownload(DownloadBeatmapSetRequest request) { if (attachedRequest != null) { attachedRequest.Failure -= onRequestFailure; attachedRequest.DownloadProgressed -= onRequestProgress; attachedRequest.Success -= onRequestSuccess; } attachedRequest = request; if (attachedRequest != null) { State.Value = DownloadState.Downloading; attachedRequest.Failure += onRequestFailure; attachedRequest.DownloadProgressed += onRequestProgress; attachedRequest.Success += onRequestSuccess; } else { State.Value = DownloadState.NotDownloaded; } } private void onRequestSuccess(byte[] data) { Schedule(() => State.Value = DownloadState.Downloaded); attachDownload(null); } private void onRequestProgress(float progress) { Schedule(() => Progress.Value = progress); } private void onRequestFailure(Exception e) { Schedule(() => State.Value = DownloadState.Downloading); } private void setAdded(BeatmapSetInfo s, bool existing, bool silent) { if (s.OnlineBeatmapSetID != BeatmapSet.Value?.OnlineBeatmapSetID) return; Schedule(() => State.Value = DownloadState.LocallyAvailable); } } public enum DownloadState { NotDownloaded, Downloading, Downloaded, LocallyAvailable } }