From 30b14473181fe3eb11f2207c61949c3f99b70731 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 4 Mar 2018 03:17:11 +0900 Subject: [PATCH 1/2] Fix skin file path lookup performance Move path mapping to the resource store, so caching can happen against the component's name rather than the skin path. Fixes regression of beatmap load time when a custom skin is selected. --- osu.Game/Skinning/LegacySkin.cs | 11 +++------- osu.Game/Skinning/SkinResourceStore.cs | 29 ++++++++++++++++++++++++++ osu.Game/osu.Game.csproj | 1 + 3 files changed, 33 insertions(+), 8 deletions(-) create mode 100644 osu.Game/Skinning/SkinResourceStore.cs diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 5f34ddc2b5..97e0bdb942 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -1,9 +1,6 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // 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; @@ -22,16 +19,14 @@ namespace osu.Game.Skinning public LegacySkin(SkinInfo skin, IResourceStore storage, AudioManager audioManager) : base(skin) { + storage = new SkinResourceStore(skin, storage); samples = audioManager.GetSampleManager(storage); 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())); + var texture = textures.Get(componentName); if (texture == null) return null; return new Sprite @@ -42,6 +37,6 @@ namespace osu.Game.Skinning }; } - public override SampleChannel GetSample(string sampleName) => samples.Get(getPathForFile(sampleName.Split('/').Last())); + public override SampleChannel GetSample(string sampleName) => samples.Get(sampleName); } } diff --git a/osu.Game/Skinning/SkinResourceStore.cs b/osu.Game/Skinning/SkinResourceStore.cs new file mode 100644 index 0000000000..58da8ad19a --- /dev/null +++ b/osu.Game/Skinning/SkinResourceStore.cs @@ -0,0 +1,29 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.IO; +using System.Linq; +using osu.Framework.IO.Stores; + +namespace osu.Game.Skinning +{ + public class SkinResourceStore : IResourceStore + { + private readonly SkinInfo skin; + private readonly IResourceStore underlyingStore; + + private string getPathForFile(string filename) => + skin.Files.FirstOrDefault(f => string.Equals(Path.GetFileNameWithoutExtension(f.Filename), filename.Split('/').Last(), StringComparison.InvariantCultureIgnoreCase))?.FileInfo.StoragePath; + + public SkinResourceStore(SkinInfo skin, IResourceStore underlyingStore) + { + this.skin = skin; + this.underlyingStore = underlyingStore; + } + + public Stream GetStream(string name) => underlyingStore.GetStream(getPathForFile(name)); + + byte[] IResourceStore.Get(string name) => underlyingStore.Get(getPathForFile(name)); + } +} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 37e304d62d..d4bd5a0013 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -870,6 +870,7 @@ + From 02690e5f25135cbecfac4a1e65990d95f6f9ac0b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 5 Mar 2018 21:27:37 +0900 Subject: [PATCH 2/2] Move to private implementation --- osu.Game/Skinning/LegacySkin.cs | 24 ++++++++++++++++++++- osu.Game/Skinning/SkinResourceStore.cs | 29 -------------------------- osu.Game/osu.Game.csproj | 1 - 3 files changed, 23 insertions(+), 31 deletions(-) delete mode 100644 osu.Game/Skinning/SkinResourceStore.cs diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 97e0bdb942..17fe6369a7 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -1,6 +1,9 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // 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; @@ -19,7 +22,7 @@ namespace osu.Game.Skinning public LegacySkin(SkinInfo skin, IResourceStore storage, AudioManager audioManager) : base(skin) { - storage = new SkinResourceStore(skin, storage); + storage = new LegacySkinResourceStore(skin, storage); samples = audioManager.GetSampleManager(storage); textures = new TextureStore(new RawTextureLoaderStore(storage)); } @@ -38,5 +41,24 @@ namespace osu.Game.Skinning } public override SampleChannel GetSample(string sampleName) => samples.Get(sampleName); + + private class LegacySkinResourceStore : IResourceStore + { + private readonly SkinInfo skin; + private readonly IResourceStore underlyingStore; + + private string getPathForFile(string filename) => + skin.Files.FirstOrDefault(f => string.Equals(Path.GetFileNameWithoutExtension(f.Filename), filename.Split('/').Last(), StringComparison.InvariantCultureIgnoreCase))?.FileInfo.StoragePath; + + public LegacySkinResourceStore(SkinInfo skin, IResourceStore underlyingStore) + { + this.skin = skin; + this.underlyingStore = underlyingStore; + } + + public Stream GetStream(string name) => underlyingStore.GetStream(getPathForFile(name)); + + byte[] IResourceStore.Get(string name) => underlyingStore.Get(getPathForFile(name)); + } } } diff --git a/osu.Game/Skinning/SkinResourceStore.cs b/osu.Game/Skinning/SkinResourceStore.cs deleted file mode 100644 index 58da8ad19a..0000000000 --- a/osu.Game/Skinning/SkinResourceStore.cs +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using System; -using System.IO; -using System.Linq; -using osu.Framework.IO.Stores; - -namespace osu.Game.Skinning -{ - public class SkinResourceStore : IResourceStore - { - private readonly SkinInfo skin; - private readonly IResourceStore underlyingStore; - - private string getPathForFile(string filename) => - skin.Files.FirstOrDefault(f => string.Equals(Path.GetFileNameWithoutExtension(f.Filename), filename.Split('/').Last(), StringComparison.InvariantCultureIgnoreCase))?.FileInfo.StoragePath; - - public SkinResourceStore(SkinInfo skin, IResourceStore underlyingStore) - { - this.skin = skin; - this.underlyingStore = underlyingStore; - } - - public Stream GetStream(string name) => underlyingStore.GetStream(getPathForFile(name)); - - byte[] IResourceStore.Get(string name) => underlyingStore.Get(getPathForFile(name)); - } -} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index d4bd5a0013..37e304d62d 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -870,7 +870,6 @@ -