Expose skin sources via ISkinSource and revert to consuming based on hierarchy

This commit is contained in:
Dean Herbert 2021-06-22 16:19:55 +09:00
parent 1b0aadcc6f
commit 0ad189e357
9 changed files with 67 additions and 28 deletions

View File

@ -2,6 +2,8 @@
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System; using System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Audio.Sample; using osu.Framework.Audio.Sample;
@ -114,6 +116,8 @@ namespace osu.Game.Rulesets.Osu.Tests
public ISkin FindProvider(Func<ISkin, bool> lookupFunction) => null; public ISkin FindProvider(Func<ISkin, bool> lookupFunction) => null;
public IEnumerable<ISkin> AllSources => Enumerable.Empty<ISkin>();
public event Action SourceChanged public event Action SourceChanged
{ {
add { } add { }

View File

@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
@ -146,6 +147,8 @@ namespace osu.Game.Rulesets.Osu.Tests
public ISkin FindProvider(Func<ISkin, bool> lookupFunction) => null; public ISkin FindProvider(Func<ISkin, bool> lookupFunction) => null;
public IEnumerable<ISkin> AllSources => Enumerable.Empty<ISkin>();
public event Action SourceChanged; public event Action SourceChanged;
private bool enabled = true; private bool enabled = true;

View File

@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System; using System;
using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
@ -330,6 +331,8 @@ namespace osu.Game.Tests.Visual.Gameplay
public ISkin FindProvider(Func<ISkin, bool> lookupFunction) => throw new NotImplementedException(); public ISkin FindProvider(Func<ISkin, bool> lookupFunction) => throw new NotImplementedException();
public IEnumerable<ISkin> AllSources => Enumerable.Empty<ISkin>();
public event Action SourceChanged public event Action SourceChanged
{ {
add { } add { }

View File

@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
@ -147,6 +148,7 @@ namespace osu.Game.Tests.Visual.Gameplay
public ISample GetSample(ISampleInfo sampleInfo) => source?.GetSample(sampleInfo); public ISample GetSample(ISampleInfo sampleInfo) => source?.GetSample(sampleInfo);
public IBindable<TValue> GetConfig<TLookup, TValue>(TLookup lookup) => source?.GetConfig<TLookup, TValue>(lookup); public IBindable<TValue> GetConfig<TLookup, TValue>(TLookup lookup) => source?.GetConfig<TLookup, TValue>(lookup);
public ISkin FindProvider(Func<ISkin, bool> lookupFunction) => source?.FindProvider(lookupFunction); public ISkin FindProvider(Func<ISkin, bool> lookupFunction) => source?.FindProvider(lookupFunction);
public IEnumerable<ISkin> AllSources => source.AllSources;
public void TriggerSourceChanged() public void TriggerSourceChanged()
{ {

View File

@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System; using System;
using System.Collections.Generic;
using JetBrains.Annotations; using JetBrains.Annotations;
namespace osu.Game.Skinning namespace osu.Game.Skinning
@ -20,5 +21,10 @@ namespace osu.Game.Skinning
/// <returns>The skin to be used for subsequent lookups, or <c>null</c> if none is available.</returns> /// <returns>The skin to be used for subsequent lookups, or <c>null</c> if none is available.</returns>
[CanBeNull] [CanBeNull]
ISkin FindProvider(Func<ISkin, bool> lookupFunction); ISkin FindProvider(Func<ISkin, bool> lookupFunction);
/// <summary>
/// Retrieve all sources available for lookup, with highest priority source first.
/// </summary>
IEnumerable<ISkin> AllSources { get; }
} }
} }

View File

@ -26,7 +26,6 @@ namespace osu.Game.Skinning
/// Therefore disallow falling back to any parent <see cref="ISkinSource"/> any further. /// Therefore disallow falling back to any parent <see cref="ISkinSource"/> any further.
/// </remarks> /// </remarks>
protected override bool AllowFallingBackToParent => false; protected override bool AllowFallingBackToParent => false;
protected override Container<Drawable> Content { get; } protected override Container<Drawable> Content { get; }
public RulesetSkinProvidingContainer(Ruleset ruleset, IBeatmap beatmap, [CanBeNull] ISkin beatmapSkin) public RulesetSkinProvidingContainer(Ruleset ruleset, IBeatmap beatmap, [CanBeNull] ISkin beatmapSkin)
@ -44,13 +43,13 @@ namespace osu.Game.Skinning
} }
[Resolved] [Resolved]
private SkinManager skinManager { get; set; } private ISkinSource skinSource { get; set; }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load() private void load()
{ {
UpdateSkins(); UpdateSkins();
skinManager.SourceChanged += OnSourceChanged; skinSource.SourceChanged += OnSourceChanged;
} }
protected override void OnSourceChanged() protected override void OnSourceChanged()
@ -63,25 +62,19 @@ namespace osu.Game.Skinning
{ {
SkinSources.Clear(); SkinSources.Clear();
// TODO: we also want to insert a DefaultLegacySkin here if the current *beatmap* is providing any skinned elements. foreach (var skin in skinSource.AllSources)
switch (skinManager.CurrentSkin.Value)
{ {
case LegacySkin currentLegacySkin: switch (skin)
SkinSources.Add(GetLegacyRulesetTransformedSkin(currentLegacySkin)); {
case LegacySkin legacySkin:
SkinSources.Add(GetLegacyRulesetTransformedSkin(legacySkin));
break;
if (currentLegacySkin != skinManager.DefaultLegacySkin) default:
SkinSources.Add(GetLegacyRulesetTransformedSkin(skinManager.DefaultLegacySkin)); SkinSources.Add(skin);
break;
break; }
default:
SkinSources.Add(skinManager.CurrentSkin.Value);
break;
} }
if (skinManager.CurrentSkin.Value != skinManager.DefaultSkin)
SkinSources.Add(skinManager.DefaultSkin);
} }
protected ISkin GetLegacyRulesetTransformedSkin(ISkin legacySkin) protected ISkin GetLegacyRulesetTransformedSkin(ISkin legacySkin)
@ -100,8 +93,8 @@ namespace osu.Game.Skinning
{ {
base.Dispose(isDisposing); base.Dispose(isDisposing);
if (skinManager != null) if (skinSource != null)
skinManager.SourceChanged -= OnSourceChanged; skinSource.SourceChanged -= OnSourceChanged;
} }
} }
} }

