diff --git a/osu.Game/Rulesets/UI/DrawableRuleset.cs b/osu.Game/Rulesets/UI/DrawableRuleset.cs
index 5062c92afe..0a46f5207e 100644
--- a/osu.Game/Rulesets/UI/DrawableRuleset.cs
+++ b/osu.Game/Rulesets/UI/DrawableRuleset.cs
@@ -11,20 +11,15 @@ using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Drawables;
using System;
using System.Collections.Generic;
-using System.IO;
using System.Linq;
using System.Threading;
-using System.Threading.Tasks;
using JetBrains.Annotations;
-using osu.Framework.Audio;
-using osu.Framework.Audio.Sample;
using osu.Framework.Audio.Track;
using osu.Framework.Bindables;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Textures;
using osu.Framework.Input;
using osu.Framework.Input.Events;
-using osu.Framework.IO.Stores;
using osu.Game.Configuration;
using osu.Game.Graphics.Cursor;
using osu.Game.Input.Handlers;
@@ -113,6 +108,8 @@ namespace osu.Game.Rulesets.UI
private OnScreenDisplay onScreenDisplay;
+ private DrawableRulesetDependencies dependencies;
+
///
/// Creates a ruleset visualisation for the provided ruleset and beatmap.
///
@@ -147,30 +144,15 @@ namespace osu.Game.Rulesets.UI
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
{
- var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
+ dependencies = new DrawableRulesetDependencies(Ruleset, base.CreateChildDependencies(parent));
- var resources = Ruleset.CreateResourceStore();
-
- if (resources != null)
- {
- textureStore = new TextureStore(new TextureLoaderStore(new NamespacedResourceStore(resources, "Textures")));
- textureStore.AddStore(dependencies.Get());
- dependencies.Cache(textureStore);
-
- localSampleStore = dependencies.Get().GetSampleStore(new NamespacedResourceStore(resources, "Samples"));
- localSampleStore.PlaybackConcurrency = OsuGameBase.SAMPLE_CONCURRENCY;
- dependencies.CacheAs(new FallbackSampleStore(localSampleStore, dependencies.Get()));
- }
+ textureStore = dependencies.TextureStore;
+ localSampleStore = dependencies.SampleStore;
+ Config = dependencies.RulesetConfigManager;
onScreenDisplay = dependencies.Get();
-
- Config = dependencies.Get().GetConfigFor(Ruleset);
-
if (Config != null)
- {
- dependencies.Cache(Config);
onScreenDisplay?.BeginTracking(this, Config);
- }
return dependencies;
}
@@ -362,13 +344,14 @@ namespace osu.Game.Rulesets.UI
{
base.Dispose(isDisposing);
- localSampleStore?.Dispose();
-
if (Config != null)
{
onScreenDisplay?.StopTracking(this, Config);
Config = null;
}
+
+ // Dispose the components created by this dependency container.
+ dependencies.Dispose();
}
}
@@ -519,62 +502,4 @@ namespace osu.Game.Rulesets.UI
{
}
}
-
- ///
- /// A sample store which adds a fallback source.
- ///
- ///
- /// This is a temporary implementation to workaround ISampleStore limitations.
- ///
- public class FallbackSampleStore : ISampleStore
- {
- private readonly ISampleStore primary;
- private readonly ISampleStore secondary;
-
- public FallbackSampleStore(ISampleStore primary, ISampleStore secondary)
- {
- this.primary = primary;
- this.secondary = secondary;
- }
-
- public SampleChannel Get(string name) => primary.Get(name) ?? secondary.Get(name);
-
- public Task GetAsync(string name) => primary.GetAsync(name) ?? secondary.GetAsync(name);
-
- public Stream GetStream(string name) => primary.GetStream(name) ?? secondary.GetStream(name);
-
- public IEnumerable GetAvailableResources() => throw new NotSupportedException();
-
- public void AddAdjustment(AdjustableProperty type, BindableNumber adjustBindable) => throw new NotSupportedException();
-
- public void RemoveAdjustment(AdjustableProperty type, BindableNumber adjustBindable) => throw new NotSupportedException();
-
- public BindableNumber Volume => throw new NotSupportedException();
-
- public BindableNumber Balance => throw new NotSupportedException();
-
- public BindableNumber Frequency => throw new NotSupportedException();
-
- public BindableNumber Tempo => throw new NotSupportedException();
-
- public IBindable GetAggregate(AdjustableProperty type) => throw new NotSupportedException();
-
- public IBindable AggregateVolume => throw new NotSupportedException();
-
- public IBindable AggregateBalance => throw new NotSupportedException();
-
- public IBindable AggregateFrequency => throw new NotSupportedException();
-
- public IBindable AggregateTempo => throw new NotSupportedException();
-
- public int PlaybackConcurrency
- {
- get => throw new NotSupportedException();
- set => throw new NotSupportedException();
- }
-
- public void Dispose()
- {
- }
- }
}
diff --git a/osu.Game/Rulesets/UI/DrawableRulesetDependencies.cs b/osu.Game/Rulesets/UI/DrawableRulesetDependencies.cs
new file mode 100644
index 0000000000..33b340a974
--- /dev/null
+++ b/osu.Game/Rulesets/UI/DrawableRulesetDependencies.cs
@@ -0,0 +1,148 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Threading.Tasks;
+using osu.Framework.Allocation;
+using osu.Framework.Audio;
+using osu.Framework.Audio.Sample;
+using osu.Framework.Audio.Track;
+using osu.Framework.Bindables;
+using osu.Framework.Graphics.Textures;
+using osu.Framework.IO.Stores;
+using osu.Game.Rulesets.Configuration;
+
+namespace osu.Game.Rulesets.UI
+{
+ public class DrawableRulesetDependencies : DependencyContainer, IDisposable
+ {
+ ///
+ /// The texture store to be used for the ruleset.
+ ///
+ public TextureStore TextureStore { get; private set; }
+
+ ///
+ /// The sample store to be used for the ruleset.
+ ///
+ ///
+ /// This is the local sample store pointing to the ruleset sample resources,
+ /// the cached sample store () retrieves from
+ /// this store and falls back to the parent store if this store doesn't have the requested sample.
+ ///
+ public ISampleStore SampleStore { get; private set; }
+
+ ///
+ /// The ruleset config manager.
+ ///
+ public IRulesetConfigManager RulesetConfigManager { get; private set; }
+
+ public DrawableRulesetDependencies(Ruleset ruleset, IReadOnlyDependencyContainer parent)
+ : base(parent)
+ {
+ var resources = ruleset.CreateResourceStore();
+
+ if (resources != null)
+ {
+ TextureStore = new TextureStore(new TextureLoaderStore(new NamespacedResourceStore(resources, @"Textures")));
+ TextureStore.AddStore(parent.Get());
+ Cache(TextureStore);
+
+ SampleStore = parent.Get().GetSampleStore(new NamespacedResourceStore(resources, @"Samples"));
+ SampleStore.PlaybackConcurrency = OsuGameBase.SAMPLE_CONCURRENCY;
+ CacheAs(new FallbackSampleStore(SampleStore, parent.Get()));
+ }
+
+ RulesetConfigManager = parent.Get().GetConfigFor(ruleset);
+ if (RulesetConfigManager != null)
+ Cache(RulesetConfigManager);
+ }
+
+ #region Disposal
+
+ ~DrawableRulesetDependencies()
+ {
+ Dispose(false);
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ private bool isDisposed;
+
+ protected void Dispose(bool disposing)
+ {
+ if (isDisposed)
+ return;
+
+ isDisposed = true;
+
+ SampleStore?.Dispose();
+ RulesetConfigManager = null;
+ }
+
+ #endregion
+ }
+
+ ///
+ /// A sample store which adds a fallback source.
+ ///
+ ///
+ /// This is a temporary implementation to workaround ISampleStore limitations.
+ ///
+ public class FallbackSampleStore : ISampleStore
+ {
+ private readonly ISampleStore primary;
+ private readonly ISampleStore secondary;
+
+ public FallbackSampleStore(ISampleStore primary, ISampleStore secondary)
+ {
+ this.primary = primary;
+ this.secondary = secondary;
+ }
+
+ public SampleChannel Get(string name) => primary.Get(name) ?? secondary.Get(name);
+
+ public Task GetAsync(string name) => primary.GetAsync(name) ?? secondary.GetAsync(name);
+
+ public Stream GetStream(string name) => primary.GetStream(name) ?? secondary.GetStream(name);
+
+ public IEnumerable GetAvailableResources() => throw new NotSupportedException();
+
+ public void AddAdjustment(AdjustableProperty type, BindableNumber adjustBindable) => throw new NotSupportedException();
+
+ public void RemoveAdjustment(AdjustableProperty type, BindableNumber adjustBindable) => throw new NotSupportedException();
+
+ public BindableNumber Volume => throw new NotSupportedException();
+
+ public BindableNumber Balance => throw new NotSupportedException();
+
+ public BindableNumber Frequency => throw new NotSupportedException();
+
+ public BindableNumber Tempo => throw new NotSupportedException();
+
+ public IBindable GetAggregate(AdjustableProperty type) => throw new NotSupportedException();
+
+ public IBindable AggregateVolume => throw new NotSupportedException();
+
+ public IBindable AggregateBalance => throw new NotSupportedException();
+
+ public IBindable AggregateFrequency => throw new NotSupportedException();
+
+ public IBindable AggregateTempo => throw new NotSupportedException();
+
+ public int PlaybackConcurrency
+ {
+ get => throw new NotSupportedException();
+ set => throw new NotSupportedException();
+ }
+
+ public void Dispose()
+ {
+ }
+ }
+}