osu/osu.Game/Tests/Visual/SkinnableTestScene.cs

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

231 lines
8.3 KiB
C#
Raw Normal View History

2019-07-26 10:29:06 +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.
2022-06-17 07:37:17 +00:00
#nullable disable
2019-07-26 10:29:06 +00:00
using System;
using System.Collections.Generic;
2019-08-20 08:39:16 +00:00
using System.Text.RegularExpressions;
using JetBrains.Annotations;
2019-07-26 10:29:06 +00:00
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
2022-08-02 10:50:57 +00:00
using osu.Framework.Graphics.Rendering;
using osu.Framework.Graphics.Shapes;
2019-08-20 08:39:16 +00:00
using osu.Framework.Graphics.Textures;
2019-07-26 10:29:06 +00:00
using osu.Framework.IO.Stores;
using osu.Framework.Platform;
using osu.Game.Beatmaps;
using osu.Game.Database;
using osu.Game.Graphics.Sprites;
using osu.Game.IO;
using osu.Game.Rulesets;
2019-07-26 10:29:06 +00:00
using osu.Game.Skinning;
using osuTK;
using osuTK.Graphics;
2019-07-26 10:29:06 +00:00
namespace osu.Game.Tests.Visual
2019-07-26 10:29:06 +00:00
{
public abstract partial class SkinnableTestScene : OsuGridTestScene, IStorageResourceProvider
2019-07-26 10:29:06 +00:00
{
2022-09-18 09:18:10 +00:00
private TrianglesSkin trianglesSkin;
2019-07-26 10:29:06 +00:00
private Skin metricsSkin;
2022-09-18 09:18:10 +00:00
private Skin legacySkin;
private Skin argonSkin;
2019-07-26 10:29:06 +00:00
private Skin specialSkin;
2019-12-12 13:27:11 +00:00
private Skin oldSkin;
2019-07-26 10:29:06 +00:00
[Resolved]
private GameHost host { get; set; }
2019-07-30 12:53:28 +00:00
protected SkinnableTestScene()
2019-12-12 13:27:11 +00:00
: base(2, 3)
2019-07-30 12:53:28 +00:00
{
}
2019-07-26 10:29:06 +00:00
[BackgroundDependencyLoader]
2022-01-15 00:06:39 +00:00
private void load()
2019-07-26 10:29:06 +00:00
{
2022-02-23 04:51:25 +00:00
var dllStore = new DllResourceStore(GetType().Assembly);
2019-07-26 10:29:06 +00:00
argonSkin = new ArgonSkin(this);
2022-09-18 09:18:10 +00:00
trianglesSkin = new TrianglesSkin(this);
metricsSkin = new TestLegacySkin(new SkinInfo { Name = "metrics-skin" }, new NamespacedResourceStore<byte[]>(dllStore, "Resources/metrics_skin"), this, true);
2022-09-18 09:18:10 +00:00
legacySkin = new DefaultLegacySkin(this);
specialSkin = new TestLegacySkin(new SkinInfo { Name = "special-skin" }, new NamespacedResourceStore<byte[]>(dllStore, "Resources/special_skin"), this, true);
oldSkin = new TestLegacySkin(new SkinInfo { Name = "old-skin" }, new NamespacedResourceStore<byte[]>(dllStore, "Resources/old_skin"), this, true);
2019-07-26 10:29:06 +00:00
}
private readonly List<Drawable> createdDrawables = new List<Drawable>();
protected void SetContents(Func<ISkin, Drawable> creationFunction)
2019-07-26 10:29:06 +00:00
{
createdDrawables.Clear();
var beatmap = CreateBeatmapForSkinProvider();
Cell(0).Child = createProvider(argonSkin, creationFunction, beatmap);
Cell(1).Child = createProvider(trianglesSkin, creationFunction, beatmap);
Cell(2).Child = createProvider(metricsSkin, creationFunction, beatmap);
Cell(3).Child = createProvider(legacySkin, creationFunction, beatmap);
Cell(4).Child = createProvider(specialSkin, creationFunction, beatmap);
Cell(5).Child = createProvider(oldSkin, creationFunction, beatmap);
2019-08-26 03:31:51 +00:00
}
protected IEnumerable<Drawable> CreatedDrawables => createdDrawables;
2021-06-01 07:13:56 +00:00
private Drawable createProvider(Skin skin, Func<ISkin, Drawable> creationFunction, IBeatmap beatmap)
2019-08-26 03:31:51 +00:00
{
2021-06-01 07:13:56 +00:00
var created = creationFunction(skin);
createdDrawables.Add(created);
2019-08-26 03:31:51 +00:00
Container childContainer;
OutlineBox outlineBox;
SkinProvidingContainer skinProvider;
ISkin provider = Ruleset.Value.CreateInstance().CreateSkinTransformer(skin, beatmap) ?? skin;
var children = new Container
{
RelativeSizeAxes = Axes.Both,
BorderColour = Color4.White,
BorderThickness = 3,
Masking = true,
Children = new Drawable[]
{
new Box
{
AlwaysPresent = true,
Alpha = 0,
RelativeSizeAxes = Axes.Both,
},
new OsuSpriteText
{
2022-09-15 07:02:57 +00:00
Text = skin.SkinInfo.Value.Name,
Scale = new Vector2(1.5f),
Padding = new MarginPadding(5),
},
childContainer = new Container
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Children = new Drawable[]
{
outlineBox = new OutlineBox(),
skinProvider = new SkinProvidingContainer(provider)
{
Child = created,
}
}
},
}
};
// run this once initially to bring things into a sane state as early as possible.
updateSizing();
// run this once after construction to handle the case the changes are made in a BDL/LoadComplete call.
Schedule(updateSizing);
return children;
void updateSizing()
{
bool autoSize = created.RelativeSizeAxes == Axes.None;
foreach (var c in new[] { childContainer, skinProvider })
{
2020-11-05 08:26:41 +00:00
c.RelativeSizeAxes = Axes.None;
c.AutoSizeAxes = Axes.None;
c.Size = Vector2.Zero;
2020-11-05 08:26:41 +00:00
if (autoSize)
c.AutoSizeAxes = Axes.Both;
else
{
c.RelativeSizeAxes = Axes.Both;
c.Anchor = Anchor.Centre;
c.Origin = Anchor.Centre;
c.Size = new Vector2(0.97f);
}
}
outlineBox.Alpha = autoSize ? 1 : 0;
}
}
/// <summary>
/// Creates the ruleset for adding the corresponding skin transforming component.
/// </summary>
[NotNull]
protected abstract Ruleset CreateRulesetForSkinProvider();
protected sealed override Ruleset CreateRuleset() => CreateRulesetForSkinProvider();
protected virtual IBeatmap CreateBeatmapForSkinProvider() => CreateWorkingBeatmap(Ruleset.Value).GetPlayableBeatmap(Ruleset.Value);
#region IResourceStorageProvider
2022-08-02 10:50:57 +00:00
public IRenderer Renderer => host.Renderer;
public AudioManager AudioManager => Audio;
public IResourceStore<byte[]> Files => null;
public new IResourceStore<byte[]> Resources => base.Resources;
public IResourceStore<TextureUpload> CreateTextureLoaderStore(IResourceStore<byte[]> underlyingStore) => host.CreateTextureLoaderStore(underlyingStore);
RealmAccess IStorageResourceProvider.RealmAccess => null;
#endregion
private partial class OutlineBox : CompositeDrawable
{
public OutlineBox()
{
BorderColour = Color4.IndianRed;
BorderThickness = 5;
Masking = true;
RelativeSizeAxes = Axes.Both;
InternalChild = new Box
2019-08-26 03:31:51 +00:00
{
RelativeSizeAxes = Axes.Both,
Alpha = 0,
Colour = Color4.Brown,
AlwaysPresent = true
};
}
2019-07-26 10:29:06 +00:00
}
2019-08-20 08:39:16 +00:00
private class TestLegacySkin : LegacySkin
2019-07-26 10:29:06 +00:00
{
2019-08-20 08:39:16 +00:00
private readonly bool extrapolateAnimations;
2019-07-30 12:53:28 +00:00
public TestLegacySkin(SkinInfo skin, IResourceStore<byte[]> storage, IStorageResourceProvider resources, bool extrapolateAnimations)
: base(skin, resources, storage)
2019-08-20 08:39:16 +00:00
{
this.extrapolateAnimations = extrapolateAnimations;
}
2019-07-30 12:53:28 +00:00
2020-07-17 07:54:30 +00:00
public override Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT)
2019-08-20 08:39:16 +00:00
{
var lookup = base.GetTexture(componentName, wrapModeS, wrapModeT);
2019-07-30 12:53:28 +00:00
if (lookup != null)
return lookup;
// extrapolate frames to test longer animations
if (extrapolateAnimations)
{
var match = Regex.Match(componentName, "-([0-9]*)");
if (match.Length > 0 && int.TryParse(match.Groups[1].Value, out int number) && number < 60)
return base.GetTexture(componentName.Replace($"-{number}", $"-{number % 2}"), wrapModeS, wrapModeT);
}
return null;
}
2019-07-26 10:29:06 +00:00
}
}
}