View File

@ -248,17 +248,29 @@ namespace osu.Game.Skinning
return null; return null;
} }
public IEnumerable<ISkin> AllSources
{
get
{
yield return CurrentSkin.Value;
if (CurrentSkin.Value is LegacySkin)
yield return DefaultLegacySkin;
yield return DefaultSkin;
}
}
private T lookupWithFallback<T>(Func<ISkin, T> lookupFunction) private T lookupWithFallback<T>(Func<ISkin, T> lookupFunction)
where T : class where T : class
{ {
if (lookupFunction(CurrentSkin.Value) is T skinSourced) foreach (var source in AllSources)
return skinSourced; {
if (lookupFunction(source) is T skinSourced)
return skinSourced;
}
if (CurrentSkin.Value is LegacySkin && lookupFunction(DefaultLegacySkin) is T legacySourced) return null;
return legacySourced;
// Finally fall back to the (non-legacy) default.
return lookupFunction(DefaultSkin);
} }
#region IResourceStorageProvider #region IResourceStorageProvider

View File

@ -131,6 +131,21 @@ namespace osu.Game.Skinning
return fallbackSource?.FindProvider(lookupFunction); return fallbackSource?.FindProvider(lookupFunction);
} }
public IEnumerable<ISkin> AllSources
{
get
{
foreach (var skin in SkinSources)
yield return skin;
if (fallbackSource != null)
{
foreach (var skin in fallbackSource.AllSources)
yield return skin;
}
}
}
public Drawable GetDrawableComponent(ISkinComponent component) public Drawable GetDrawableComponent(ISkinComponent component)
{ {
foreach (var skin in SkinSources) foreach (var skin in SkinSources)

View File

@ -146,6 +146,7 @@ namespace osu.Game.Tests.Beatmaps
} }
public ISkin FindProvider(Func<ISkin, bool> lookupFunction) => null; public ISkin FindProvider(Func<ISkin, bool> lookupFunction) => null;
public IEnumerable<ISkin> AllSources => Enumerable.Empty<ISkin>();
} }
} }
} }