// Copyright (c) Arlo Godfrey. All Rights Reserved. // Licensed under the GNU Lesser General Public License, Version 3.0 with additional terms. // See the LICENSE, LICENSE.LESSER and LICENSE.ADDITIONAL files in the project root for more information. using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using OwlCore.Events; using StrixMusic.Sdk.AdapterModels; using StrixMusic.Sdk.AppModels; using StrixMusic.Sdk.CoreModels; using StrixMusic.Sdk.Plugins.Model; namespace StrixMusic.Sdk.PluginModels { /// /// Wraps an instance of with the provided plugins. /// public class StrixDataRootPluginWrapper : IStrixDataRoot, IPluginWrapper { private readonly IStrixDataRoot _strixDataRoot; private readonly SdkModelPlugin[] _plugins; /// /// Initializes a new instance of the class. /// /// An existing instance to wrap around and provide plugins on top of. /// The plugins to import and apply to everything returned from this wrapper. public StrixDataRootPluginWrapper(IStrixDataRoot strixDataRoot, params SdkModelPlugin[] plugins) { foreach (var plugin in plugins) ActivePlugins.Import(plugin); ActivePlugins = GlobalModelPluginConnector.Create(ActivePlugins); _strixDataRoot = ActivePlugins.StrixDataRoot.Execute(strixDataRoot); Library = new LibraryPluginWrapper(_strixDataRoot.Library, plugins); if (_strixDataRoot.Search is not null) Search = new SearchPluginWrapper(_strixDataRoot.Search, plugins); if (_strixDataRoot.Pins is not null) Pins = new PlayableCollectionGroupPluginWrapper(_strixDataRoot.Pins, plugins); if (_strixDataRoot.Discoverables is not null) Discoverables = new DiscoverablesPluginWrapper(_strixDataRoot.Discoverables, plugins); if (_strixDataRoot.RecentlyPlayed is not null) RecentlyPlayed = new RecentlyPlayedPluginWrapper(_strixDataRoot.RecentlyPlayed, plugins); _plugins = plugins; AttachEvents(_strixDataRoot); } private void AttachEvents(IStrixDataRoot strixDataRoot) { strixDataRoot.SourcesChanged += OnSourcesChanged; strixDataRoot.DevicesChanged += OnDevicesChanged; strixDataRoot.DevicesChanged += OnDevicesChanged; strixDataRoot.PinsChanged += OnPinsChanged; strixDataRoot.RecentlyPlayedChanged += OnRecentlyPlayedChanged; strixDataRoot.DiscoverablesChanged += OnDiscoverablesChanged; strixDataRoot.SearchChanged += OnSearchChanged; } private void DetachEvents(IStrixDataRoot strixDataRoot) { strixDataRoot.SourcesChanged -= OnSourcesChanged; strixDataRoot.DevicesChanged -= OnDevicesChanged; strixDataRoot.DevicesChanged -= OnDevicesChanged; strixDataRoot.PinsChanged -= OnPinsChanged; strixDataRoot.RecentlyPlayedChanged -= OnRecentlyPlayedChanged; strixDataRoot.DiscoverablesChanged -= OnDiscoverablesChanged; strixDataRoot.SearchChanged -= OnSearchChanged; } private void OnDiscoverablesChanged(object sender, IDiscoverables e) { Discoverables = new DiscoverablesPluginWrapper(e, _plugins); DiscoverablesChanged?.Invoke(this, Discoverables); } private void OnRecentlyPlayedChanged(object sender, IRecentlyPlayed e) { RecentlyPlayed = new RecentlyPlayedPluginWrapper(e, _plugins); RecentlyPlayedChanged?.Invoke(this, RecentlyPlayed); } private void OnPinsChanged(object sender, IPlayableCollectionGroup e) { Pins = new PlayableCollectionGroupPluginWrapper(e, _plugins); PinsChanged?.Invoke(this, Pins); } private void OnSearchChanged(object sender, ISearch e) { Search = new SearchPluginWrapper(e, _plugins); SearchChanged?.Invoke(this, Search); } private void OnSourcesChanged(object sender, EventArgs e) => SourcesChanged?.Invoke(sender, e); private void OnDevicesChanged(object sender, IReadOnlyList> addedItems, IReadOnlyList> removedItems) => DevicesChanged?.Invoke(this, addedItems, removedItems); /// public SdkModelPlugin ActivePlugins { get; } = new(PluginModelWrapperInfo.Metadata); /// public event EventHandler? SourcesChanged; /// public event CollectionChangedEventHandler? DevicesChanged; /// public event EventHandler? PinsChanged; /// public event EventHandler? DiscoverablesChanged; /// public event EventHandler? SearchChanged; /// public event EventHandler? RecentlyPlayedChanged; /// public MergedCollectionConfig MergeConfig => _strixDataRoot.MergeConfig; /// public IReadOnlyList Devices => _strixDataRoot.Devices; /// public ILibrary Library { get; } /// public IPlayableCollectionGroup? Pins { get; private set; } /// public ISearch? Search { get; private set; } /// public IRecentlyPlayed? RecentlyPlayed { get; private set; } /// public IDiscoverables? Discoverables { get; private set; } /// public IReadOnlyList Sources => _strixDataRoot.Sources; /// public bool IsInitialized => _strixDataRoot.IsInitialized; /// public bool Equals(ICore other) => _strixDataRoot.Equals(other); /// public Task InitAsync(CancellationToken cancellationToken = default) => _strixDataRoot.InitAsync(cancellationToken); /// public ValueTask DisposeAsync() { DetachEvents(_strixDataRoot); return _strixDataRoot.DisposeAsync(); } } }