// 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; } /// /// 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; } /// /// 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() { } } }