2019-07-22 03:34:40 +00:00
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
2019-01-24 08:43:03 +00:00
// See the LICENCE file in the repository root for full licence text.
2018-04-13 09:19:50 +00:00
using System ;
using osu.Framework.Allocation ;
2020-11-06 13:11:49 +00:00
using osu.Framework.Graphics.Pooling ;
2018-04-13 09:19:50 +00:00
namespace osu.Game.Skinning
{
/// <summary>
/// A drawable which has a callback when the skin changes.
/// </summary>
2020-11-06 13:11:49 +00:00
public abstract class SkinReloadableDrawable : PoolableDrawable
2018-04-13 09:19:50 +00:00
{
2019-12-17 10:49:13 +00:00
/// <summary>
/// Invoked when <see cref="CurrentSkin"/> has changed.
/// </summary>
public event Action OnSkinChanged ;
2019-09-26 08:04:38 +00:00
/// <summary>
/// The current skin source.
/// </summary>
protected ISkinSource CurrentSkin { get ; private set ; }
2018-04-13 09:19:50 +00:00
private readonly Func < ISkinSource , bool > allowFallback ;
/// <summary>
/// Whether fallback to default skin should be allowed if the custom skin is missing this resource.
/// </summary>
2019-09-26 08:04:38 +00:00
private bool allowDefaultFallback = > allowFallback = = null | | allowFallback . Invoke ( CurrentSkin ) ;
2018-04-13 09:19:50 +00:00
/// <summary>
/// Create a new <see cref="SkinReloadableDrawable"/>
/// </summary>
/// <param name="allowFallback">A conditional to decide whether to allow fallback to the default implementation if a skinned element is not present.</param>
protected SkinReloadableDrawable ( Func < ISkinSource , bool > allowFallback = null )
{
this . allowFallback = allowFallback ;
}
[BackgroundDependencyLoader]
private void load ( ISkinSource source )
{
2019-09-26 08:04:38 +00:00
CurrentSkin = source ;
CurrentSkin . SourceChanged + = onChange ;
2018-04-13 09:19:50 +00:00
}
2019-07-22 03:34:40 +00:00
private void onChange ( ) = >
// schedule required to avoid calls after disposed.
2019-07-29 09:35:22 +00:00
// note that this has the side-effect of components only performing a skin change when they are alive.
2019-12-17 10:49:13 +00:00
Scheduler . AddOnce ( skinChanged ) ;
2018-04-13 09:19:50 +00:00
protected override void LoadAsyncComplete ( )
{
base . LoadAsyncComplete ( ) ;
2019-12-17 10:49:13 +00:00
skinChanged ( ) ;
}
private void skinChanged ( )
{
2019-09-26 08:04:38 +00:00
SkinChanged ( CurrentSkin , allowDefaultFallback ) ;
2019-12-17 10:49:13 +00:00
OnSkinChanged ? . Invoke ( ) ;
2018-04-13 09:19:50 +00:00
}
/// <summary>
/// Called when a change is made to the skin.
/// </summary>
/// <param name="skin">The new skin.</param>
/// <param name="allowFallback">Whether fallback to default skin should be allowed if the custom skin is missing this resource.</param>
protected virtual void SkinChanged ( ISkinSource skin , bool allowFallback )
{
}
2018-08-23 05:53:16 +00:00
protected override void Dispose ( bool isDisposing )
{
base . Dispose ( isDisposing ) ;
2019-09-26 08:04:38 +00:00
if ( CurrentSkin ! = null )
CurrentSkin . SourceChanged - = onChange ;
2019-12-17 10:49:13 +00:00
OnSkinChanged = null ;
2018-08-23 05:53:16 +00:00
}
2018-04-13 09:19:50 +00:00
}
}