2021-05-20 02:52:29 +08: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.
2022-06-17 15:37:17 +08:00
#nullable disable
2021-05-20 02:52:29 +08:00
using System ;
using System.Linq ;
2021-05-30 02:22:39 +08:00
using NUnit.Framework ;
2021-05-20 02:52:29 +08:00
using osu.Framework.Allocation ;
using osu.Framework.Audio ;
using osu.Framework.Lists ;
using osu.Framework.Testing ;
using osu.Framework.Timing ;
using osu.Framework.Utils ;
using osu.Game.Beatmaps ;
2021-11-29 16:57:17 +08:00
using osu.Game.Database ;
2021-05-20 02:52:29 +08:00
using osu.Game.Extensions ;
using osu.Game.Rulesets ;
using osu.Game.Rulesets.Osu ;
using osu.Game.Rulesets.Osu.Skinning.Legacy ;
using osu.Game.Rulesets.Scoring ;
2022-03-15 21:55:47 +08:00
using osu.Game.Screens.Play ;
2021-05-20 02:52:29 +08:00
using osu.Game.Screens.Play.HUD ;
using osu.Game.Skinning ;
using osu.Game.Storyboards ;
namespace osu.Game.Tests.Visual.Gameplay
{
public class TestSceneBeatmapSkinFallbacks : OsuPlayerTestScene
{
private ISkin currentBeatmapSkin ;
[Resolved]
private SkinManager skinManager { get ; set ; }
protected override bool HasCustomSteps = > true ;
2021-05-20 04:01:41 +08:00
[Test]
public void TestEmptyLegacyBeatmapSkinFallsBack ( )
{
2022-09-17 23:14:49 +08:00
CreateSkinTest ( TrianglesSkin . CreateInfo ( ) , ( ) = > new LegacyBeatmapSkin ( new BeatmapInfo ( ) , null ) ) ;
2021-10-05 10:06:24 +08:00
AddUntilStep ( "wait for hud load" , ( ) = > Player . ChildrenOfType < SkinnableTargetContainer > ( ) . All ( c = > c . ComponentsLoaded ) ) ;
2022-11-09 15:04:56 +08:00
AddAssert ( "hud from default skin" , ( ) = > AssertComponentsFromExpectedSource ( GlobalSkinComponentLookup . LookupType . MainHUDComponents , skinManager . CurrentSkin . Value ) ) ;
2021-05-20 04:01:41 +08:00
}
2021-05-20 03:53:21 +08:00
protected void CreateSkinTest ( SkinInfo gameCurrentSkin , Func < ISkin > getBeatmapSkin )
2021-05-20 02:52:29 +08:00
{
CreateTest ( ( ) = >
{
AddStep ( "setup skins" , ( ) = >
{
2021-12-14 13:21:23 +08:00
skinManager . CurrentSkinInfo . Value = gameCurrentSkin . ToLiveUnmanaged ( ) ;
2021-05-20 03:53:21 +08:00
currentBeatmapSkin = getBeatmapSkin ( ) ;
2021-05-20 02:52:29 +08:00
} ) ;
} ) ;
}
2022-11-09 15:04:56 +08:00
protected bool AssertComponentsFromExpectedSource ( GlobalSkinComponentLookup . LookupType target , ISkin expectedSource )
2021-05-20 02:52:29 +08:00
{
2021-05-21 01:47:40 +08:00
var actualComponentsContainer = Player . ChildrenOfType < SkinnableTargetContainer > ( ) . First ( s = > s . Target = = target )
. ChildrenOfType < SkinnableTargetComponentsContainer > ( ) . SingleOrDefault ( ) ;
if ( actualComponentsContainer = = null )
return false ;
var actualInfo = actualComponentsContainer . CreateSkinnableInfo ( ) ;
2022-11-09 15:04:56 +08:00
var expectedComponentsContainer = ( SkinnableTargetComponentsContainer ) expectedSource . GetDrawableComponent ( new GlobalSkinComponentLookup ( target ) ) ;
2021-05-21 01:47:40 +08:00
if ( expectedComponentsContainer = = null )
return false ;
2021-05-20 02:52:29 +08:00
2022-05-28 19:33:09 +08:00
var expectedComponentsAdjustmentContainer = new DependencyProvidingContainer
2021-05-21 01:47:40 +08:00
{
Position = actualComponentsContainer . Parent . ToSpaceOfOtherDrawable ( actualComponentsContainer . DrawPosition , Content ) ,
Size = actualComponentsContainer . DrawSize ,
Child = expectedComponentsContainer ,
2022-05-28 19:33:09 +08:00
// proxy the same required dependencies that `actualComponentsContainer` is using.
CachedDependencies = new ( Type , object ) [ ]
{
( typeof ( ScoreProcessor ) , actualComponentsContainer . Dependencies . Get < ScoreProcessor > ( ) ) ,
( typeof ( HealthProcessor ) , actualComponentsContainer . Dependencies . Get < HealthProcessor > ( ) ) ,
( typeof ( GameplayState ) , actualComponentsContainer . Dependencies . Get < GameplayState > ( ) ) ,
2022-08-15 16:11:22 +08:00
( typeof ( IGameplayClock ) , actualComponentsContainer . Dependencies . Get < IGameplayClock > ( ) )
2022-05-28 19:33:09 +08:00
} ,
2021-05-21 01:47:40 +08:00
} ;
2021-05-20 02:52:29 +08:00
2021-05-21 01:47:40 +08:00
Add ( expectedComponentsAdjustmentContainer ) ;
2021-05-21 02:08:31 +08:00
expectedComponentsAdjustmentContainer . UpdateSubTree ( ) ;
var expectedInfo = expectedComponentsContainer . CreateSkinnableInfo ( ) ;
2022-08-26 14:19:05 +08:00
Remove ( expectedComponentsAdjustmentContainer , true ) ;
2021-05-20 02:52:29 +08:00
2021-05-21 01:47:40 +08:00
return almostEqual ( actualInfo , expectedInfo ) ;
2021-05-20 02:52:29 +08:00
}
2021-10-01 21:58:40 +08:00
private static bool almostEqual ( SkinnableInfo info , SkinnableInfo other ) = >
other ! = null
& & info . Type = = other . Type
& & info . Anchor = = other . Anchor
& & info . Origin = = other . Origin
& & Precision . AlmostEquals ( info . Position , other . Position , 1 )
& & Precision . AlmostEquals ( info . Scale , other . Scale )
& & Precision . AlmostEquals ( info . Rotation , other . Rotation )
& & info . Children . SequenceEqual ( other . Children , new FuncEqualityComparer < SkinnableInfo > ( almostEqual ) ) ;
2021-05-20 02:52:29 +08:00
protected override WorkingBeatmap CreateWorkingBeatmap ( IBeatmap beatmap , Storyboard storyboard = null )
= > new CustomSkinWorkingBeatmap ( beatmap , storyboard , Clock , Audio , currentBeatmapSkin ) ;
protected override Ruleset CreatePlayerRuleset ( ) = > new TestOsuRuleset ( ) ;
private class CustomSkinWorkingBeatmap : ClockBackedTestWorkingBeatmap
{
private readonly ISkin beatmapSkin ;
public CustomSkinWorkingBeatmap ( IBeatmap beatmap , Storyboard storyboard , IFrameBasedClock referenceClock , AudioManager audio , ISkin beatmapSkin )
: base ( beatmap , storyboard , referenceClock , audio )
{
this . beatmapSkin = beatmapSkin ;
}
2021-08-16 00:38:01 +08:00
protected internal override ISkin GetSkin ( ) = > beatmapSkin ;
2021-05-20 02:52:29 +08:00
}
private class TestOsuRuleset : OsuRuleset
{
2022-09-15 16:36:14 +08:00
public override ISkin CreateSkinTransformer ( ISkin skin , IBeatmap beatmap ) = > new TestOsuLegacySkinTransformer ( skin ) ;
2021-05-20 02:52:29 +08:00
private class TestOsuLegacySkinTransformer : OsuLegacySkinTransformer
{
2021-06-09 18:34:42 +08:00
public TestOsuLegacySkinTransformer ( ISkin skin )
: base ( skin )
2021-05-20 02:52:29 +08:00
{
}
}
}
}
}