2019-01-31 10:17:42 +00:00
// 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.
2019-01-17 12:10:34 +00:00
2019-01-18 05:28:06 +00:00
using System ;
2019-01-17 12:10:34 +00:00
using osu.Framework.Allocation ;
2019-02-21 10:04:31 +00:00
using osu.Framework.Bindables ;
2019-01-17 12:10:34 +00:00
using osu.Framework.Graphics.Containers ;
2019-06-11 17:31:01 +00:00
using osu.Game.Database ;
2019-06-11 15:41:30 +00:00
using osu.Game.Online.API ;
2019-01-17 12:10:34 +00:00
2019-06-11 17:31:01 +00:00
namespace osu.Game.Online
2019-01-17 12:10:34 +00:00
{
2019-02-14 07:21:01 +00:00
/// <summary>
2019-11-17 12:48:23 +00:00
/// A component which tracks a <typeparamref name="TModel"/> through potential download/import/deletion.
2019-02-14 07:21:01 +00:00
/// </summary>
2019-06-11 17:31:01 +00:00
public abstract class DownloadTrackingComposite < TModel , TModelManager > : CompositeDrawable
2019-06-11 17:53:40 +00:00
where TModel : class , IEquatable < TModel >
2019-06-11 19:11:17 +00:00
where TModelManager : class , IModelDownloader < TModel >
2019-01-17 12:10:34 +00:00
{
2019-06-26 15:29:09 +00:00
protected readonly Bindable < TModel > Model = new Bindable < TModel > ( ) ;
2019-01-18 05:28:06 +00:00
2019-06-11 17:31:01 +00:00
private TModelManager manager ;
2019-01-17 12:10:34 +00:00
2019-01-18 05:28:06 +00:00
/// <summary>
2019-11-17 12:48:23 +00:00
/// Holds the current download state of the <typeparamref name="TModel"/>, whether is has already been downloaded, is in progress, or is not downloaded.
2019-01-18 05:28:06 +00:00
/// </summary>
protected readonly Bindable < DownloadState > State = new Bindable < DownloadState > ( ) ;
2019-01-17 12:10:34 +00:00
2019-01-18 05:28:06 +00:00
protected readonly Bindable < double > Progress = new Bindable < double > ( ) ;
2019-01-17 12:10:34 +00:00
2019-06-11 17:31:01 +00:00
protected DownloadTrackingComposite ( TModel model = null )
2019-01-17 12:10:34 +00:00
{
2019-06-26 15:29:09 +00:00
Model . Value = model ;
2019-01-17 12:10:34 +00:00
}
[BackgroundDependencyLoader(true)]
2019-06-11 17:31:01 +00:00
private void load ( TModelManager manager )
2019-01-17 12:10:34 +00:00
{
2019-06-11 17:31:01 +00:00
this . manager = manager ;
2019-01-17 12:10:34 +00:00
2019-06-26 15:29:09 +00:00
Model . BindValueChanged ( modelInfo = >
2019-02-13 19:04:49 +00:00
{
2019-06-11 17:31:01 +00:00
if ( modelInfo . NewValue = = null )
2019-02-13 19:04:49 +00:00
attachDownload ( null ) ;
2019-06-11 17:31:01 +00:00
else if ( manager . IsAvailableLocally ( modelInfo . NewValue ) )
2019-02-13 19:04:49 +00:00
State . Value = DownloadState . LocallyAvailable ;
else
2019-06-11 17:31:01 +00:00
attachDownload ( manager . GetExistingDownload ( modelInfo . NewValue ) ) ;
2019-02-13 19:04:49 +00:00
} , true ) ;
2019-01-18 05:28:06 +00:00
2019-08-05 08:58:16 +00:00
manager . DownloadBegan + = downloadBegan ;
manager . DownloadFailed + = downloadFailed ;
2019-06-11 17:31:01 +00:00
manager . ItemAdded + = itemAdded ;
manager . ItemRemoved + = itemRemoved ;
2019-01-17 12:10:34 +00:00
}
2019-08-05 08:58:16 +00:00
private void downloadBegan ( ArchiveDownloadRequest < TModel > request )
{
if ( request . Model . Equals ( Model . Value ) )
attachDownload ( request ) ;
}
private void downloadFailed ( ArchiveDownloadRequest < TModel > request )
{
if ( request . Model . Equals ( Model . Value ) )
attachDownload ( null ) ;
}
2019-06-26 12:52:37 +00:00
private ArchiveDownloadRequest < TModel > attachedRequest ;
2019-01-17 12:10:34 +00:00
2019-06-26 12:52:37 +00:00
private void attachDownload ( ArchiveDownloadRequest < TModel > request )
2019-01-18 05:28:06 +00:00
{
if ( attachedRequest ! = null )
{
attachedRequest . Failure - = onRequestFailure ;
attachedRequest . DownloadProgressed - = onRequestProgress ;
attachedRequest . Success - = onRequestSuccess ;
}
attachedRequest = request ;
if ( attachedRequest ! = null )
{
2019-01-31 10:08:45 +00:00
if ( attachedRequest . Progress = = 1 )
{
State . Value = DownloadState . Downloaded ;
Progress . Value = 1 ;
}
else
{
State . Value = DownloadState . Downloading ;
Progress . Value = attachedRequest . Progress ;
attachedRequest . Failure + = onRequestFailure ;
attachedRequest . DownloadProgressed + = onRequestProgress ;
attachedRequest . Success + = onRequestSuccess ;
}
2019-01-18 05:28:06 +00:00
}
else
{
State . Value = DownloadState . NotDownloaded ;
}
2019-01-17 12:10:34 +00:00
}
2019-02-14 07:21:01 +00:00
private void onRequestSuccess ( string _ ) = > Schedule ( ( ) = > State . Value = DownloadState . Downloaded ) ;
2019-01-17 12:10:34 +00:00
2019-02-14 07:21:01 +00:00
private void onRequestProgress ( float progress ) = > Schedule ( ( ) = > Progress . Value = progress ) ;
2019-01-17 12:10:34 +00:00
2019-02-14 07:21:01 +00:00
private void onRequestFailure ( Exception e ) = > Schedule ( ( ) = > attachDownload ( null ) ) ;
2019-01-17 12:10:34 +00:00
2019-06-26 12:52:37 +00:00
private void itemAdded ( TModel s ) = > setDownloadStateFromManager ( s , DownloadState . LocallyAvailable ) ;
2019-02-13 19:11:46 +00:00
2019-06-11 17:31:01 +00:00
private void itemRemoved ( TModel s ) = > setDownloadStateFromManager ( s , DownloadState . NotDownloaded ) ;
2019-02-13 19:11:46 +00:00
2019-06-11 17:31:01 +00:00
private void setDownloadStateFromManager ( TModel s , DownloadState state ) = > Schedule ( ( ) = >
2019-01-17 12:10:34 +00:00
{
2019-06-26 15:29:09 +00:00
if ( ! s . Equals ( Model . Value ) )
2019-01-17 12:10:34 +00:00
return ;
2019-02-14 07:21:01 +00:00
State . Value = state ;
} ) ;
2019-06-26 15:29:38 +00:00
#region Disposal
protected override void Dispose ( bool isDisposing )
{
base . Dispose ( isDisposing ) ;
if ( manager ! = null )
{
2019-08-05 08:58:16 +00:00
manager . DownloadBegan - = downloadBegan ;
manager . DownloadFailed - = downloadFailed ;
2019-06-26 15:29:38 +00:00
manager . ItemAdded - = itemAdded ;
2019-08-05 08:58:16 +00:00
manager . ItemRemoved - = itemRemoved ;
2019-06-26 15:29:38 +00:00
}
State . UnbindAll ( ) ;
attachDownload ( null ) ;
}
#endregion
2019-01-17 12:10:34 +00:00
}
2019-01-18 05:28:06 +00:00
}