1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-12 20:22:55 +08:00

Allow instantiation of skins

This commit is contained in:
Dean Herbert 2018-02-22 17:16:48 +09:00
parent ce7d212c3c
commit 3726db53b5
6 changed files with 125 additions and 6 deletions

View File

@ -1,4 +1,4 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
@ -106,7 +106,7 @@ namespace osu.Game
runMigrations();
dependencies.Cache(SkinManager = new SkinManager(Host.Storage, contextFactory, Host));
dependencies.Cache(SkinManager = new SkinManager(Host.Storage, contextFactory, Host, Audio));
dependencies.Cache(API = new APIAccess
{

View File

@ -0,0 +1,17 @@
using osu.Framework.Audio.Sample;
using osu.Framework.Graphics;
namespace osu.Game.Skinning
{
public class DefaultSkin : Skin
{
public DefaultSkin()
: base(SkinInfo.Default)
{
}
public override Drawable GetDrawableComponent(string componentName) => null;
public override SampleChannel GetSample(string sampleName) => null;
}
}

View File

@ -0,0 +1,49 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.IO;
using System.Linq;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
using osu.Framework.IO.Stores;
namespace osu.Game.Skinning
{
public class LegacySkin : Skin
{
private readonly TextureStore textures;
private readonly SampleManager samples;
public LegacySkin(SkinInfo skin, IResourceStore<byte[]> storage, AudioManager audioManager)
: base(skin)
{
var audioStore = new ResourceStore<byte[]>(storage);
samples = audioManager.GetSampleManager(audioStore);
textures = new TextureStore(new RawTextureLoaderStore(storage));
}
private string getPathForFile(string filename) =>
SkinInfo.Files.FirstOrDefault(f => string.Equals(Path.GetFileNameWithoutExtension(f.Filename), filename, StringComparison.InvariantCultureIgnoreCase))?.FileInfo.StoragePath;
public override Drawable GetDrawableComponent(string componentName)
{
var texture = textures.Get(getPathForFile(componentName.Split('/').Last()));
if (texture == null) return null;
return new Sprite
{
RelativeSizeAxes = Axes.Both,
FillMode = FillMode.Fit,
Texture = texture,
};
}
public override SampleChannel GetSample(string sampleName) => samples.Get(getPathForFile(sampleName.Split('/').Last()));
}
}

22
osu.Game/Skinning/Skin.cs Normal file
View File

@ -0,0 +1,22 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Audio.Sample;
using osu.Framework.Graphics;
namespace osu.Game.Skinning
{
public abstract class Skin
{
public readonly SkinInfo SkinInfo;
public abstract Drawable GetDrawableComponent(string componentName);
public abstract SampleChannel GetSample(string sampleName);
protected Skin(SkinInfo skin)
{
SkinInfo = skin;
}
}
}

View File

@ -1,4 +1,4 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Microsoft.EntityFrameworkCore;
using osu.Framework.Audio;
using osu.Framework.Configuration;
using osu.Framework.Platform;
using osu.Game.Database;
@ -15,6 +16,9 @@ namespace osu.Game.Skinning
{
public class SkinManager : ArchiveModelManager<SkinInfo, SkinFileInfo>
{
private readonly AudioManager audio;
public readonly Bindable<Skin> CurrentSkin = new Bindable<Skin>(new DefaultSkin());
public readonly Bindable<SkinInfo> CurrentSkinInfo = new Bindable<SkinInfo>(SkinInfo.Default) { Default = SkinInfo.Default };
public override string[] HandledExtensions => new[] { ".osk" };
@ -30,13 +34,37 @@ namespace osu.Game.Skinning
return userSkins;
}
protected override SkinInfo CreateModel(ArchiveReader archive) => new SkinInfo { Name = archive.Name };
protected override SkinInfo CreateModel(ArchiveReader archive) => new SkinInfo
{
Name = archive.Name
};
/// <summary>
/// Retrieve a <see cref="Skin"/> instance for the provided <see cref="SkinInfo"/>
/// </summary>
/// <param name="skinInfo">The skin to lookup.</param>
/// <returns>A <see cref="Skin"/> instance correlating to the provided <see cref="SkinInfo"/>.</returns>
public Skin GetSkin(SkinInfo skinInfo)
{
if (skinInfo == SkinInfo.Default)
return new DefaultSkin();
return new LegacySkin(skinInfo, Files.Store, audio);
}
private SkinStore store;
public SkinManager(Storage storage, DatabaseContextFactory contextFactory, IIpcHost importHost)
public SkinManager(Storage storage, DatabaseContextFactory contextFactory, IIpcHost importHost, AudioManager audio)
: base(storage, contextFactory, new SkinStore(contextFactory, storage), importHost)
{
this.audio = audio;
CurrentSkinInfo.ValueChanged += info => { CurrentSkin.Value = GetSkin(info); };
CurrentSkin.ValueChanged += skin =>
{
if (skin.SkinInfo != CurrentSkinInfo.Value)
throw new InvalidOperationException($"Setting {nameof(CurrentSkin)}'s value directly is not supported. Use {nameof(CurrentSkinInfo)} isntead.");
};
}
/// <summary>

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="14.0">
<Import Project="..\osu.Game.props" />
<PropertyGroup>
@ -854,6 +854,9 @@
<Compile Include="Screens\Tournament\Teams\DrawingsTeam.cs" />
<Compile Include="Screens\Tournament\Teams\ITeamList.cs" />
<Compile Include="Screens\Tournament\Teams\StorageBackedTeamList.cs" />
<Compile Include="Skinning\DefaultSkin.cs" />
<Compile Include="Skinning\LegacySkin.cs" />
<Compile Include="Skinning\Skin.cs" />
<Compile Include="Skinning\SkinFileInfo.cs" />
<Compile Include="Skinning\SkinInfo.cs" />
<Compile Include="Skinning\SkinManager.cs" />