diff --git a/osu.Game/Skinning/LegacyDatabasedSkinResourceStore.cs b/osu.Game/Skinning/LegacyDatabasedSkinResourceStore.cs index ab820a13ab..4194aa5089 100644 --- a/osu.Game/Skinning/LegacyDatabasedSkinResourceStore.cs +++ b/osu.Game/Skinning/LegacyDatabasedSkinResourceStore.cs @@ -3,10 +3,8 @@ using System; using System.Collections.Generic; -using System.Linq; using osu.Framework.Extensions; using osu.Framework.IO.Stores; -using osu.Game.Database; using osu.Game.Extensions; using Realms; @@ -14,12 +12,36 @@ namespace osu.Game.Skinning { public class LegacyDatabasedSkinResourceStore : ResourceStore { - private readonly ILive source; + private readonly Dictionary fileToStoragePathMapping = new Dictionary(); + + private readonly IDisposable subscription; public LegacyDatabasedSkinResourceStore(SkinInfo source, IResourceStore underlyingStore) : base(underlyingStore) { - this.source = source.ToLive(); + subscription = source.Files.SubscribeForNotifications((sender, changes, error) => + { + if (changes == null) + return; + + // If a large number of changes are made on skin files, this may be better suited to being cleared here + // and reinitialised on next usage. + initialiseFileCache(source); + }); + + initialiseFileCache(source); + } + + ~LegacyDatabasedSkinResourceStore() + { + Dispose(false); + } + + private void initialiseFileCache(SkinInfo source) + { + fileToStoragePathMapping.Clear(); + foreach (var f in source.Files) + fileToStoragePathMapping[f.Filename.ToLowerInvariant()] = f.File.GetStoragePath(); } protected override IEnumerable GetFilenames(string name) @@ -32,18 +54,16 @@ protected override IEnumerable GetFilenames(string name) } } + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + + subscription?.Dispose(); + } + private string getPathForFile(string filename) => - source.PerformRead(s => - { - if (s.IsManaged) - { - // avoid enumerating all files if this is a managed realm instance. - return s.Files.Filter(@"Filename ==[c] $0", filename).FirstOrDefault()?.File.GetStoragePath(); - } + fileToStoragePathMapping.TryGetValue(filename.ToLower(), out string path) ? path : null; - return s.Files.FirstOrDefault(f => string.Equals(f.Filename, filename, StringComparison.OrdinalIgnoreCase))?.File.GetStoragePath(); - }); - - public override IEnumerable GetAvailableResources() => source.PerformRead(s => s.Files.Select(f => f.Filename)); + public override IEnumerable GetAvailableResources() => fileToStoragePathMapping.Keys; } }